Title: Add tests to prevent regressions with the combination of `ctypes` and metaclasses. · Issue #125783 · python/cpython · GitHub
Open Graph Title: Add tests to prevent regressions with the combination of `ctypes` and metaclasses. · Issue #125783 · python/cpython
X Title: Add tests to prevent regressions with the combination of `ctypes` and metaclasses. · Issue #125783 · python/cpython
Description: Feature or enhancement Proposal: There were breaking changes to ctypes in Python 3.13. Projects like comtypes and pyglet, which implement functionality by combining ctypes and metaclasses, no longer work unless their codebases are update...
Open Graph Description: Feature or enhancement Proposal: There were breaking changes to ctypes in Python 3.13. Projects like comtypes and pyglet, which implement functionality by combining ctypes and metaclasses, no longe...
X Description: Feature or enhancement Proposal: There were breaking changes to ctypes in Python 3.13. Projects like comtypes and pyglet, which implement functionality by combining ctypes and metaclasses, no longe...
Opengraph URL: https://github.com/python/cpython/issues/125783
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Add tests to prevent regressions with the combination of `ctypes` and metaclasses.","articleBody":"# Feature or enhancement\n\n### Proposal:\n\nThere were [breaking changes to `ctypes` in Python 3.13](https://docs.python.org/3.13/whatsnew/3.13.html#ctypes). \nProjects like [`comtypes`](https://github.com/enthought/comtypes/) and [`pyglet`](https://github.com/pyglet/pyglet), which implement functionality by combining `ctypes` and metaclasses, no longer work unless their codebases are updated.\nWe discussed what changes such projects need to make to their codebases in gh-124520.\n\nI believe the easiest and most effective way to prevent regressions from happening again is to add tests on the `cpython` side.\n\nI wrote a simple test like the one below.\n\n```py\n# Lib/test/test_ctypes/test_c_simple_type_meta.py?\nimport unittest\nimport ctypes\nfrom ctypes import POINTER, c_void_p\n\nfrom ._support import PyCSimpleType, _CData, _SimpleCData\n\n\nclass PyCSimpleTypeAsMetaclassTest(unittest.TestCase):\n def tearDown(self):\n # to not leak references, we must clean _pointer_type_cache\n ctypes._reset_cache()\n\n def test_early_return_in_dunder_new_1(self):\n # this implementation is used in `IUnknown` of comtypes.\n\n class _ct_meta(type):\n def __new__(cls, name, bases, namespace):\n self = super().__new__(cls, name, bases, namespace)\n if bases == (c_void_p,):\n return self\n if issubclass(self, _PtrBase):\n return self\n if bases == (object,):\n _ptr_bases = (self, _PtrBase)\n else:\n _ptr_bases = (self, POINTER(bases[0]))\n p = _p_meta(f\"POINTER({self.__name__})\", _ptr_bases, {})\n ctypes._pointer_type_cache[self] = p\n return self\n\n class _p_meta(PyCSimpleType, _ct_meta):\n pass\n\n class _PtrBase(c_void_p, metaclass=_p_meta):\n pass\n\n class _CtBase(object, metaclass=_ct_meta):\n pass\n\n class _Sub(_CtBase):\n pass\n\n class _Sub2(_Sub):\n pass\n\n\n def test_early_return_in_dunder_new_2(self):\n # this implementation is used in `CoClass` of comtypes.\n\n class _ct_meta(type):\n def __new__(cls, name, bases, namespace):\n self = super().__new__(cls, name, bases, namespace)\n if isinstance(self, _p_meta):\n return self\n p = _p_meta(\n f\"POINTER({self.__name__})\", (self, c_void_p), {}\n )\n ctypes._pointer_type_cache[self] = p\n return self\n\n class _p_meta(PyCSimpleType, _ct_meta):\n pass\n\n class _Base(object):\n pass\n\n class _Sub(_Base, metaclass=_ct_meta):\n pass\n\n class _Sub2(_Sub):\n pass\n\n```\n\nIf no errors occur when this test is executed, we can assume that no regressions have occurred with the combination of `ctypes` and metaclasses.\nHowever, I feel that this may not be enough. What should we specify as the target for the `assert`?\n\n### Has this already been discussed elsewhere?\n\nNo response given\n\n### Links to previous discussion of this feature:\n\nhttps://github.com/python/cpython/issues/124520\n\n\u003c!-- gh-linked-prs --\u003e\n### Linked PRs\n* gh-125881\n* gh-125987\n* gh-125988\n* gh-126126\n* gh-126275\n* gh-126276\n\u003c!-- /gh-linked-prs --\u003e\n","author":{"url":"https://github.com/junkmd","@type":"Person","name":"junkmd"},"datePublished":"2024-10-21T11:33:32.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":7},"url":"https://github.com/125783/cpython/issues/125783"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:6bbf7e94-5ccd-2b8d-61db-6952a6a44405 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | 92F8:2AC946:2BF21D:3BA799:6969AA0A |
| html-safe-nonce | cd331a050f53869ce9bf9b54b044e196164c16fb9500fae0b3603bc0f0a6e5b8 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI5MkY4OjJBQzk0NjoyQkYyMUQ6M0JBNzk5OjY5NjlBQTBBIiwidmlzaXRvcl9pZCI6IjcwMjQ5MTQzMjcxODQ5NzYzOTQiLCJyZWdpb25fZWRnZSI6ImlhZCIsInJlZ2lvbl9yZW5kZXIiOiJpYWQifQ== |
| visitor-hmac | e4b978b8420fa7e6455d456eaa89b16a81a242c148a0cd36b86a8ee192e1d39a |
| hovercard-subject-tag | issue:2602262301 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/python/cpython/125783/issue_layout |
| twitter:image | https://opengraph.githubassets.com/7c51b776969d52343e4ed42d871050d16dbadb32374d7d5b7362ae161574780f/python/cpython/issues/125783 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/7c51b776969d52343e4ed42d871050d16dbadb32374d7d5b7362ae161574780f/python/cpython/issues/125783 |
| og:image:alt | Feature or enhancement Proposal: There were breaking changes to ctypes in Python 3.13. Projects like comtypes and pyglet, which implement functionality by combining ctypes and metaclasses, no longe... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | junkmd |
| hostname | github.com |
| expected-hostname | github.com |
| None | 24c4c97a2d520cb286b35e1a4c22d7a4df3c26a2fa28dd7cdf0e65db327b4de7 |
| turbo-cache-control | no-preview |
| go-import | github.com/python/cpython git https://github.com/python/cpython.git |
| octolytics-dimension-user_id | 1525981 |
| octolytics-dimension-user_login | python |
| octolytics-dimension-repository_id | 81598961 |
| octolytics-dimension-repository_nwo | python/cpython |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 81598961 |
| octolytics-dimension-repository_network_root_nwo | python/cpython |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 124667f43168afb6c9c03b7c02eb5b1d2e1be3d9 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width