From 81555b81be78b0763e1e62fc0c08ab6a1c246bfa Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Tue, 1 Apr 2025 09:56:13 +0100 Subject: [PATCH 1/9] Cache ``types.CapsuleType`` on first compution --- Lib/types.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Lib/types.py b/Lib/types.py index 1484c22ee9dffa..7b9434ebae35bd 100644 --- a/Lib/types.py +++ b/Lib/types.py @@ -333,8 +333,10 @@ def wrapped(*args, **kwargs): def __getattr__(name): if name == 'CapsuleType': + global CapsuleType import _socket - return type(_socket.CAPI) + CapsuleType = type(_socket.CAPI) + return CapsuleType raise AttributeError(f"module {__name__!r} has no attribute {name!r}") __all__ = [n for n in globals() if n[:1] != '_'] From f2a25309a54e9992242c54e3a0afa489d9b829af Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Tue, 1 Apr 2025 12:51:37 +0100 Subject: [PATCH 2/9] Add a _types module exposing `CapsuleType` and `SimpleNamespace` --- Modules/Setup | 1 + Modules/Setup.bootstrap.in | 1 + Modules/_typesmodule.c | 37 ++++++++++++++++++++++++++++++ PC/config.c | 2 ++ PCbuild/pythoncore.vcxproj | 1 + PCbuild/pythoncore.vcxproj.filters | 3 +++ Python/stdlib_module_names.h | 1 + configure.ac | 1 + 8 files changed, 47 insertions(+) create mode 100644 Modules/_typesmodule.c diff --git a/Modules/Setup b/Modules/Setup index ddf39e0b966610..d050d7a5fc2dc3 100644 --- a/Modules/Setup +++ b/Modules/Setup @@ -150,6 +150,7 @@ PYTHONPATH=$(COREPYTHONPATH) #_socket socketmodule.c #_statistics _statisticsmodule.c #_struct _struct.c +#_types _typesmodule.c #_typing _typingmodule.c #_zoneinfo _zoneinfo.c #array arraymodule.c diff --git a/Modules/Setup.bootstrap.in b/Modules/Setup.bootstrap.in index 4dcc0f55176d0e..2b2e8cb3e3cacd 100644 --- a/Modules/Setup.bootstrap.in +++ b/Modules/Setup.bootstrap.in @@ -23,6 +23,7 @@ _sre _sre/sre.c _sysconfig _sysconfig.c _thread _threadmodule.c time timemodule.c +_types _typesmodule.c _typing _typingmodule.c _weakref _weakref.c diff --git a/Modules/_typesmodule.c b/Modules/_typesmodule.c new file mode 100644 index 00000000000000..f2e925a69dca1d --- /dev/null +++ b/Modules/_typesmodule.c @@ -0,0 +1,37 @@ +/* _types module */ + +#include "Python.h" +#include "internal/pycore_namespace.h" // _PyNamespace_Type + +static int +_types_exec(PyObject *m) +{ + if (PyModule_AddObjectRef(m, "CapsuleType", (PyObject *)&PyCapsule_Type) < 0) { + return -1; + } + if (PyModule_AddObjectRef(m, "SimpleNamespace", (PyObject *)&_PyNamespace_Type) < 0) { + return -1; + } + return 0; +} + +static struct PyModuleDef_Slot _typesmodule_slots[] = { + {Py_mod_exec, _types_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {Py_mod_gil, Py_MOD_GIL_NOT_USED}, + {0, NULL} +}; + +static struct PyModuleDef typesmodule = { + .m_base = PyModuleDef_HEAD_INIT, + .m_name = "_types", + .m_doc = "Define names for built-in types.", + .m_size = 0, + .m_slots = _typesmodule_slots, +}; + +PyMODINIT_FUNC +PyInit__types(void) +{ + return PyModuleDef_Init(&typesmodule); +} diff --git a/PC/config.c b/PC/config.c index 873f93063057dc..c1a314a7454f81 100644 --- a/PC/config.c +++ b/PC/config.c @@ -23,6 +23,7 @@ extern PyObject* PyInit__sha2(void); extern PyObject* PyInit__sha3(void); extern PyObject* PyInit__statistics(void); extern PyObject* PyInit__sysconfig(void); +extern PyObject* PyInit__types(void); extern PyObject* PyInit__typing(void); extern PyObject* PyInit__blake2(void); extern PyObject* PyInit_time(void); @@ -107,6 +108,7 @@ struct _inittab _PyImport_Inittab[] = { {"time", PyInit_time}, {"_thread", PyInit__thread}, {"_tokenize", PyInit__tokenize}, + {"_types", PyInit__types}, {"_typing", PyInit__typing}, {"_statistics", PyInit__statistics}, #ifdef WIN32 diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index 2e639ddfc320f5..3e9dbcbedbc19c 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -481,6 +481,7 @@ + diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index 31064f50f5c8d7..acbfbd7533c506 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -992,6 +992,9 @@ Modules + + Modules + Modules diff --git a/Python/stdlib_module_names.h b/Python/stdlib_module_names.h index 584b050fc4bb6e..0e5834ebdb233d 100644 --- a/Python/stdlib_module_names.h +++ b/Python/stdlib_module_names.h @@ -92,6 +92,7 @@ static const char* _Py_stdlib_module_names[] = { "_tkinter", "_tokenize", "_tracemalloc", +"_types", "_typing", "_uuid", "_warnings", diff --git a/configure.ac b/configure.ac index 23bd81ed4431b9..b0a8fb368e3ea2 100644 --- a/configure.ac +++ b/configure.ac @@ -7767,6 +7767,7 @@ PY_STDLIB_MOD_SIMPLE([_queue]) PY_STDLIB_MOD_SIMPLE([_random]) PY_STDLIB_MOD_SIMPLE([select]) PY_STDLIB_MOD_SIMPLE([_struct]) +PY_STDLIB_MOD_SIMPLE([_types]) PY_STDLIB_MOD_SIMPLE([_typing]) PY_STDLIB_MOD_SIMPLE([_interpreters]) PY_STDLIB_MOD_SIMPLE([_interpchannels]) From 50c51732f140d30d015e6772a4c83d6f29b5029e Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Tue, 1 Apr 2025 12:52:06 +0100 Subject: [PATCH 3/9] Use the `_types` module in `types` --- Lib/types.py | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/Lib/types.py b/Lib/types.py index 7b9434ebae35bd..26b58e8384c366 100644 --- a/Lib/types.py +++ b/Lib/types.py @@ -2,7 +2,7 @@ Define names for built-in types that aren't directly accessible as a builtin. """ -import sys +import _types # Iterators in Python aren't a matter of type but of protocol. A large # and changing number of builtin types implement *some* flavor of @@ -14,7 +14,7 @@ def _f(): pass LambdaType = type(lambda: None) # Same as FunctionType CodeType = type(_f.__code__) MappingProxyType = type(type.__dict__) -SimpleNamespace = type(sys.implementation) +SimpleNamespace = _types.SimpleNamespace def _cell_factory(): a = 1 @@ -49,7 +49,7 @@ def _m(self): pass MethodDescriptorType = type(str.join) ClassMethodDescriptorType = type(dict.__dict__['fromkeys']) -ModuleType = type(sys) +ModuleType = type(_types) try: raise TypeError @@ -60,7 +60,9 @@ def _m(self): pass GetSetDescriptorType = type(FunctionType.__code__) MemberDescriptorType = type(FunctionType.__globals__) -del sys, _f, _g, _C, _c, _ag, _cell_factory # Not for export +CapsuleType = _types.CapsuleType + +del _types, _f, _g, _C, _c, _ag, _cell_factory # Not for export # Provide a PEP 3115 compliant mechanism for class creation @@ -331,13 +333,4 @@ def wrapped(*args, **kwargs): NoneType = type(None) NotImplementedType = type(NotImplemented) -def __getattr__(name): - if name == 'CapsuleType': - global CapsuleType - import _socket - CapsuleType = type(_socket.CAPI) - return CapsuleType - raise AttributeError(f"module {__name__!r} has no attribute {name!r}") - -__all__ = [n for n in globals() if n[:1] != '_'] -__all__ += ['CapsuleType'] +__all__ = [n for n in globals() if not n.startswith('_')] From 84684499115d1adc18e279a7e46ccea4d25215e0 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Tue, 1 Apr 2025 15:02:18 +0100 Subject: [PATCH 4/9] Apply configure changes --- configure | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/configure b/configure index a058553480ca5a..7f23fac856c451 100755 --- a/configure +++ b/configure @@ -781,6 +781,8 @@ MODULE__INTERPRETERS_FALSE MODULE__INTERPRETERS_TRUE MODULE__TYPING_FALSE MODULE__TYPING_TRUE +MODULE__TYPES_FALSE +MODULE__TYPES_TRUE MODULE__STRUCT_FALSE MODULE__STRUCT_TRUE MODULE_SELECT_FALSE @@ -30975,6 +30977,27 @@ then : +fi + + + if test "$py_cv_module__types" != "n/a" +then : + py_cv_module__types=yes +fi + if test "$py_cv_module__types" = yes; then + MODULE__TYPES_TRUE= + MODULE__TYPES_FALSE='#' +else + MODULE__TYPES_TRUE='#' + MODULE__TYPES_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__TYPES_STATE=$py_cv_module__types$as_nl" + if test "x$py_cv_module__types" = xyes +then : + + + fi @@ -33650,6 +33673,10 @@ if test -z "${MODULE__STRUCT_TRUE}" && test -z "${MODULE__STRUCT_FALSE}"; then as_fn_error $? "conditional \"MODULE__STRUCT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${MODULE__TYPES_TRUE}" && test -z "${MODULE__TYPES_FALSE}"; then + as_fn_error $? "conditional \"MODULE__TYPES\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${MODULE__TYPING_TRUE}" && test -z "${MODULE__TYPING_FALSE}"; then as_fn_error $? "conditional \"MODULE__TYPING\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 From 816b4af66eb7e896236541f857af9ffd6162b4a7 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Tue, 1 Apr 2025 15:12:50 +0100 Subject: [PATCH 5/9] fixup! Apply configure changes --- configure | 1 + 1 file changed, 1 insertion(+) diff --git a/configure b/configure index 7f23fac856c451..ff08b7ebf3a9e1 100755 --- a/configure +++ b/configure @@ -30999,6 +30999,7 @@ then : + fi From d97b1227ea96239f5e2ec1741a86952586ddb9c2 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Tue, 1 Apr 2025 15:38:26 +0100 Subject: [PATCH 6/9] fixup! Apply configure changes --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index ff08b7ebf3a9e1..c6016470637012 100755 --- a/configure +++ b/configure @@ -30977,6 +30977,7 @@ then : + fi @@ -30999,7 +31000,6 @@ then : - fi From 04d9b4e463a75f10fb150859544133822b9d2d2a Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Tue, 1 Apr 2025 15:48:06 +0100 Subject: [PATCH 7/9] Remove `internal/` prefix --- Modules/_typesmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_typesmodule.c b/Modules/_typesmodule.c index f2e925a69dca1d..aabb35f47eefc3 100644 --- a/Modules/_typesmodule.c +++ b/Modules/_typesmodule.c @@ -1,7 +1,7 @@ /* _types module */ #include "Python.h" -#include "internal/pycore_namespace.h" // _PyNamespace_Type +#include "pycore_namespace.h" // _PyNamespace_Type static int _types_exec(PyObject *m) From 9c508ae1be58bdfb119fee90a5ad243b46085c09 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Tue, 1 Apr 2025 16:30:18 +0100 Subject: [PATCH 8/9] Remove ``types.__all__`` `from types import *` will ignore underscore-prefixed names by default, so defining `__all__` doesn't add anything. --- Lib/types.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/Lib/types.py b/Lib/types.py index 26b58e8384c366..a0ad90b8d3272a 100644 --- a/Lib/types.py +++ b/Lib/types.py @@ -332,5 +332,3 @@ def wrapped(*args, **kwargs): EllipsisType = type(Ellipsis) NoneType = type(None) NotImplementedType = type(NotImplemented) - -__all__ = [n for n in globals() if not n.startswith('_')] From b7f5df13f541c135b166eec4cf1ff19fd2c39613 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Tue, 1 Apr 2025 17:19:46 +0100 Subject: [PATCH 9/9] Reinstate __all__ for pydoc --- Lib/types.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Lib/types.py b/Lib/types.py index a0ad90b8d3272a..9aa0a3b087c1c7 100644 --- a/Lib/types.py +++ b/Lib/types.py @@ -332,3 +332,5 @@ def wrapped(*args, **kwargs): EllipsisType = type(Ellipsis) NoneType = type(None) NotImplementedType = type(NotImplemented) + +__all__ = [n for n in globals() if not n.startswith('_')] # for pydoc