-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Design type creation API #4
Comments
Adding members to a class is fine as long as it is mutable, and making a class immutable is also fine. Are there any cases where that wouldn't work? |
Here is a sketch. There are four parts of a class that must be defined when the class is created.
Everything else can be added after class creation, including making it immutable. int PyApi_Class_Create(
PyStrRef name, PyRef* mro, uintptr_t mro_length,
PyRef metaclass, uintptr_t opaque_section_size,
UtfString *slot_names, uintptr_t slot_count,
PyClassRef *result);
int PyApi_Class_SetAttr(PyClassRef cls, PyStrRef name, PyRef value);
void PyApi_Class_MakeImmutable(PyClassRef cls); Alternatively, and probably better, is to replace int PyApi_Class_Create(
PyStrRef name, PyRef* mro, uintptr_t mro_length,
PyRef metaclass, PyApi_LayoutDescription *layout,
PyClassRef *result); Once created, the class can be filled out with: int PyApi_Class_SetAttr(PyClassRef cls, PyStrRef name, PyRef value);
void PyApi_Class_MakeImmutable(PyClassRef cls); plus some helper functions to add binary, indexing and call operators. @encukou thoughts? |
I think the MRO should always be computed from the bases, so this should take bases rather than MRO. |
How the MRO is computed from the bases is up to the metaclass, so I think it better to specify the MRO.
By slots, I mean
If you care about optimization, then keeping the API simple and consistent is the best thing to do. I think we should only allow one opaque section in the MRO. Allowing multiple opaque sections slows things down due to the indirection, and makes writing C extensions more error prone, IMO. |
How would
For multiple opaque sections, you could ask authors of binding generators for C++ (or another language with inheritance) for their use cases. |
There is no unique list of bases for any MRO, but you can compute a minimal one. Why do you need the bases anyway, apart from having a result for |
Sorry, I don't follow your reasoning here. Why should the user pre-compute the MRO? |
The MRO is determined by the metaclass. If the API accepts bases, then we need to call the metaclass to determine the MRO, which complicates things as the VM needs to call int PyApi_Class_CreateFromBases(
PyStrRef name, PyRef* bases, uintptr_t bases_length,
PyRef metaclass, PyApi_LayoutDescription *layout,
PyClassRef *result)
{
PyRef mro;
int err = PyApi_CallMethod_s(metaclass, "str", bases, bases_length, &mro);
/* Error handling here */
return PyApi_Class_Create(name, mro, metaclass, layout, result);
} It works, but it is the MRO that defines the class, so we might as well expose the API that takes an MRO. |
That |
It sounds like that would
|
We're working toward something like this, gradually. There's now a proposal to add a “ |
To frame this question in a way that supports my position: do you think that allowing types to be made immutable at any arbitrary time (as opposed to "before anyone could be using it") might prevent us from later optimising anything about immutable types? |
Type creation is a pain point in the current Limited API. (The problems are systemic -- module spec has similar issues -- but they're most visible there & a solution should be applicable elsewhere.)
The initial description -- PyType_Spec now and “layout and inheritance description” in #2 (comment) -- can't easily be extended. The current extension mechanism, slots, is not type-safe. Adding methods and properties to a live class (my interpretation of Mark's “current thinking” in the linked issue) means modifying a possibly-immutable class, a no-no as it could invalidate useful invariants.
We could have an opaque “configuration” object that's allocated and configured using functions, with a “finalize” function that turns it into a class. Not sure about performance and other implications there.
The text was updated successfully, but these errors were encountered: