HPy HPyField_Load(HPyContext *ctx, HPy source_object, HPyField source_field)
void HPyField_Store(HPyContext *ctx, HPy target_object, HPyField *target_field, HPy h)

HPyFields should be used ONLY in parts of memory which is known to the GC, e.g. memory allocated by HPy_New:

  • NEVER declare a local variable of type HPyField

  • NEVER use HPyField on a struct allocated by e.g. malloc()

CPython’s note: contrarily than PyObject*, you don’t need to manually manage refcounting when using HPyField: if you use HPyField_Store to overwrite an existing value, the old object will be automatically decrefed. This means that you CANNOT use HPyField_Store to write memory which contains uninitialized values, because it would try to decref a dangling pointer.

Note that HPy_New automatically zeroes the memory it allocates, so everything works well out of the box. In case you are using manually allocated memory, you should initialize the HPyField to HPyField_NULL.

Note the difference:

  • obj->f = HPyField_NULL: this should be used only to initialize uninitialized memory. If you use it to overwrite a valid HPyField, you will cause a memory leak (at least on CPython)

  • HPyField_Store(ctx, &obj->f, HPy_NULL): this does the right and decref the old value. However, you CANNOT use it if the memory is not initialized.

Note: target_object and source_object are there in case an implementation needs to add write and/or read barriers on the objects. They are ignored by CPython but e.g. PyPy needs a write barrier.