# PEP 793 – PyModExport: A new entry point for C extension modules

**URL:** https://discuss.python.org/t/pep-793-pymodexport-a-new-entry-point-for-c-extension-modules/93444
**Category:** PEPs
**Created:** [May 27, 2025, 4:55am UTC](https://discuss.python.org/t/pep-793-pymodexport-a-new-entry-point-for-c-extension-modules/93444 "2025-05-27T04:55:15Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![encukou](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/encukou/32/2461_2.png) [@encukou](https://discuss.python.org/u/encukou)
#### Post date: [May 27, 2025, 4:55am UTC](https://discuss.python.org/t/pep-793-pymodexport-a-new-entry-point-for-c-extension-modules/93444/1 "2025-05-27T04:55:15Z")

</div>

We’ve just published [PEP 793](https://peps.python.org/pep-0793/) – PyModExport: A new entry point for C extension modules. Thanks @AA-Turner’s for the reviews!

## [Abstract](https://peps.python.org/pep-0793/#abstract)

In this PEP, we propose a new entry point for C extension modules, by which one can define a module using an array of `PyModuleDef_Slot` structures without an enclosing `PyModuleDef` structure. This allows extension authors to avoid using a statically allocated `PyObject`, lifting the most common obstacle to making one compiled library file usable with both regular and free-threaded builds of CPython.

To make this viable, we also specify new module slot types to replace `PyModuleDef`’s fields, and to allow adding a _token_ similar to the `Py_tp_token` used for type objects.

We also add an API for defining modules from slots dynamically.

* * *

## Code example

The PEP includes [a full example](https://peps.python.org/pep-0793/#example). If you compile it (with _non-free-threaded_ Python headers) and remove extension file’s the version suffix (e.g. on Linux, rename to `examplemodule.so`), it will work with both regular and `t` Python.

To get some code on this page, here’s the definition from the example:

```c
static PyModuleDef_Slot examplemodule_slots[] = {
    {Py_mod_name, "examplemodule"},
    {Py_mod_doc, (char*)examplemodule_doc},
    {Py_mod_exec, (void*)examplemodule_exec},
    {Py_mod_methods, examplemodule_methods},
    {Py_mod_state_size, (void*)sizeof(examplemodule_state)},
    {0}
};

PyMODEXPORT_FUNC
PyModExport_examplemodule(PyObject *spec)
{
    return examplemodule_slots;
}

```

* * *

See [this topic](https://discuss.python.org/t/86458) for the larger plan for stable ABI for free-threaded builds.

* * *

What do y’all think?

---

<div class="post-metadata">

### Author: ![efimov-mikhail](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/efimov-mikhail/32/23145_2.png) [@efimov-mikhail](https://discuss.python.org/u/efimov-mikhail)
#### Post date: [May 27, 2025, 9:26am UTC](https://discuss.python.org/t/pep-793-pymodexport-a-new-entry-point-for-c-extension-modules/93444/2 "2025-05-27T09:26:55Z")

</div>

My first impression about this PEP is great!  
For now I’m not deeply in nuances but I can read example section and understand what’s going on without reading any docs. And, of course, removing “the most common obstacle to making one compiled library file usable with both regular and free-threaded builds of CPython” sounds nice.

---

<div class="post-metadata">

### Author: ![steve.dower](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/steve.dower/32/56_2.png) [@steve.dower](https://discuss.python.org/u/steve.dower)
#### Post date: [May 27, 2025, 10:14am UTC](https://discuss.python.org/t/pep-793-pymodexport-a-new-entry-point-for-c-extension-modules/93444/3 "2025-05-27T10:14:17Z")

</div>

> [@encukou](#):
>
> This allows extension authors to avoid using a statically allocated `PyObject`, lifting the most common obstacle to making one compiled library file usable with both regular and free-threaded builds of CPython.

Can’t this already be avoided? Or we can add more changes by adding more slots. The “common obstacle” is just single-phase init, right?

This strikes me as primarily a path towards removing single-phase init entirely, which I fully support, but I’d like to see that acknowledged. I didn’t spot in the PEP text any clear answer to what the “common obstacle” actually is - a statically allocated `PyObject` _in theory_ is perfectly fine provided that you meet a ridiculous set of conditions (which we wouldn’t expect anyone to meet).

But using multi-phase init gets you around that particular issue already, and the problem is just that single-phase is still supported at all and so we can’t assume that multi-phase is being used when the module is first loaded.

It may still be that adding _another_ API (that could take 10+ years for people to actually start using) is the best approach, but I’d like to see more clarity around whether “just kill off single-phase init” would also achieve the same goals.

* * *

It’s a mild aside, but I don’t see a problem with adding new slots that also cover static fields and using them in preference to the static fields, if that’s the main value here. No doubt there are backwards compatibility limitations here (I know we don’t love the use of `void *` for a range of different value types), but if these are actual blockers to improving the range of slots then _that_ needs to be explained better. The text really leads towards single-phase init being the problem being solved here, without actually saying it.

---

<div class="post-metadata">

### Author: ![encukou](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/encukou/32/2461_2.png) [@encukou](https://discuss.python.org/u/encukou)
#### Post date: [May 27, 2025, 11:09am UTC](https://discuss.python.org/t/pep-793-pymodexport-a-new-entry-point-for-c-extension-modules/93444/4 "2025-05-27T11:09:06Z")

</div>

This PEP is pretty much orthogonal to removing single-phase init, that’s why you don’t see it mentioned :‍)

The obstacle is the static `PyModuleDef`.

> [@steve.dower](#):
>
> a statically allocated `PyObject` _in theory_ is perfectly fine

It is not. The layout of `PyObject` differs between the regular and free-threaded builds, so if you bake a static `PyObject` into the compiled extension, it will not work for both builds.

> [@steve.dower](#):
>
> I’d like to see more clarity around whether “just kill off single-phase init” would also achieve the same goals.

It would not, because current multi-phase init expects the entry point to return a statically allocated `PyModuleDef`. And `PyModuleDef` is, for reasons lost to time, a `PyObject` subclass.

> [@steve.dower](#):
>
> Can’t using a statically allocated `PyObject` already be avoided?

Hmm, technically, yes, you can avoid `PyModuleDef` by using the low-level API (`PyModule_NewObject` or `PyModule_New`) with single-phase init, and filling in methods & ` __doc__ ` manually.  
The PEP should mention that.

---

<div class="post-metadata">

### Author: ![steve.dower](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/steve.dower/32/56_2.png) [@steve.dower](https://discuss.python.org/u/steve.dower)
#### Post date: [May 27, 2025, 11:54am UTC](https://discuss.python.org/t/pep-793-pymodexport-a-new-entry-point-for-c-extension-modules/93444/5 "2025-05-27T11:54:14Z")

</div>

> [@encukou](#):
>
> It would not, because current multi-phase init expects the entry point to return a statically allocated `PyModuleDef`. And `PyModuleDef` is, for reasons lost to time, a `PyObject` subclass.

Ah okay, this is the point that I missed.

Any possibility of making `PyModuleDef` be shaped as if it were always using non-freethreaded `PyObject` as the base? Statically allocated, it should be immortal anyway, and so it’s not being refcounted. A lot of the other changes still make sense then (like not returning it from `_Get`), but I think we can avoid the problem of having three potential APIs to support where everyone is still using the first one…

---

<div class="post-metadata">

### Author: ![encukou](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/encukou/32/2461_2.png) [@encukou](https://discuss.python.org/u/encukou)
#### Post date: [May 27, 2025, 12:25pm UTC](https://discuss.python.org/t/pep-793-pymodexport-a-new-entry-point-for-c-extension-modules/93444/6 "2025-05-27T12:25:39Z")

</div>

> [@steve.dower](#):
>
> Any possibility of making `PyModuleDef` be shaped as if it were always using non-freethreaded `PyObject` as the base? Statically allocated, it should be immortal anyway, and so it’s not being refcounted.

Personally, I’d rather support three well-defined APIs\[1\] than this kind of fragile trickery.  
`PyModuleDef` layout is public API. Refcounting is a valid on it, though it doesn’t make much sense.  
More importantly, the import system (and any 3rd party reimplementation of that) will need to call `PyTYPE` on it to separate it from single-phase extension that returns `PyModule`. (BTW, this is what allowed the current multi-phase init to reuse the import hook.)

* * *

1. well, _two_ well defined ones plus a really weird one

---

<div class="post-metadata">

### Author: ![steve.dower](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/steve.dower/32/56_2.png) [@steve.dower](https://discuss.python.org/u/steve.dower)
#### Post date: [May 27, 2025, 1:14pm UTC](https://discuss.python.org/t/pep-793-pymodexport-a-new-entry-point-for-c-extension-modules/93444/7 "2025-05-27T13:14:21Z")

</div>

Makes sense. The two things I’d really like to see added (and discussed, since I expect controversy):

- a copy-pasteable implementation of the current entrypoint so that code can skip right to the new API and offer an equivalent entrypoint that works for 3.14 and earlier (copy-pasteable so that Cython and friends can copy-paste it - separately distributed is less useful here, IMHO)
- a hard deprecation/disablement deadline for the existing API. The _biggest_ problem with the existing two tier API is that people have never moved, so let’s not make that mistake - this design allows for noisy compile-time and import-time warnings, so let’s be noisy and actually remove the old one (at least single-phase, but ideally both it sounds like) as quickly as we can.

---

<div class="post-metadata">

### Author: ![encukou](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/encukou/32/2461_2.png) [@encukou](https://discuss.python.org/u/encukou)
#### Post date: [May 27, 2025, 2:22pm UTC](https://discuss.python.org/t/pep-793-pymodexport-a-new-entry-point-for-c-extension-modules/93444/8 "2025-05-27T14:22:31Z")

</div>

Let’s discuss all that, but I consider it out of scope here.  
This is not the “entrypoint API changes I’d like in 3.15” PEP. It’s compatible with [my planned next steps](https://discuss.python.org/t/86458); I believe it’s compatible enough with yours; and I believe it’ll be a net benefit even if ($DEITY forbid) none of the next steps make it.

> [@steve.dower](#):
>
> a copy-pasteable implementation of the current entrypoint […] (copy-pasteable so that Cython and friends can copy-paste it - separately distributed is less useful here, IMHO)

Trouble is, I think Cython is better off generating both versions directly, rather than using a generic C macro that covers all the bases.  
(I do have [ideas](https://discuss.python.org/t/78873) for a more autogeneration-friendly format, but that’s for a whole different PEP.)

> [@steve.dower](#):
>
> a hard deprecation/disablement deadline for the existing API. […] let’s be noisy and actually remove the old one (at least single-phase, but ideally both it sounds like) as quickly as we can.

Deprecating only single-phase init feels off-topic for this PEP, and has [its own discussion thread](https://discuss.python.org/t/proposal-officially-deprecate-support-for-legacy-single-phase-init-extension-modules/89262).  
Deprecating the current multi-phase can’t quite begin for 5 years at the _very_ least – when the new API will be supported by non-EOL versions of Python. And after those years, any deadline we set _now_ is likely to just be discussed all over again. I guess we can set a timer now to start that discussion.  
I’d rather discuss deprecations/removals in the stable ABI in general – we obviously need to break PEP 384’s “until Python 4” promise, and that alone feels like a vat of worms.

---

<div class="post-metadata">

### Author: ![steve.dower](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/steve.dower/32/56_2.png) [@steve.dower](https://discuss.python.org/u/steve.dower)
#### Post date: [May 27, 2025, 2:32pm UTC](https://discuss.python.org/t/pep-793-pymodexport-a-new-entry-point-for-c-extension-modules/93444/9 "2025-05-27T14:32:54Z")

</div>

> [@encukou](#):
>
> I consider it out of scope here.

I think it’s in scope enough to discuss why we need three APIs - if the answer is, “we plan to not have three APIs” then that’s a good answer, but I don’t think it’s responsible to simply hope that one or two of the three will disappear. Think of it like a spending budget - free up some budget to pay for the new addition. (The budget is your time 😉 )

It’s especially relevant because the plan when we added the second API was for the first to go away. That hasn’t worked out, so there’s a higher bar for the next go at doing the same thing.

> [@encukou](#):
>
> Trouble is, I think Cython is better off generating both versions directly, rather than using a generic C macro that covers all the bases.

Did I say macro? I typed it at one point but thought I removed it while editing because I don’t think a macro can handle it. But it should be straightforward to have a function that reads the new slots and fills in a static `PyModuleDef` and returns it, without needing to customise it. I’m sure they’ll figure one out and do it themselves, but including our own that covers all bases makes the addition more palatable - something that’s clearly been an issue with the previous changes to this API.

---

<div class="post-metadata">

### Author: ![ronaldoussoren](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/ronaldoussoren/32/61_2.png) [@ronaldoussoren](https://discuss.python.org/u/ronaldoussoren)
#### Post date: [May 27, 2025, 4:33pm UTC](https://discuss.python.org/t/pep-793-pymodexport-a-new-entry-point-for-c-extension-modules/93444/10 "2025-05-27T16:33:20Z")

</div>

Have you looked into adding an API to create a `PyModuleDef` object, something like:

```c
PyModuleDef* PyModuleDef_Create(const char* name, const char* doc, /* other ModuleDef fields go here */);

```

This would fix most backward compatibility issues, although there are also disadvantages: the API would not be extensible, and there likely are memory management issues because `PyModuleDef_Init` (and hence `PyInit_*`) returns a borrowed reference (leaving no clean way to clean up the `ModuleDef` value).

---

<div class="post-metadata">

### Author: ![encukou](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/encukou/32/2461_2.png) [@encukou](https://discuss.python.org/u/encukou)
#### Post date: [May 27, 2025, 4:57pm UTC](https://discuss.python.org/t/pep-793-pymodexport-a-new-entry-point-for-c-extension-modules/93444/11 "2025-05-27T16:57:26Z")

</div>

> [@steve.dower](#):
>
> Think of it like a spending budget - free up some budget to pay for the new addition. (The budget is your time 😉 )

If it’s _my_ time, I’d rather discuss stable ABI removals in general.

> [@steve.dower](#):
>
> It should be straightforward to have a function that reads the new slots and fills in a static `PyModuleDef`

That sounds doable, thanks for the suggestion! There’ll be limitations but, yeah, they should be easy to explain. I’ll do this for the next update.

> [@ronaldoussoren](#):
>
> Have you looked into adding an API to create a `PyModuleDef` object, something like:
> 
> ```c
> PyModuleDef* PyModuleDef_Create(const char* name, const char* doc, /* other ModuleDef fields go here */);
> 
> ```
> 
> This would fix most backward compatibility issues, although there are also disadvantages: the API would not be extensible, and there likely are memory management issues because `PyModuleDef_Init` (and hence `PyInit_*`) returns a borrowed reference (leaving no clean way to clean up the `ModuleDef` value).

That function could be extensible if it took a slots array as argument.  
But you’re right about the memory management issue; also the interpreter switch issue would remain.

---

<div class="post-metadata">

### Author: ![encukou](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/encukou/32/2461_2.png) [@encukou](https://discuss.python.org/u/encukou)
#### Post date: [June 11, 2025, 12:14pm UTC](https://discuss.python.org/t/pep-793-pymodexport-a-new-entry-point-for-c-extension-modules/93444/12 "2025-06-11T12:14:40Z")

</div>

I’ve merged an [update](https://github.com/python/peps/pull/4453/files) (thanks to Hugo for proofreading):

## Soft-deprecating `PyInit_*`

The PEP soft-deprecates the old way of doing things, and to help avoid knee-jerk reactions, it takes some care to explain what soft-deprecation means ([PEP 387](https://peps.python.org/pep-0387/#soft-deprecation): “the API remains documented and tested, but will not be developed further [and] a soft deprecation does not issue a warning”).

As for planning any removals, it’s too soon to start.

## Easier migration from PyModuleDef to tokens

The PEP now specifies that `PyType_GetModuleByDef` will match a module’s _token_ – that is, it’ll be exactly equivalent to the new `PyType_GetModuleByToken` except for the signature.

An extension can use `#ifdef` to define a variable as either `PyModuleDef` or, for Python versions that don’t have that, a dummy `char` token, and the `PyType_GetModuleByDef` _calls_ will not need a `#ifdef` – they’ll just need an ugly extra cast to `void*`.

To make this fully backwards compatible, the spec disallows using an unrelated `PyModuleDef` address as a token. That would be a silly thing to do anyway.

## Backwards compatibility shim

The PEP now lists a copy-pastable `PyInit_` function that calls `PyModExport_`.  
If the PEP is accepted, I plan to add it to `pythoncapi-compat`. (Or a better home. No promises.)

---

<div class="post-metadata">

### Author: ![steve.dower](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/steve.dower/32/56_2.png) [@steve.dower](https://discuss.python.org/u/steve.dower)
#### Post date: [June 11, 2025, 3:08pm UTC](https://discuss.python.org/t/pep-793-pymodexport-a-new-entry-point-for-c-extension-modules/93444/13 "2025-06-11T15:08:20Z")

</div>

The porting guide looks great!

No other comments right now, but only because I haven’t the bandwidth to go through it closely. Trusting in others to take a good look.

---

<div class="post-metadata">

### Author: ![pitrou](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/pitrou/32/28_2.png) [@pitrou](https://discuss.python.org/u/pitrou)
#### Post date: [June 11, 2025, 7:55pm UTC](https://discuss.python.org/t/pep-793-pymodexport-a-new-entry-point-for-c-extension-modules/93444/14 "2025-06-11T19:55:37Z")

</div>

> [@](#):
>
> Type safety: `void *` is used for data pointers, function pointers and small integers, requiring casting that is technically undefined behaviour in C – but works in practice on all relevant architectures. (For example: `Py_tp_doc` marks a string; `Py_mod_gil` an integer.)

Would it work to use `intptr_t` or `uintptr_t` instead? From [what I can read](https://wiki.sei.cmu.edu/confluence/display/c/INT36-C.+Converting+a+pointer+to+integer+or+integer+to+pointer), it’s guaranteed by the C standard to correctly roundtrip pointers.

---

<div class="post-metadata">

### Author: ![h-vetinari](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/h-vetinari/32/1220_2.png) [@h-vetinari](https://discuss.python.org/u/h-vetinari)
#### Post date: [June 11, 2025, 10:47pm UTC](https://discuss.python.org/t/pep-793-pymodexport-a-new-entry-point-for-c-extension-modules/93444/15 "2025-06-11T22:47:27Z")

</div>

> [@pitrou](#):
>
> > [@](#):
> >
> > Type safety: `void *` is used for data pointers, function pointers and small integers, requiring casting that is technically undefined behaviour in C – but works in practice on all relevant architectures. (For example: `Py_tp_doc` marks a string; `Py_mod_gil` an integer.)
> 
> Would it work to use `intptr_t` or `uintptr_t` instead?

FWIW, this [recent paper](https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3556.htm) targeting C2y covers the state of the art in some depth, and essentially proposes codifying existing practice.

---

<div class="post-metadata">

### Author: ![encukou](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/encukou/32/2461_2.png) [@encukou](https://discuss.python.org/u/encukou)
#### Post date: [June 12, 2025, 6:45am UTC](https://discuss.python.org/t/pep-793-pymodexport-a-new-entry-point-for-c-extension-modules/93444/16 "2025-06-12T06:45:53Z")

</div>

> [@pitrou](#):
>
> Would it work to use `intptr_t` or `uintptr_t` instead?

This PEP explicitly sticks with the existing `PyModuleDef_Slot`.

Using `intptr_t` would mean either changing `PyModuleDef_Slot`, or making `PyModExport_*` use a new slot type.  
I’d like to do the latter, and solve a few more issues with slots too, but it’s a more controversial proposal. See [this topic](https://discuss.python.org/t/pre-pep-unified-slot-system-for-the-c-api/78873).

---

<div class="post-metadata">

### Author: ![encukou](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/encukou/32/2461_2.png) [@encukou](https://discuss.python.org/u/encukou)
#### Post date: [June 18, 2025, 11:06am UTC](https://discuss.python.org/t/pep-793-pymodexport-a-new-entry-point-for-c-extension-modules/93444/17 "2025-06-18T11:06:29Z")

</div>

Another small update I’ll make to the PEP:

> A new `PyType_GetModuleByToken` function will be added, with a signature like the existing `PyType_GetModuleByDef` but a `void *token` argument, and the same behaviour except matching tokens rather than only defs.

Turns out that `PyType_GetModuleByToken` returns a borrowed reference ([see #135666 for a docs fix](https://github.com/python/cpython/pull/135666)). That’s a no-no for new APIs, so I’ll make `PyType_GetModuleByToken` return a strong one.

Better than a `PyType_GetModuleByDefRef`, ey? :‍)

---

<div class="post-metadata">

### Author: ![encukou](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/encukou/32/2461_2.png) [@encukou](https://discuss.python.org/u/encukou)
#### Post date: [August 1, 2025, 8:54am UTC](https://discuss.python.org/t/pep-793-pymodexport-a-new-entry-point-for-c-extension-modules/93444/18 "2025-08-01T08:54:27Z")

</div>

The SC encouraged me to submit the PEP even without a C API WG recommendation, so I did: [python/steering-council#293](https://github.com/python/steering-council/issues/293)

---

<div class="post-metadata">

### Author: ![corona10](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/corona10/32/9943_2.png) [@corona10](https://discuss.python.org/u/corona10)
#### Post date: [August 21, 2025, 6:01pm UTC](https://discuss.python.org/t/pep-793-pymodexport-a-new-entry-point-for-c-extension-modules/93444/19 "2025-08-21T18:01:21Z")

</div>

The Steering Council would like the C API WG to affirm their position (even if it’s that the WG cannot reach agreement) on [PEP 793](https://peps.python.org/pep-0793/) before the September sprint in Cambridge [UK] with the goal of collectively pronouncing on it by the end of the sprint. Our preference is to delegate this decision to the WG, but we do feel a sense of urgency as this impacts the future roll out of free-threading. If _not_ this PEP, we would like to have a viable alternative, as we feel that doing _nothing_ in this area is worse.

Barring a pronouncement on PEP 793 by the WG in this time frame the SC may opt to make the decision on its own.

We realize the above WG position could also mean discussing and deciding on a direction for the future of the ABI (e.g. abi4, abi3t) for 3.15. The SC does not want to block PEP 793 on that being settled, we just recognize that if we _did_ adopt a new ABI it could wind up making PEP 793 sort of immediately obsolete or unnecessary. That outcome should not be considered a problem. Any abi4 style declaration would be its own separate PEP, and could include “we no longer need PEP 793 which hasn’t been released yet” if this happened in the same 3.15 pre-beta release time frame.

Donghee  
on behalf of the Steering Council

---

<div class="post-metadata">

### Author: ![encukou](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/encukou/32/2461_2.png) [@encukou](https://discuss.python.org/u/encukou)
#### Post date: [September 19, 2025, 11:07am UTC](https://discuss.python.org/t/pep-793-pymodexport-a-new-entry-point-for-c-extension-modules/93444/20 "2025-09-19T11:07:54Z")

</div>

The C API WG did not reach an unanimous decision. (This means that if we were _deciding_ on this, rather than giving a recommendation to the SC, the proposal would not get in.)  
4 members are for, 1 against, and 1 counts as abstaining.  
The one against – @steve.dower – agrees that the API is fine, but we should not add it _now_; it should only be added together with a new stable ABI. His key points to consider:

- this change doesn’t seem to be important enough to _force_ package developers to move to it
- this change _may_ add non-trivial burden to our own maintainers
- this change doesn’t entirely solve the key problem (compatible ABIs), and later steps _probably_ involve incompatible changes that would cause us to reevaluate how we approach this one (we have to move from `abi3` to `abi???` _anyway_, and if we do that then we would approach this API differently; and if we _don’t_ move off `abi3` then this API doesn’t provide the direct benefit it claims to)

On the maintenance burden, we asked an `import.c` maintainer, @eric.snow: He thinks the maintenance burden is small, and we’d want this API even if it didn’t help with the current free-threading ABI issues.

* * *

The WG also agreed that the _spec_ argument is unnecessary; the new hook should take no arguments.

[Next page](https://discuss.python.org/t/pep-793-pymodexport-a-new-entry-point-for-c-extension-modules/93444.md?page=2)
