-
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
Py_PACK_VERSION #47
Comments
Is it really useful to add Py_PACK_FULL_VERSION(x, y, z, level, serial)? What's the use case?
Cython can use its own macro. |
I see it more as fully defining our version field. We shouldn't make other people replicate our logic for that if we're going to provide any level of support - I'd argue that |
I support adding the macros, but I am against adding functions. The main use of such macros is in preprocessor: #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= Py_PACK_FULL_VERSION(3, 14, 0, 0xA, 1)
And it only works if they are macros. Wrappers for non-C languages should implement them as native functions. This is not more difficult than create a wrapper. |
Right, but C code is never going to get the function, they'll always get the macro. They can be exported for GetProcAddress and (I assume) dlsym purposes without being in the header files. It's not trivial for non-C languages to write a function that wraps the macros. That involves adding a C compiler or copy-pasting the logic. |
def Py_PACK_FULL_VERSION(x, y, z, level, serial):
return (x << 24) | (y << 16) | (z << 8) | (level << 4) | (serial << 0) I am sure that it is easy to write in any language. |
Sure, but it's not easy to infer without being given that information. So either we present it in the docs as "here's how to do this yourself", or we can simply provide a function that does the same job as the macro (which we've agreed elsewhere is a good policy to have for stability). (There are probably also languages where it's not easy - very strictly typed languages may not let you shift a byte outside of its range without explicit casts/conversions - but this is very much speculative and besides the point.) |
It is already represented in details in the documentation for If add function, we should discuss them in details. What types of parameters -- I do not believe that functions are needed. Macros will be helpful. If authors of wrappers for non-C languages ask us to add functions, then we can add functions that satisfy their needs. |
I would prefer to only provide macros. I don't think that it's useful to add functions here. |
This goes in the limited API, where, IMO, we should add function equivalents to macros whenever it's possible. There's no pressing reason to omit the functions here.
That's only true if you're writing the wrapper by hand. If you're generating wrappers from headers (which some projects do, and which I'd like to make easier), functions should make it much easier. As for I'd rather add masking (which is no-op in the primary use case of using a macros on literals): def Py_PACK_FULL_VERSION(x, y, z, level, serial):
return (
(x & 0xff) << 24)
| ((y & 0xff) << 16)
| ((z & 0xff) << 8)
| ((level & 0x0f) << 4)
| ((serial & 0x0f) << 0)
) Thanks for asking about the signatures. My proposal is to match the inputs' domains, except
Out-of range |
Might as well just go |
OK, let's go with |
If you don't want uint8_t, I would prefer |
Let's split the voting separately for macros and functions. There is a global variable |
If we did that, I couldn't express my preference to add both at the same time (following a general guideline discussed in capi-workgroup/api-evolution#18).
New API should use the fixed-width types, per discussion here.
IMO, functions and function-like macros that do the same thing should have the same name. |
Why? |
Using Example:
Warning when using
|
There's a level of "someone doesn't know how to use the API" that we can't help any further. On one hard, we have the argument that everyone should use the macro (which can't really handle error checking like this). On the other, we have the argument that the function version should have excessive amounts of error checking. This is a simple enough API that I think we can allow garbage-in-garbage-out. No need to overthink it. |
Coincidentally: with masking, -1 is a convenient way to spell “maximum”. |
The draft guidelines
Of course, we can grant an exception if circumstances require it, and we can of course change those guidelines -- they are new and untested. @serhiy-storchaka, do you think we should do one of those? If not: I see no strong reason to omit adding the functions as library symbols. |
@serhiy-storchaka, do you still want to block the proposal to add the functions? |
Please vote for adding macros/functions for easier version handling, as discussed on Discourse:
Py_PACK_FULL_VERSION(x, y, z, level, serial)
packs a version number from componentsinto the format used by
Py_VERSION_HEX
andPy_LIMITED_API
.For example,
Py_PACK_FULL_VERSION(3, 14, 0, 0xA, 1)
evaluates to 0x030E00A1.Py_PACK_VERSION(x, y)
is shorthand forPy_PACK_FULL_VERSION(x, y, 0, 0, 0)
,useful because the first two version components often determine ABI
compatibility.
These are primarily macros, but we will export library functions with the same names and functionality, for use in wrappers for non-C languages – for example, Python with
ctypes
.(The macro-style naming means that we do encourage “serious” wrappers to implement them as compile-time constructs, rather than library calls.)
These should go in the limited API.
See the discussion thread for other considered ideas:
Py_PACK_FULL_VERSION
(it's useful to explain this in docs, and sometimes in projects like Cython)Py_VERSION_GE(x, y, z)
&Py_VERSION_LE(x, y, z)
that would directly comparePy_VERSION_HEX
to a given version (but do nothing forPy_LIMITED_API
or the macro proposed in PEP 743)The text was updated successfully, but these errors were encountered: