Skip to content

gh-143715: deprecate incomplete initialization of struct.Struct()#143659

Open
skirpichev wants to merge 22 commits intopython:mainfrom
skirpichev:deprecate-struct-init-2/78724
Open

gh-143715: deprecate incomplete initialization of struct.Struct()#143659
skirpichev wants to merge 22 commits intopython:mainfrom
skirpichev:deprecate-struct-init-2/78724

Conversation

@skirpichev
Copy link
Member

@skirpichev skirpichev commented Jan 10, 2026

  • Struct.__new__() will require a mandatory argument (format)
  • Calls of __init__() method on initialized Struct are deprecated

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

* ``Struct.__new__()`` will require a mandatory argument (format)
* Calls of ``__init__()`` method on initialized Struct are deprecated
@skirpichev
Copy link
Member Author

The evil plan is to remove custom Struct.__init__() method and move all initialization logic to the Struct.__new__(). Something, that was done by #94532 before.

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.

I think this needs a separate issue for discussion. Please open a new issue, and refer #78724 and #112358 (maybe even with citations).

We need to discuss what should be the end goal after the end of the deprecation period, and how deprecations canl help to transit the user code.

@skirpichev skirpichev marked this pull request as draft January 12, 2026 00:23
@skirpichev skirpichev changed the title gh-78724: deprecate incomplete initialization of struct.Struct() gh-143715: deprecate incomplete initialization of struct.Struct() Jan 12, 2026
@skirpichev skirpichev marked this pull request as ready for review January 12, 2026 06:09
This make format argument in the __init__() - optional.  If it's
missing, the object must be already initialized in __new__().
@skirpichev skirpichev requested a review from meadori January 13, 2026 01:35
@skirpichev
Copy link
Member Author

CC @meadori per experts index.

Copy link
Member

@vstinner vstinner left a comment

Choose a reason for hiding this comment

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

LGTM.

What do you think @serhiy-storchaka?

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.

78724

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.

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'}
Copy link
Member

Choose a reason for hiding this comment

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

This is a regression. You can use @text_signature to set a fake signature.

Copy link
Member Author

Choose a reason for hiding this comment

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

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'>

Copy link
Member

Choose a reason for hiding this comment

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

But it works in main after conversion to Argument Clinic. See #143672.

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.

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'}
Copy link
Member

Choose a reason for hiding this comment

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

But it works in main after conversion to Argument Clinic. See #143672.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants