Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-85283: Add PySys_AuditTuple() function #108965

Merged
merged 1 commit into from
Oct 5, 2023

Conversation

vstinner
Copy link
Member

@vstinner vstinner commented Sep 5, 2023

PySys_Audit() now raises an exception if the event argument is NULL or if the "N" format is used in the format argument.

Add tests on PySys_AuditTuple() and on new PySys_Audit() error code paths.


📚 Documentation preview 📚: https://cpython-previews--108965.org.readthedocs.build/

@vstinner
Copy link
Member Author

vstinner commented Sep 5, 2023

For the rationale of adding PySys_AuditTuple() in addition to the existing PySys_Audit(), see the discussion on my PR #108571 "Add PySys_Audit() to the limited C API" and this discussion: capi-workgroup/problems#35 (comment)

In short, it's possible to use the Python C API in Go, but Go doesn't support ... variadic arguments (<stdarg.h>). I would like to add PySys_Audit() argument to the limited C API, but @encukou asked me to add a different flavor which accepts a tuple. So here you have.

@vstinner
Copy link
Member Author

vstinner commented Sep 6, 2023

cc @encukou

@vstinner
Copy link
Member Author

vstinner commented Sep 6, 2023

cc @zooba

@zooba
Copy link
Member

zooba commented Sep 6, 2023

Please don't make every PySys_Audit call convert the arguments to a tuple eagerly. It deliberately defers it until it knows there's at least one hook that's going to be called.

Please don't slow down the regular API for the sake of the limited API. If anything, make PySys_AuditTuple just pass its tuple to PySys_Audit, which will hide the ... from callers but otherwise not change any other code.

@vstinner
Copy link
Member Author

vstinner commented Sep 6, 2023

Please don't make every PySys_Audit call convert the arguments to a tuple eagerly. It deliberately defers it until it knows there's at least one hook that's going to be called.

Oh! Nicely spotted, I knew that, I recall that I paid attention to that when you implemented audit hooks :-) Oops, it's now fixed. I made sure that "should audit" is checked as soon as possible. In exchange, arguments are only checked if a audit hook is added (if "should audit" is true).

Please don't slow down the regular API for the sake of the limited API. If anything, make PySys_AuditTuple just pass its tuple to PySys_Audit, which will hide the ... from callers but otherwise not change any other code.

I fixed my PR, existing APIs are still lazy as before, and I made PySys_AuditTuple() a litlte bit more lazy (exit earlier, before checking arguments).

@zooba: Would you mind to review the updated PR?

@vstinner
Copy link
Member Author

vstinner commented Sep 6, 2023

Please don't slow down the regular API for the sake of the limited API.

Oh by the way, as I wrote earlier: I would prefer to not add PySys_AuditTuple() to the limited C API.

@zooba
Copy link
Member

zooba commented Sep 6, 2023

I can't do a thorough review of that much code right now.

Why isn't the new function just this?

int PySys_AuditTuple(const char *event, PyObject *tuple) {
    return PySys_Audit(event, "O", tuple);
}

If a single object is passed in and it's a tuple, it's meant to be left alone (i.e. splatted). If you want a single argument that happens to be a tuple, you need PySys_Audit(event, "(O)", tuple).

@vstinner
Copy link
Member Author

vstinner commented Sep 6, 2023

If a single object is passed in and it's a tuple, it's meant to be left alone (i.e. splatted).

Hum, I dislike this kind of magic "unpack or not" depending on the number of items. What if an event takes a single argument which a tuple? What if you want to unpack the tuple since the event has multiple arguments?

I would prefer a regular API: always pass a tuple.

@zooba
Copy link
Member

zooba commented Sep 6, 2023

The magic already exists, and I showed in my message how to handle the case where you pass a tuple. It's also in the docs. If you want to make a massively complicated change instead of using the already existing API, that's up to you, but it's going to make it much harder to get a review and will cause maintenance headaches for all of us later on.

@serhiy-storchaka
Copy link
Member

I concur with @zooba.

@vstinner
Copy link
Member Author

Ok, I updated my PR so PySys_AuditTuple() simply calls PySys_Audit(). I updated the doc and the added tests.

@zooba @serhiy-storchaka: Would you mind to review the updated PR?

Copy link
Member

@serhiy-storchaka serhiy-storchaka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are all these changes necessary? It looks to me that they were needed if you implement PySys_AuditTuple() on lower level. But if you make it a simple wrapper around PySys_Audit(), you can write it in 10-15 lines of code.

@vstinner
Copy link
Member Author

Ok, I updated my PR so PySys_AuditTuple() simply calls PySys_Audit().

Oh, I removed too many changes and new tests failed. I added again checks on event and format to fix tests.

@vstinner
Copy link
Member Author

vstinner commented Sep 19, 2023

Ok, I updated my PR to add assertions to check arguments when should_audit() is false, and I added a PyTuple_Check() to reject types other than tuple.

@serhiy-storchaka: Would you mind to review the updated PR?

Note: sys_audit() is implemented by calling _PySys_Audit(tstate, event, "O", auditArgs).

Copy link
Member

@zooba zooba left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall the change is good, but I don't like having sometimes assertions and sometimes exceptions for invalid values in debug builds.

Also you should benchmark the extra runtime checks you're doing now. Previously I benchmarked and found that I needed to use assertions to maintain performance when adding these functions in the first place, so if you're going to regress them, it should be its own discussion and not slipped into an unrelated change.

@vstinner
Copy link
Member Author

@zooba @serhiy-storchaka: I updated my PR to address latest @zooba's review, would you mind to review it?

  • Assertions are now also tested in all cases, not only if should_audit() is false. Well, never caled these functions with invalid arguments!
  • Fix the doc.
  • Replace assert() with printf+return in test_audit_tuple.

I rebased my PR.

@vstinner
Copy link
Member Author

@serhiy-storchaka: I updated my PR to take your review in account.

SystemError is now raised if events is NULL or if the "N" format option is used. I documented the error, as requested by @zooba.

@vstinner vstinner enabled auto-merge (squash) October 5, 2023 21:22
@vstinner vstinner disabled auto-merge October 5, 2023 21:28
sys.audit() now has assertions to check that the event argument is
not NULL and that the format argument does not use the "N" format.

Add tests on PySys_AuditTuple().
@vstinner
Copy link
Member Author

vstinner commented Oct 5, 2023

@zooba:

Overall the change is good, but I don't like having sometimes assertions and sometimes exceptions for invalid values in debug builds.
Also you should benchmark the extra runtime checks you're doing now. Previously I benchmarked and found that I needed to use assertions to maintain performance when adding these functions in the first place, so if you're going to regress them, it should be its own discussion and not slipped into an unrelated change.

Ok. I removed the two checks which raised exceptions to leave PySys_Audit() and sys.audit() unchanged. I only added assertions to sys.audit() to check arguments even if there is no hook. They can be added again separately later if needed.

@vstinner vstinner enabled auto-merge (squash) October 5, 2023 21:40
@vstinner vstinner merged commit bb057b3 into python:main Oct 5, 2023
@vstinner vstinner deleted the sys_audit_tuple branch October 5, 2023 21:59
@vstinner
Copy link
Member Author

vstinner commented Oct 5, 2023

Ok, I addressed all reviews. Thanks a lot for all your reviews :-) I merged my PR.

@serhiy-storchaka
Copy link
Member

Thank you Victor.

Glyphack pushed a commit to Glyphack/cpython that referenced this pull request Sep 2, 2024
sys.audit() now has assertions to check that the event argument is
not NULL and that the format argument does not use the "N" format.

Add tests on PySys_AuditTuple().
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants