[Python] Copy a generator via ctypes

Discussão em 'Python' iniciado por Stack, Abril 16, 2025.

  1. Stack

    Stack Membro Participativo

    I'm trying to copy a generator by using PyGen_New by passing in a frame object. Thus far, I get the following error that I don't understand:

    Traceback (most recent call last):
    File "C:\test.py", line 19, in <module>
    frame = Frame(gen.gi_code)
    ^^^^^^^^^^^^^^^^^^
    File "C:\test.py", line 11, in Frame
    return ctypes.pythonapi.PyFrame_New(
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    OSError: exception: access violation reading 0x0000000000000008


    code used:

    from types import CodeType, FrameType
    import ctypes


    ctypes.pythonapi.PyThreadState_Get.argtypes = None
    ctypes.pythonapi.PyThreadState_Get.restype = ctypes.POINTER(ctypes.c_ulong)
    ctypes.pythonapi.PyFrame_New.restype = ctypes.POINTER(ctypes.py_object)

    def Frame(code_obj: CodeType, globals: dict = None, locals: dict = None) -> FrameType:
    """Instantiates a FrameType object"""
    return ctypes.pythonapi.PyFrame_New(
    ctypes.pythonapi.PyThreadState_Get(),
    ctypes.cast(id(code_obj), ctypes.POINTER(ctypes.c_int)),
    globals,
    locals,
    )

    gen = (i for i in range(3))
    frame = Frame(gen.gi_code)

    ctypes.pythonapi.PyGen_New.restype = ctypes.POINTER(ctypes.py_object)
    new_gen = ctypes.pythonapi.PyGen_New(
    ctypes.cast(id(frame), ctypes.POINTER(ctypes.c_void_p))
    )

    for value in new_gen:
    print(value)


    Note: I do understand that copying and pickling generators is not intended by the cpython language so you don't need to tell me about this and all the footguns associated with trying (it's not the point of this question). The point of this question is overcoming and understanding the nuances of the error faced with a solution specific to the problem case; it's not supposed to be a generalizable problem necessarily to all generator instances.

    Additionally, yes, this is using c level implementation details. I'm aware of the nuances of this; it's not the point of this question.

    code was ran on python version 3.11.9

    Continue reading...

Compartilhe esta Página