gh-143715: deprecate incomplete initialization of struct.Struct()#143659
gh-143715: deprecate incomplete initialization of struct.Struct()#143659skirpichev wants to merge 22 commits intopython:mainfrom
Conversation
* ``Struct.__new__()`` will require a mandatory argument (format) * Calls of ``__init__()`` method on initialized Struct are deprecated
|
The evil plan is to remove custom |
This make format argument in the __init__() - optional. If it's missing, the object must be already initialized in __new__().
|
CC @meadori per experts index. |
Co-authored-by: Victor Stinner <vstinner@python.org>
vstinner
left a comment
There was a problem hiding this comment.
LGTM.
What do you think @serhiy-storchaka?
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
serhiy-storchaka
left a comment
There was a problem hiding this comment.
Please add a test for a new case mentioned in the issue. We can test if the type's tp_init and tp_new are the same to make more qualified decision.
| def test_struct_module_has_signatures(self): | ||
| import struct | ||
| self._test_module_has_signatures(struct) | ||
| unsupported_signature = {'Struct'} |
There was a problem hiding this comment.
This is a regression. You can use @text_signature to set a fake signature.
There was a problem hiding this comment.
Hmm,
$ python3.14
Python 3.14.3 (tags/v3.14.3:323c59a5e34, Feb 11 2026, 08:44:26) [GCC 14.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import inspect, struct
>>> inspect.signature(struct.Struct)
Traceback (most recent call last):
File "<python-input-1>", line 1, in <module>
inspect.signature(struct.Struct)
~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.14/inspect.py", line 3322, in signature
return Signature.from_callable(obj, follow_wrapped=follow_wrapped,
~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
globals=globals, locals=locals, eval_str=eval_str,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
annotation_format=annotation_format)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.14/inspect.py", line 3037, in from_callable
return _signature_from_callable(obj, sigcls=cls,
follow_wrapper_chains=follow_wrapped,
globals=globals, locals=locals, eval_str=eval_str,
annotation_format=annotation_format)
File "/usr/local/lib/python3.14/inspect.py", line 2596, in _signature_from_callable
raise ValueError(
'no signature found for builtin type {!r}'.format(obj))
ValueError: no signature found for builtin type <class '_struct.Struct'>
There was a problem hiding this comment.
But it works in main after conversion to Argument Clinic. See #143672.
serhiy-storchaka
left a comment
There was a problem hiding this comment.
And what about the following case?
class MyStruct(struct.Struct):
def __init__(self, arg):
super().__init__('>h')
my_struct = MyStruct('<h')
my_struct.pack(12345)There should emit a FutureWarning, because the current and the future code produce different results. MyStruct(5) should emit a DeprecationWarning, because it works in the current code, but will be error in future. ``MyStruct('>h')` should work without warnings.
Add *args, **kwargs to __init__() at line 798 and test with different arguments:
MyStruct(), MyStruct('>h'), MyStruct('<h'), MyStruct(5), MyStruct('<h', 5), MyStruct(format='<h'), etc.
Also add *args, **kwargs to __new__() in other example and test with different arguments.
| def test_struct_module_has_signatures(self): | ||
| import struct | ||
| self._test_module_has_signatures(struct) | ||
| unsupported_signature = {'Struct'} |
There was a problem hiding this comment.
But it works in main after conversion to Argument Clinic. See #143672.
Struct.__new__()will require a mandatory argument (format)__init__()method on initialized Struct are deprecated📚 Documentation preview 📚: https://cpython-previews--143659.org.readthedocs.build/