Skip to content
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

gh-113666: Adding missing UF_ and SF_ flags to module 'stat' #113667

Open
wants to merge 15 commits into
base: main
Choose a base branch
from

Conversation

ronaldoussoren
Copy link
Contributor

@ronaldoussoren ronaldoussoren commented Jan 2, 2024

Add some constants to module 'stat' that are used on macOS.


📚 Documentation preview 📚: https://cpython-previews--113667.org.readthedocs.build/

Add some constants to module 'stat' that are used on macOS.
@ronaldoussoren
Copy link
Contributor Author

There will be an update to this PR, just noticed that there's also a C extension with a definitions.

Lib/stat.py Outdated Show resolved Hide resolved
Lib/stat.py Outdated Show resolved Hide resolved
Lib/stat.py Outdated Show resolved Hide resolved
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
@ronaldoussoren
Copy link
Contributor Author

Something I noticed while looking at stat.py & _stat.c is that the two contain a lot of the same definitions.

IMHO it would be better to strip duplicates (DRY and all), and possibly just drop stat.py (e.g. rename the _stat extension module to stat).

I also don't particularly like defining names that aren't relevant for the current platform (for example S_IFDOOR which AFAIK is only relevant for Solaris). Changing that is something for a different PR though, this would change the interface for stat and requires the usual deprecation cycle before removing.

@ronaldoussoren
Copy link
Contributor Author

I've updated the PR:

  • Fixed typos noted by @serhiy-storchaka
  • Added the new constants to _stat.c as well
  • Added a test case that tests the values on macOS (this is a bit overkill, but makes it easier to validate the changes)

I still don't like having the definitions in two places and exporting definitions not relevant for the current platform (e.g. S_IFDOOR on anything that isn't Solaris), I'll file a separate issue about those.


.. versionadded: 3.13

.. data:: UF_SETTABLE
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.. data:: UF_SETTABLE
.. data:: SF_SETTABLE

@serhiy-storchaka
Copy link
Member

I thought about adding some general tests, like testing that UF_SETTABLE, SF_SETTABLE and SF_SYNTHETIC do not intersect, SF_SUPPORTED is a subset of SF_SETTABLE, all UF_* flags are in UF_SETTABLE, and all SF_* flags are in SF_SETTABLE or SF_SYNTHETIC, etc. But your tests are more strict.

I searched for SF_SETTABLE and found it in the xnu sources (https://opensource.apple.com/source/xnu/xnu-2050.18.24/bsd/sys/stat.h), where it's definition is different. Also, there are no SF_SUPPORTED and SF_SYNTHETIC there. Does it matter?

Some flags are defined in stat.py and _stat.c because we want to provide some values even if the platform do not support them. But values from _stat.c override default values in stat.py. If meta-flags are only provided on macOS, I think that there is no need to define default values for them in stat.py.

@ronaldoussoren
Copy link
Contributor Author

I thought about adding some general tests, like testing that UF_SETTABLE, SF_SETTABLE and SF_SYNTHETIC do not intersect, SF_SUPPORTED is a subset of SF_SETTABLE, all UF_* flags are in UF_SETTABLE, and all SF_* flags are in SF_SETTABLE or SF_SYNTHETIC, etc. But your tests are more strict.

My tests are basically written by copying the #define-s from Apple headers (macOS 14.2 SDK) and transforming those to test assertions.

I searched for SF_SETTABLE and found it in the xnu sources (https://opensource.apple.com/source/xnu/xnu-2050.18.24/bsd/sys/stat.h), where it's definition is different. Also, there are no SF_SUPPORTED and SF_SYNTHETIC there. Does it matter?

Those definitions are old, I'm not entirely sure when SF_SYNTHETIC was introduced, but likely when the APFS filesystem was added (10.13), or when they added the system volume and firm links (10.15)

See https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/sys/stat.h.auto.html for a more recent copy.

The difference between the older and newer versions shouldn't be a problem, all bits that are set in the older SF_SETTABLE but not in the newer have no assigned meaning in the older release.

Some flags are defined in stat.py and _stat.c because we want to provide some values even if the platform do not support them. But values from _stat.c override default values in stat.py. If meta-flags are only provided on macOS, I think that there is no need to define default values for them in stat.py.

I'll do some more research, google seems to indicate that SF_SETTABLE and SU_SETTABLE are available in at least glibc as well (with the older definition you found), in which case:

  • Add SU_SETTABLE and SF_SETTABLE to stat.py with the Linux definition, and remove the "if darwin" block
  • Add SF_SUPPORTED and SF_SYNTHETIC only in stat.c (and override SF_SETTABLE there for macOS by way of using the system definition).

1. SF_SETTABLE and UF_SETTABLE are available on BSD as well

   Add generic definitions to stat.py and fallback defines to
   _stat.c (the latter matching how we handle other generic flags)

2. Older versions of macOS do not have SF_SUPPORTED and SF_SYNTHETIC

   _stat.c defines those for all macOS platforms, and redefines
   SF_SETTABLE to match recent macOS versions.

   I did this primarily to end up with an explainable situation: our
   installers are build on recent versions of macOS and can be used
   on older versions.

   The implementation in this changeset ensures we end up with the same
   definitions regardless of how the binary was build (old SDK or new SDK
   and old deployment target)
@ronaldoussoren
Copy link
Contributor Author

I didn't find UF_SETTABLE and SF_SETTABLE on Linux, but did find them on FreeBSD. The PR therefore handles them like other generic flags (always available).

A slight complication: As you noticed older versions of macOS have a definition of SF_SETTABLE that doesn't match the definition in the current SDK, and "older" includes at least macOS 10.9 which is the oldest version of the OS targeted by our installers.

To end up with an interface that's easily explainable I've chooses to redefine SF_SETTABLE on those older macOS versions, and define SF_SUPPORTED and SF_SYNTHETIC there as well. That way we can describe those as being available on macOS, without having to explain that availability and values depend on how the installation was build (old SDK vs. new SDK). This should affect usage of these attributes because the extra bits set in the older definition of SF_SETTABLE do not have a defined meaning on those older releases of macOS.

Lib/test/test_stat.py Outdated Show resolved Hide resolved
@@ -579,6 +604,7 @@ stat_exec(PyObject *module)
ADD_INT_MACRO(module, UF_TRACKED);
ADD_INT_MACRO(module, UF_DATAVAULT);
ADD_INT_MACRO(module, UF_HIDDEN);
ADD_INT_MACRO(module, SF_SETTABLE);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#ifdef SF_SETTABLE

Modules/_stat.c Outdated Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants