-
Notifications
You must be signed in to change notification settings - Fork 1
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
Better support for type checking #19
Comments
I suppose this is mainly about fast subclass checking. Currently some types do not have a fast path:
while many of the built-ins have the luxury of using the TP-flags for super-fast subclass checking? Personally, I am still confused about the idea because it seems to effectively introduce the In any case, this is probably all more brainstorming and a side issue, so I don't want to waste much time discussing it. Thanks for working on improving the C-API, it is much appreciated! |
Oh, important context: this is mainly for cases where it's not easy to get the superclass object. |
If I understand you correctly, you're suggesting something like this:
|
Well, I wasn't planning to add I'd like to do some more research into comparing a live pointer to a dangling pointer. If this would be possible without an additional type flag (just by relying on the fact that the user has a valid pointer to the original spec), |
So where are you suggesting to store the spec pointer, then? :) As a slot? |
But you would still need to know that the same pointer could not point to a different spec later (by coincidence)? And by that time, I am not sure it matters anymore whether or not you require it to be a life pointer? But, at least I understand the point now: We need something that "bypasses" the issue of global state for sub-interpreters, which indeed is a worthy objective. But, I still feel you may be overcomplicating things. Why not ask the user to provide a/the unique symbol instead and document it as: If you define your spec static, just use the spec here! |
I recon setting the spec pointer would be done implicitly in However, we need to know if we can "trust" the pointer; that is, does it point to a heap allocated spec (can be a dangling pointer), or a static spec (can never be a dangling pointer). One solution to that is to use a non-inheritable type flag. |
Aha! Right, that would work nicely. (Having to put a pointer to the spec in the spec won't be very ergonomic, but we can live with that). |
Like the following? PyType_Spec foo_spec = {
...
.static_spec = &foo_spec // ask a user to ensure it's a static spec
}; If so, If you mean a type slot, I have tried introducing a slot ID: python/cpython#118139. This way enforces a forward declaration of the spec. |
Yes, a slot like that. But I think it needs a PEP-like (though maybe much smaller) proposal, and approval from the C-API WG. Would you be willing to write up something like that? As said above, this doesn't necessarily need to be a pointer to the spec itself -- we only need a pointer that will
For example, an extensions that automatically wraps C++ classes could put the |
Does it also mean that a user-defined unique number in the module will also work fine, if the type has the |
Hmm. Would that work for the StgInfo case, where the module might be being deallocated? Something like this was requested by the JPype maintainer; that discussion reminds me that things might be easier in modules that use a metaclass. I commented on the StgInfo issue. |
EDIT: Draft version of |
In my understanding, the pointer to the statically allocated spec should also become invalid after the DLL unload. |
Ah, I agree that the existing |
We don't unload DLLs. There are no plans to do that; even if there were, we definitely wouldn't want to unload them if their classes are still alive, or if code that references their |
…it would be highly platform-specific. |
This comment was marked as outdated.
This comment was marked as outdated.
Thanks. I should get to the draft in around 2 weeks. |
This comment was marked as resolved.
This comment was marked as resolved.
Leaving two approaches we have come up with: PyType_Slot foo_slots[] = {
{Py_tp_token, &pointee_in_the_module}, // spec, typeid, ...
...
};
PyType_Spec foo_spec = { ..., .slots = foo_slots};
PyType_Spec bar_spec = { ..., .slots = foo_slots}; (a)
(b)
I would prefer (b) if possible when creating a spec dynamically (not just copy & paste). |
https://discuss.python.org/t/allowing-heaptypes-to-have-a-token-for-superclass-identification/55598 |
As PEP 630 notes, there's no good equivalent for
Py*_Check
functions (like forPyUnicode_Check
forstr
a static type).These checks are used to ensure instances have compatible memory layout (and thus, whether it's safe to cast from
PyObject
to a specific type).We can assume that types made from the same spec share the memory layout, so, I could imagine API for checking if any superclass was defined using a given PyType_Spec.
This means the API wouldn't be usable without access to that original spec (in particular, it wouldn't be usable with classes created completely "on-demand").
The spec would also need to be stored on the class for this comparison. Since specs for "on-demand" classes can be deallocated right after the class is created, this would become a dangling pointer.
By using the new typechecking API, the user has a pointer to the original spec. Sadly, AFAIK, comparing a live pointer to a dangling pointer is implementation-defined, so we can't use it.
So, there probably needs to be a new flag for saying that the spec will outlive the type (e.g. by being static), which would be required for the type check.
The text was updated successfully, but these errors were encountered: