Правильное использование ctypes для вызова _Py_Mangle?

Пока я сидел на грибе и размышлял о тонкостях написания функции для реализации алгоритма искажения имени Python, мне в голову пришла невероятно лучшая идея. Почему бы не использовать рецепт, уже встроенный в язык, для достижения такой цели? Поэтому я вытащил ctypes из своей сумки, чтобы помочь с делом, и казнил ctypes.pythonapi._Py_Mangle('Demo', '__test'). И вот, из ниоткуда появилась ошибка, говорящая OSError: exception: access violation reading 0x00000A65646F00A8, и больше не стал объяснять загадку.

Полное взаимодействие с интерпретатором выглядит следующим образом:

Python 3.4.2 (v3.4.2:ab2c023a9432, Oct  6 2014, 22:16:31) [MSC v.1600 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import ctypes
>>> ctypes.pythonapi._Py_Mangle('Demo', '__test')
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    ctypes.pythonapi._Py_Mangle('Demo', '__test')
OSError: exception: access violation reading 0x00000A65646F00A8

Кто-нибудь знает, что нужно изменить, чтобы успешно вызвать функцию искажения?


person Noctis Skytower    schedule 13.01.2015    source источник
comment
pythonapi является экземпляром PyDLL, который является подклассом CDLL, который устанавливает флаг для указателей функций, чтобы предотвратить освобождение глобальной блокировки интерпретатора (GIL) во время вызова. В противном случае преобразования аргументов по умолчанию и тип результата такие же, как CDLL. Таким образом, вам нужно определить типы: ctypes.pythonapi._Py_Mangle.argtypes = [ctypes.py_object, ctypes.py_object]; ctypes.pythonapi._Py_Mangle.restype = ctypes.py_object.   -  person Eryk Sun    schedule 13.01.2015
comment
К вашему сведению, это не поможет, если ваш код должен работать на PyPy, Jython или IronPython. На самом деле должен быть sys.name_mangle или inspect.name_mangle, чтобы сделать это за вас.   -  person Eryk Sun    schedule 13.01.2015
comment
@eryksun: Есть ли для этого запрос функции или PEP? Или хотя бы python-ideas обсуждение?   -  person Kevin    schedule 13.01.2015


Ответы (1)


Благодаря комментариям eryksun ответ на проблему довольно прост:

>>> from ctypes import pythonapi, py_object
>>> py_mangle = pythonapi._Py_Mangle
>>> py_mangle.argtypes = py_object, py_object
>>> py_mangle.restype = py_object
>>> py_mangle('Demo', '__test')
'_Demo__test'
person Noctis Skytower    schedule 13.01.2015