-
-
Notifications
You must be signed in to change notification settings - Fork 32.1k
Add sys.set_object_tags() and sys.get_object_tags() APIs for debugging and experimental Use #134819
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
Comments
FYI, I am even fine with |
And please let me know if there are better namings |
I like the general idea, but I have a few notes/concerns:
An alternative could be to properly expose unstable APIs like we do with |
I no longer like adding more such APIs. The basic concept of this API is not making CPython a specific implementation's API anymore. It will break other implementations and cause compatibility issues. unstable.sys will not solve the current situtations.
Well, API will not care about whether the user adding multiple attributes and singe attribute anyway.
I don't care about the naming, I thought that get/set is conventional naming. For me, this is matter of documentation and I still think that people should not use this API as much as possible.
Would you like to provide a concrete example? Currently, we only care about defer_refcount and immortal, so I didn't think about it. Well, we could change the signature of set_tags to be set_tag and make it receive parameters. |
I'm worried that def do_something_to_constant(op):
# Use immortality as a notion of constant-ness
if "immortal" not in sys.get_tags(op):
raise ValueError() Couldn't other implementations just implement
What if we wanted to provide an API for object flags someday? It's also not totally clear to me if |
The key point is where the focus lies. If you care about portability, then you shouldn’t rely on unstable or implementation-specific APIs, which may not exist in other versions or implementations. However, Consider the case where we want to remove |
Ok, that makes sense. The place where I'm getting a little tripped up is that the whole point of the |
I'm open to making the API design more flexible, but we should still try to avoid exposing implementation details whenever possible. So, should we plan to support object flags in the future? The reason I mention this is that we can not cover all cases :) How about |
See: #134762 (comment), this is a real-world example. |
I was under the impression that it'd be totally fine to remove |
Please rename your API to |
Looks good! |
I would prefer And By the way, is it possible to mark a string as interned with your API? Something like: I suppose that |
What do we do if we remove the tag in the future though? E.g. if one day we remove defer_refcount. Wouldn't that break the API? |
Should we include GC "tags" (related to the
Not sure about And what about other low-level object attributes?
Would it be interesting to expose these tags? They cannot be modified by |
Even if tags that can not be set by |
I still prefer to use string-based tag since those keywords would be meaningless for other implementations. |
I am not sure about these, if we think that |
I think we'd be better of with dedicated APIs for the different pieces of functionality. I think combining lots of functionality into a single Swiss army knife style API isn't good design: it makes it harder to use, harder to discover, harder to implement correctly, and harder to add new features. To quote Robert C. Martin: "Functions should do one thing. They should do it well. They should do it only." I am not convinced that this style of design makes it any easier for implementers of alternate Python runtimes. It is incredibly easy to support APIs like On the other hand, the semantics of |
To expand on my previous comment: if you want the APIs to be clearly labeled as experimental or implementation details, stick them in a namespace whose name that makes that clear. |
I concur with @colesbury, I also prefer multiple functions rather than a single one (two in practice). |
Most of case this is correct approach and rasonable concern, but intention of this API is not recommending people to use. The user of this API would be limited and we prefer to use our internal purpose which can allow to change anything without any burnden. |
Once the API is added most of implementer does not need to care about it. Most of case it will set anything or return nothing. For the user, I believe that they should not rely on this API and even for the current usage. |
Yeah, that’s true. But why should we care about people who rely on private APIs like sys._xxx? If the current stance is that these sys._xxx APIs can be removed freely without documentation, that would make things much less stressful. |
My motivation for this API is that if exposing implementation details is inevitable, then why aren't we exposing a sandbox API that can be easily managed, and nothing needs to be guaranteed? |
Uh oh!
There was an error while loading. Please reload this page.
Background
CPython currently exposes several internal implementation details via APIs such as:
sys._defer_refcount
sys._is_immortal
sys._is_interned
These APIs leak implementation-specific details and create implicit expectations of cross-version(e.g 3.13, 3.14, 3.15...) and cross-implementation compatibility(e.g CPython, PyPy, RustPython), even though they are not part of any formal public API contract.
For example, other Python implementations may not support or emulate these features, and yet their presence in CPython can create unintentional backward compatibility burdens when new releases are made.
Proposal
To address this, I would like to propose introducing two weak introspection APIs in the
sys
module:sys.set_tags(obj, tags: Iterable[str]) -> None
sys.get_tags(obj) -> tuple[str, ...]
Goals and Non-Goals
Goals:
Non-Goals:
Documentation and Guarantees
We will clearly document that:
cc @ZeroIntensity @vstinner @Fidget-Spinner @colesbury
Linked PRs
The text was updated successfully, but these errors were encountered: