Skip to content

Issue when binding to Python API (struct__typeobject._fields_ AttributeError: _fields_ is final) #211

@mara004

Description

@mara004

When binding to the Python C API via

# pypdfium2 ctypesgen
ctypesgen --system-headers python3.11/Python.h --all-headers -l python --dllclass pythonapi -o ctypes_python.py

or

# legacy ctypesgen
# then manually replace CDLL with PyDLL, or better load_library("python3") with ctypes.pythonapi (this is to get the GIL & error checking correct)
ctypesgen /usr/include/python3.11/Python.h --all-headers -l python3 -o ctypes_python.py

I get the following strange exception:

Traceback (most recent call last):
  File "/home/me/projects/third_party/ctypesgen_orig/ctypes_python.py", line 15940, in <module>
    struct__typeobject._fields_ = [
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: _fields_ is final

struct__typeobject is the ctypesgen definition alias of PyTypeObject and _typeobject, which apparently is some sort of complex forward-declared struct with direct and indirect self-references.
But that doesn't yet explain the exception. In particular, it works if we isolate just this struct and its dependencies by adding --symbol-rules 'if_needed=\w+' yes=PyTypeObject to the pypdfium2 ctypesgen call.1

Attached are the two samples complete.py (broken) and isolated.py (passing): Samples.zip

Excluding PyTypeObject and dependents via --symbol-rules never=... would only be a workaround, and is undesirable because this is a core object.
I guess a reasonable workaround might be to make it opaque by linking in a spoof definition, though (as suggested in #20 (comment)).

Footnotes

  1. Not possible with legacy ctypesgen due to lack of if_needed and flexible symbol filter pipeline in CLI.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions