- :mod:`argparse`
- :mod:`csv`
+ - :mod:`ctypes`
- :mod:`!ctypes.macholib`
- :mod:`decimal` (use :data:`decimal.SPEC_VERSION` instead)
- :mod:`http.server`
- :mod:`argparse`
- :mod:`csv`
+ - :mod:`ctypes`
- :mod:`!ctypes.macholib`
- :mod:`decimal` (use :data:`decimal.SPEC_VERSION` instead)
- :mod:`http.server`
import sysconfig as _sysconfig
import types as _types
-__version__ = "1.1.0"
-
from _ctypes import Union, Structure, Array
from _ctypes import _Pointer
from _ctypes import CFuncPtr as _CFuncPtr
-from _ctypes import __version__ as _ctypes_version
from _ctypes import RTLD_LOCAL, RTLD_GLOBAL
from _ctypes import ArgumentError
from _ctypes import SIZEOF_TIME_T
from struct import calcsize as _calcsize
-if __version__ != _ctypes_version:
- raise Exception("Version number mismatch", __version__, _ctypes_version)
-
if _os.name == "nt":
from _ctypes import COMError, CopyComPointer, FormatError
raise SystemError(f"Unexpected sizeof(time_t): {SIZEOF_TIME_T=}")
_reset_cache()
+
+
+def __getattr__(name):
+ if name == "__version__":
+ from warnings import _deprecated
+
+ _deprecated("__version__", remove=(3, 20))
+ return "1.1.0" # Do not change
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
import os
+import unittest
from test import support
from test.support import import_helper
# skip tests if the _ctypes extension was not built
import_helper.import_module('ctypes')
+
+class TestModule(unittest.TestCase):
+ def test_deprecated__version__(self):
+ import ctypes
+ import _ctypes
+
+ for mod in (ctypes, _ctypes):
+ with self.subTest(mod=mod):
+ with self.assertWarnsRegex(
+ DeprecationWarning,
+ "'__version__' is deprecated and slated for removal in Python 3.20",
+ ) as cm:
+ getattr(mod, "__version__")
+ self.assertEqual(cm.filename, __file__)
+
+
def load_tests(*args):
return support.load_package_tests(os.path.dirname(__file__), *args)
--- /dev/null
+Deprecate ``__version__`` from :mod:`ctypes`. Patch by Hugo van Kemenade.
MOD_ADD("FUNCFLAG_USE_ERRNO", PyLong_FromLong(FUNCFLAG_USE_ERRNO));
MOD_ADD("FUNCFLAG_USE_LASTERROR", PyLong_FromLong(FUNCFLAG_USE_LASTERROR));
MOD_ADD("FUNCFLAG_PYTHONAPI", PyLong_FromLong(FUNCFLAG_PYTHONAPI));
- MOD_ADD("__version__", PyUnicode_FromString("1.1.0"));
MOD_ADD("_memmove_addr", PyLong_FromVoidPtr(memmove));
MOD_ADD("_memset_addr", PyLong_FromVoidPtr(memset));
}
+static PyObject *
+_ctypes_getattr(PyObject *Py_UNUSED(self), PyObject *args)
+{
+ PyObject *name;
+ if (!PyArg_UnpackTuple(args, "__getattr__", 1, 1, &name)) {
+ return NULL;
+ }
+
+ if (PyUnicode_Check(name) && PyUnicode_EqualToUTF8(name, "__version__")) {
+ if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "'__version__' is deprecated and slated for "
+ "removal in Python 3.20",
+ 1) < 0) {
+ return NULL;
+ }
+ return PyUnicode_FromString("1.1.0"); // Do not change
+ }
+
+ PyErr_Format(PyExc_AttributeError,
+ "module '_ctypes' has no attribute %R", name);
+ return NULL;
+}
+
PyMethodDef _ctypes_module_methods[] = {
+ {"__getattr__", _ctypes_getattr, METH_VARARGS},
{"get_errno", get_errno, METH_NOARGS},
{"set_errno", set_errno, METH_VARARGS},
{"_unpickle", unpickle, METH_VARARGS },