Skip to content

Conversation

@henryiii
Copy link
Contributor

@henryiii henryiii commented Dec 9, 2025

This adds __all__ and __dir__ to the tags module. This exports just the public names; type checkers respect __all__, REPL tab completion respects __dir__. It does not stop someone from using an unexported name at runtime. This is much better than trying to use underscores on things like standard imports or deleting things, and it also works for re-exporting. See https://learn.scientific-python.org/development/patterns/exports for details.

Before:

>>> import packaging.tags
>>> dir(packaging.tags)
['Any', 'AppleVersion', 'EXTENSION_SUFFIXES', 'INTERPRETER_SHORT_NAMES', 'Iterable',
 'Iterator', 'PythonVersion', 'Sequence', 'Tag', 'Tuple', '_32_BIT_INTERPRETER',
 '__all__', '__annotations__', '__builtins__', '__cached__', '__conditional_annotations__',
 '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__',
 '_abi3_applies', '_cpython_abis', '_generic_abi', '_generic_platforms',
 '_get_config_var', '_is_threaded_cpython', '_linux_platforms', '_mac_arch',
 '_mac_binary_formats', '_manylinux', '_musllinux', '_normalize_string',
 '_py_interpreter_range', '_version_nodot', 'android_platforms', 'annotations',
 'cast', 'compatible_tags', 'cpython_tags', 'generic_tags', 'interpreter_name',
 'interpreter_version', 'ios_platforms', 'logger', 'logging', 'mac_platforms',
 'parse_tag', 'platform', 'platform_tags', 're', 'struct', 'subprocess', 'sys',
 'sys_tags', 'sysconfig']

After:

>>> import packaging.tags
>>> dir(packaging.tags)
['AppleVersion', 'INTERPRETER_SHORT_NAMES', 'PythonVersion', 'Tag', 'compatible_tags',
 'cpython_tags', 'generic_tags', 'interpreter_name', 'interpreter_version', 'parse_tag',
 'platform_tags', 'sys_tags']

I've skipped exporting mac_platforms, ios_platform, and android_platforms, because _linux_platforms is hidden, but maybe those are public? Ah, nevermind, I do see them in the documentation. Interesting, I'll add them. I could list _linux_platforms here too if we want to, but it's not documented.

If this looks good, I'll work on the other modules.

@henryiii henryiii force-pushed the henryiii/chore/tags_all branch 2 times, most recently from d78fbc3 to 9a27e01 Compare December 9, 2025 04:04
@brettcannon
Copy link
Member

tab completion respects __dir__.

Tab completion by whom?

@henryiii
Copy link
Contributor Author

henryiii commented Dec 9, 2025

Python's old and new REPL and IPython's REPL (at least), are based on dir(item). I think static tab completion, like in VSCode, respects __all__. Edit: no, it doesn't seem to.

@henryiii
Copy link
Contributor Author

henryiii commented Dec 9, 2025

New REPL:

Screenshot 2025-12-09 at 2 31 38 PM

(Looks like I forgot to update Python to 3.14.2, embarrassing!)

Old REPL:

Screenshot 2025-12-09 at 2 32 41 PM

(No color now looks so sad)

IPython:

Screenshot 2025-12-09 at 2 33 31 PM

Looks like vscode does not respect __all__, it's still showing me other stuff like Any. But it's not worse, at least. :) And mypy does respect __all__.

Signed-off-by: Henry Schreiner <henryfs@princeton.edu>
Signed-off-by: Henry Schreiner <henryfs@princeton.edu>
@henryiii henryiii force-pushed the henryiii/chore/tags_all branch from 9a27e01 to 496e3ba Compare December 9, 2025 19:40
@henryiii henryiii changed the title chore(tags): limit dir / tab-completion chore(tags): limit dir / tab-completion in REPL Dec 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants