logo       

[Python-Dev] Py_TPFLAGS_HEAPTYPE too overloaded: msg#00610

python-dev

Subject: [Python-Dev] Py_TPFLAGS_HEAPTYPE too overloaded

I'm writing a C Python extension that needs to generate PyTypeObjects
dynamically. Unfortunately, the Py_TPFLAGS_HEAPTYPE flag is overloaded
in a way that makes it difficult to achieve this goal.

The documentation for Pt_TPFLAGS_HEAPTYPE says:

Py_TPFLAGS_HEAPTYPE

This bit is set when the type object itself is allocated
on the heap. In this case, the ob_type field of its
instances is considered a reference to the type, and the
type object is INCREFâed when a new instance is created,
and DECREFâed when an instance is destroyed (this does not
apply to instances of subtypes; only the type referenced
by the instanceâs ob_type gets INCREFâed or DECREFâed).

This sounds like exactly what I want. I want my type object INCREF'd
and DECREF'd by its instances so it doesn't leak or get deleted
prematurely. If this were all that Py_TPFLAGS_HEAPTYPE did, it would
work great for me.

Unfortunately, Py_TPFLAGS_HEAPTYPE is also overloaded to mean
"user-defined type" (as opposed to a built-in type). It controls
numerous subtle behaviors such as:

- whether the type's name is module.type or just type.
- whether you're allowed to set __name__, __module__, or __bases__ on the type.
- whether you're allowed to set __class__ on instances of this type.
- whether the module name comes from the type name or the __module__ attribute.
- whether it will use type->tp_doc as the docstring
- whether its repr() calls it a "class" or a "type".
- whether you can set attributes of the type.
- whether someone is attempting the Carlo Verre hack.

So I'm stuck with an unenviable choice. I think the lesser of two evils
is to *not* specify Py_TPFLAGS_HEAPTYPE, because the worst that will
happen is that my types will leak. This is not as bad as having someone
set __class__ on one of my instances, or set attributes on my type, etc.

Ideally the interpreter would have a separate flag like
Py_TPFLAGS_BUILTIN that would trigger all of the above behaviors, but
still make it possible to have dynamically generated built-in types get
garbage collected appropriately.

At the very least, the documentation I cited above should make it clear
that Py_TPFLAGS_HEAPTYPE controls more than just whether the type gets
INCREF'd and DECREF'd. Based on the list of behaviors I discovered
above, it is almost certainly not correct for a C exension type to be
declared with Py_TPFLAGS_HEAPTYPE.

Josh

_______________________________________________
Python-Dev mailing list
Python-Dev@xxxxxxxxxx
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
http://mail.python.org/mailman/options/python-dev/maillists%40codeha.us
<Prev in Thread] Current Thread [Next in Thread>
Google Custom Search

News | Mail Home | sitemap | FAQ | advertise