PEP 741: Python Configuration C API (second version)

I know it’s your PEP, but this isn’t what 587 says (emphasis mine):

It becomes possible to read the configuration and then override some computed parameters before it is applied.

In practice, we’ve never applied PEP 587 in a way to make it the way to read the current configuration, only to read the intended configuration before applying it. And even that makes certain things difficult/impossible, so it’s best wound back (which is what 741 is doing, so +1 to the new PEP).

The current configuration should be accessible through sys.*/PySys_*. We’ll get there eventually, but I don’t think that’s essential as long as there’s some way right now (e.g. from site or importlib etc.)

The PEP 587 intent was to allow reading the current configuration with PyConfig_Read(), let the user modify it, and then apply the configuration with Py_InitializeFromConfig().

In practice, there are corner cases like sys.path which changed a lot in recent Python versions. Also, some users want to modify Python configuration after the initialization phase: in Python, not in C.

Maybe we’re disagreeing on the definition of “current”.

To me, prior to initialization, there is no “current” config. There are a bunch of environment settings and arguments that might influence the config, but that only affects what is in a struct owned by the host application (i.e. python.c).

After you initialize, now there is a “current” config, but PyConfig_Read() won’t read it, and never would. At best, it would avoid recalculating parts of it. You always had to look at the sys module for the current config.

Yeah, this is fine. We just need to make sure that anywhere we read the config (that is allowed to change) that we’re reading it from the place where it may have been modified (e.g. sys.path is a perfect example of this).

1 Like

Right, PEP 741 does that. PyConfig_Get() and PyConfig_Set() have a different design (than PEP 587).

@vstinner - I’m completing my final review of PEP 741 for SC pronouncement. I was on vacation for two weeks, but am now back at work, so promised my fellow SC members that I’d do one more read-through.

I’ve now done that and have one question. From the abstract:

This new API replaces the deprecated and incomplete legacy API which is scheduled for removal between Python 3.13 and Python 3.15.

It’s not clear to me whether this sentence needs updating, given that the PEP is targeted at 3.14 now (thus shifting the mentioned deprecation schedule forward), or if the mentioned deprecations are already in progress and PEP 741 doesn’t affect some previously set-in-motion schedule.

Could you please clarify here, and in the PEP? For the PEP clarification, if these are already in progress deprecations, can you please link to where they are defined in the code or elsewhere?

Thanks!

1 Like

Oh, this sentence is just outdated: I just removed it. Previously, the PEP had a whole section about deprecations, it’s no longer the case. I prefer to not link PEP 741 to the scheduled deprecations and removals.

2 Likes

Thank you @vstinner !

On behalf of the Steering Council, I’m happy to say that we have Accepted PEP 741. Thank you and congratulations @vstinner! You know what to do next. :smile:

7 Likes

Thanks! I merged the implementation and set the PEP Status to Final.

You can now modify sys.flags with the test API. Example enablng bytes warning at runtime:

$ ./python
>>> b'bytes' == 'unicode'
False

>>> # call PyConfig_Set("bytes_warning", 1)
>>> import _testcapi; _testcapi.config_set('bytes_warning', 1)

>>> b'bytes' == 'unicode'
<python-input-2>:1: BytesWarning: Comparison between bytes and string
  b'bytes' == 'unicode'
False

You can now also inspect (deep secret!) internals such as the hash seed with the test API:

$ PYTHONHASHSEED=123 ./python
>>> # call PyConfig_Get("hash_seed")
>>> import _testcapi; _testcapi.config_get('hash_seed')
123

The options list is documented at: PEP 741 - Configuration Options.

4 Likes