| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Changing this behaviour might break existing code. Perhaps it would be better to update the docs to match the actual behaviour. Alternatively, we could issue a warning for this in 3.12 and change the behaviour in 3.14.
I'm not sure what's the most correct (or less painful) solution.
@erlend-aasland Can we update the docs for 3.10/3.11/3.12 to match behaviour, but for 3.12 mention that inheritance is deprecated and will be removed in 3.14, and make 3.12 issue a deprecation warning on attempt to instantiate subclass of non-instantiable?
The 3.10, 3.11 and 3.12 docs should be updated. Regarding deprecation, it is not for me to decide alone. Please raise a topic in the Core Development category on Discourse.
IMO the Python example above should fail. But the flag isn't responsible directly: this fails because the flag prevented inheriting tp_new, and so there is no C-level constructor to call. There's no way Python code can safely work around that.
If a subclass provides a tp_new (from C), then it should be possible to instantiate it – the subclass knows how to create its instances in that case. (I haven't checked if there's a bug there as well, though.)
IMO the Python example above should fail. But the flag isn't responsible directly: this fails because the flag prevented inheriting tp_new, and so there is no C-level constructor to call. There's no way Python code can safely work around that.
Ok, so we should probably just leave the current behaviour as it is, if I am reading you right. In any case, the docs should be updated to reflect the implementation.
I agree that there is misconception on my part, and subclass doesn't actually inherit said flag (i. e. doesn't have it in its tp_flags) but have its tp_new set to value of the same field of its base class, which is NULL if base class is not instantiable.
My opinion is that if flag is not inheritable, it shouldn't affect ability of subclasses to be instantiable. The current situation is that ability to instantiate class depends on presence of flag in base class.
And, as far as I know, there is no way to make such subclass instantiable in pure Python.
Also I think that non-instantiable base classes with instantiable subclasses can be useful in some situations, e. g. as abstract classes defined in extensions.
Now I see that probably there is no bug here, but there still may be a little feature :)
Now I see that probably there is no bug here, but there still may be a little feature :)
If you think such a feature is worth it, raise a discussion first on Discourse. If you gain support for you idea, create a new type-feature issue for you idea here on the tracker.
Suggesting closing this.
And, as far as I know, there is no way to make such subclass instantiable in pure Python.
That's intentional. A big use case for Py_TPFLAGS_DISALLOW_INSTANTIATION is that there's some necessary setup at the C level – setting C pointers rather than Python attributes. Allowing Python subclasses would mean that this initialization could be bypassed.
Also I think that non-instantiable base classes with instantiable subclasses can be useful in some situations, e. g. as abstract classes defined in extensions.
Py_TPFLAGS_DISALLOW_INSTANTIATION isn't the tool for that.
In this case, the tp_new would check if type(self) is the base class, and raise an exception in that case.
The flag's docs should mention that – they're currently unclear unless you know the internals already. I'll turn this into a docs issue.
Thanks for reporting it! Hopefully we can clear up some confusion for everyone :)
@chgnrdv, does https://github.com/python/cpython/pull/99002/files look helpful?
@encukou Yes, looks helpful to me. Thank you!
The docs were updated. Thanks again for bringing this up!
| Back | FazBrowse Home | New Git URL |
When Py_TPFLAGS_BASETYPE and Py_TPFLAGS_DISALLOW_INSTANTIATION flags are set on extension type tp_flags field, attempt to create type subclass instance fails:
According to documentation, it shouldn't happen:
https://docs.python.org/3/c-api/typeobj.html#Py_TPFLAGS_DISALLOW_INSTANTIATION
Extension code example:
_foo.c.txt
Tested on 3.10.3 and 3.12.0a0.