fix: accept app arguments in user_preference_dir - #531
Merged
gaborbernat merged 3 commits intoAug 27, 2026
Merged
Conversation
user_preference_dir() and user_preference_path() took no arguments, so they always returned the unscoped base directory. The property they wrap is app scoped on every platform: macOS appends the app name and version to ~/Library/Preferences, and Unix, Windows and Android resolve it to user_config_dir. PR tox-dev#491 added these two helpers in the same batch as user_publicshare_dir, user_templates_dir and user_fonts_dir, which are app independent, and the zero argument shape carried over to the one member of the batch that is not. Give both functions the signature of user_config_dir, the property they resolve to on three of the four platforms. The defaults are unchanged, so calling either with no arguments returns what it returns today. The new test asserts the general invariant over every directory getter: when the property varies with appname and version, the module level function has to accept them. It fails only for user_preference_dir before this change.
The original conditional asserted nothing for the 26 properties that do not vary with the app name, and where it did fire it only checked that appname and version appear in the signature, not that the function passes them on. A wrapper accepting both and calling PlatformDirs() anyway still passed. Assert the implication with both branches carrying a claim: a function taking the app arguments must return what the scoped property returns, and one that does not must wrap a property that never varies. Only one direction holds, since tox-dev#534 gives the applications functions arguments that three of the four platforms ignore. Pass them by keyword, because multipath stays first positional on the site functions.
gaborbernat
force-pushed
the
fix/user-preference-dir-app-args
branch
from
August 27, 2026 20:13
37eda96 to
1b1a5ce
Compare
gaborbernat
marked this pull request as ready for review
August 27, 2026 20:19
The FBT suppressions were only needed because the booleans were positional, which is the thing the rule objects to. Both functions took no arguments before this branch, so nothing can be passing them positionally and a bare * costs nothing. That drops seven of the eight suppressions per function. The remaining too-many-arguments is honest: six options are six options, and every one of them reaches user_preference_dir through user_config_dir on Unix, Windows and Android.
gaborbernat
approved these changes
Aug 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Differential check of the 54 module-level
*_dir/*_pathfunctions against thePlatformDirsproperties they wrap: 0 value divergences in 12,960 comparisons, and 8 reach gaps. All 8 areuser_preference_diranduser_preference_path.Neither takes arguments, so neither can pass the app name or the version that the property acts on:
macOS appends the app name and version to
~/Library/Preferences. On the other three platformsuser_preference_dirresolves touser_config_dir, which is app scoped as well. Either way the function can only return the unscoped base directory.#491 added these two in one batch with app independent helpers such as
user_fonts_dir, and the zero argument shape carried over to the one member of the batch it does not suit.This gives both the signature of
user_config_dir. Defaults are unchanged, so a no-argument call returns what it returns today.The test asserts the invariant over every getter in
PROPS: where the property varies withappnameandversion, the function must accept them. Reverting__init__.pyfails it foruser_preference_diralone; the other 26 parametrizations pass either way, as pins.Testing: full suite on macOS with 3.14, 1032 passed. The four
test_compatibility[site_data_dir-*]failures reproduce on a cleanorigin/mainworktree. Pinned ruff v0.16.4 is clean. Windows and Linux legs unrun here.Drafted with Claude Code (Claude Opus 5). Not yet reviewed by a human; @dylanpulver will review before this is treated as ready.