Skip to content

Comments

chore: add more __all__/__dir__#1069

Merged
henryiii merged 1 commit intopypa:mainfrom
henryiii:henryiii/chore/alls
Jan 24, 2026
Merged

chore: add more __all__/__dir__#1069
henryiii merged 1 commit intopypa:mainfrom
henryiii:henryiii/chore/alls

Conversation

@henryiii
Copy link
Contributor

@henryiii henryiii commented Jan 23, 2026

Followup to #1011, filling out more all/dir.

I was going to do this one at a time, but quite a few already had __all__, so I did it all at once. Here's the script I used to help:

import argparse
import ast
from pathlib import Path


def generate_all_from_ast(path: Path) -> list[str]:
    tree = ast.parse(path.read_text())
    names: set[str] = set()

    for node in tree.body:
        match node:
            # def foo(...) or class Foo:
            case (
                ast.FunctionDef(name=name)
                | ast.AsyncFunctionDef(name=name)
                | ast.ClassDef(name=name)
            ) if not name.startswith("_"):
                names.add(name)

            # x = ...
            case ast.Assign(targets=targets) | ast.AnnAssign(targets=targets):
                for target in targets:
                    match target:
                        case ast.Name(id=name) if not name.startswith("_"):
                            names.add(name)
            case (
                ast.Assign(target=ast.Name(id=name))
                | ast.AnnAssign(target=ast.Name(id=name))
            ) if not name.startswith("_"):
                names.add(name)

            # from module import a, b as c
            case ast.ImportFrom(module=_, level=0, names=imported):
                for entry in imported:
                    match entry:
                        case ast.alias(name=name, asname=asname) if (
                            asname is not None and not asname.startswith("_")
                        ):
                            names.add(asname)

            # Ignore everything else
            case _:
                pass

    return sorted(names)


def main() -> None:
    parser = argparse.ArgumentParser(
        description="Generate a __all__ list for a Python source file"
    )
    parser.add_argument(
        "file",
        type=Path,
        help="Python source file to analyze",
    )
    args = parser.parse_args()

    names = generate_all_from_ast(args.file)

    print("__all__ = [")
    for name in names:
        print(f'    "{name}",')
    print("]")


if __name__ == "__main__":
    main()

Signed-off-by: Henry Schreiner <henryfs@princeton.edu>
@henryiii henryiii force-pushed the henryiii/chore/alls branch from eeb0261 to 37d38bd Compare January 23, 2026 16:47
@@ -1,6 +1,5 @@
from __future__ import annotations

import email.feedparser
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was noticed by pylance, not a directly related change, though.

@henryiii henryiii merged commit 8c6aab9 into pypa:main Jan 24, 2026
44 checks passed
@henryiii henryiii deleted the henryiii/chore/alls branch January 24, 2026 02:56
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.

3 participants