“Often” is quite an overstatement. Among the existing system utilities, only the following are independent of the Python runtime: PyOS_getsig, PyOS_setsig (with a doc that warns "Do not call those functions directly!"), Py_DecodeLocale (again, “This function should not be called directly”…) and Py_EncodeLocale. To this we should add the PyTime utility functions.
And it seems that’s all there is, unless I’m missing something.
I believe that the warning refers to the underlying C functions, not the wrappers.
@skirpichev pointed to the other instances we currently have.
And we have more, but those are not exposed directly in the Python C API, e.g. the functions to get the current time or access to performance counters in the time module across various platforms.
Perhaps “often” is the wrong word.
What I wanted to say is that the approach to provide low level C APIs for things that are hard to get right across platforms and compilers is a common theme in CPython.
If we’ve already done all the hard work, why not let the C extension writers benefit as well ?
Supporting something as public API is additional work, and a significant part of it has not been done yet.
In this case, it’s because if C compilers[1] eventually also do the work, we’ll be stuck with a duplicate API that we can’t remove.
If we[2] want to commit to providing pure-C API for complex numbers, then I think it should be published separately, and vendored in CPython, like we now handle HACL* or mimalloc. That way it can be useful to any C programmer, not just Python extension writers. (And if/when it’s no longer useful, we* can rip it out and give it a new home.)
There’s an implicit assumption here that a bigger audience is worth extra work. That might very well be true – but it’s a question for the person who’ll be doing that work. And, unfortunately, for the person who’ll pick things up if the first one burns out and leaves.
I might add that when PyOS_snprintf was added, Python was made by the first kind of people. Now, people like me were hired to be the second kind.
This is is sad, and worthy of nostalgia.
Smaller (third-party) projects are way more fun.
Why not ? We apply the usual deprecation phase and then remove it.
And like you mentioned: it is possible to then extract those APIs into a separate library on Github/Gitlab, if needed, and can then be maintained by those who do need it as a separate project.
Specifically for complex numbers, it seems that “only” MSVC benefits from the ones we have in CPython. That’s still a significant audience… From @h-vetinari’s comment, it seems that it should be possible to use MSVC APIs to implement the ones we have in CPython, but I’m not sure whether it’s worth the trouble, since we’d still need to keep those wrappers around too.
Normally we’re worried about removing private APIs because they’re widely used, and yet today we’ve got private APIs that are barely used at all and we’re considering making them public, stable, and adding more? Make it make sense!
Is there a genuine, broad demand for native complex arithmetic? MSVC team is pretty good at tracking these kinds of needs among the people who pay for MSVC, and apparently it’s never been needed.[1] Have we heard people asking for it, or perhaps a better question, have we heard people complaining about the complexity involved in converting Python’s complex numbers into an alternate format for optimised calculations?[2]
I sure haven’t, so proposing to dramatically increase our API surface to satisfy apparently non-existent users sounds very strange, and a poor allocation of our resources.
The original proposal was fine for me. We’re now getting deep into scope creep for no apparent reason.
Though MSVC is also very good at progressively introducing C++, so they may just have all been satisfied by switching mode and introducing a class that handles it. ↩︎
As we heard for arbitrary length integers, for example. ↩︎
That’s a tad facetious methinks. Taking absence of engagement in shouting into the void[1] as evidence that no-one wants this feature (and just hasn’t given up on MSVC for this feature completely) is a very large stretch, even adjusting for some understandable “this product comes from my company” sentiment.
The thing that’s incomprehensible to me is that MSVC built the entire complex API, but apparently cannot be bothered to finish the final stretch of this feature that’s been standardized for 25 years by providing the proper types. Two[2] more reasons why all but the most obstinate people have stopped giving feedback to the MSVC team about it.
And the important extension of this is that if they’re asking us, we might be justified in adding it to our public API. If they’re asking Microsoft, then there might be value in a standalone library that provides the APIs which we could then vendor (which I’m totally on board with).
Taking Microsoft’s gap and forcing Petr to cover it by adding the library to the project he’s paid to maintain is a big jump. Let’s be confident that it’s the only reasonable way forward before making him own it
That’s a strange way to approach the question. CPython is a big user of those APIs and so we have to maintain them anyway, regardless of whether there are extensions using them or not.
Arguing that the APIs are not used much in extensions is also a strange approach. After all, the APIs are private APIs at the moment.
Since we have, in this discussion, now identified a fairly large potential use case for the APIs, namely all extensions which want to provide this functionality on MSVC, why not simply remove the underscores and continue maintaining them as we have in the past ?
That’s going to be a lot less work, than moving them to an external library, which we then have to vendor in again.
If, at some point, MSVC does provide proper support, we can then deprecate and remove them (see above).
Because it affects how we maintain them into the future, whereas leaving them as they are now doesn’t.
Like all the other private APIs, if we find that they’re being used widely, we can make them public then. If MSVC gets support, then we can quietly drop our internal ones.
Why the urgency to start guaranteeing APIs that haven’t been asked for and aren’t being used, even though they are already there?
As I mentioned already, this API uses the current internal layout of Python complex numbers, Py_Complex, so if we stop using Py_Complex internally, we’ll be stuck maintaining a bunch of functions that convert from Py_Complex, do the internal operation, and convert back.
And that’s not just a theoretical possibility – I would like to start the deprecation period for the internal implementation (PyComplexObject.cval) now, in 3.15, and switch as soon as that’s over.
It’s certainly not common for extension modules to make use of complex numbers, and those that do are probably specialized enough that their authors don’t need help from the CPython C API.