Skip to content

[3.13] gh-131507: Add a way to recreate the Misc/mypy symlinks if missing (GH-132274) #132293

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

Merged
merged 1 commit into from
Apr 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/mypy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,5 @@ jobs:
cache: pip
cache-dependency-path: Tools/requirements-dev.txt
- run: pip install -r Tools/requirements-dev.txt
- run: python3 Misc/mypy/make_symlinks.py --symlink
- run: mypy --config-file ${{ matrix.target }}/mypy.ini
12 changes: 10 additions & 2 deletions Misc/mypy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,21 @@ This directory stores symlinks to standard library modules and packages
that are fully type-annotated and ready to be used in type checking of
the rest of the stdlib or Tools/ and so on.

## Why this is necessary
Due to most of the standard library being untyped, we prefer not to
point mypy directly at `Lib/` for type checking. Additionally, mypy
as a tool does not support shadowing typing-related standard libraries
like `types`, `typing`, and `collections.abc`.

So instead, we set `mypy_path` to include this directory,
which only links modules and packages we know are safe to be
type-checked themselves and used as dependencies.
type-checked themselves and used as dependencies. See
`Lib/_pyrepl/mypy.ini` for a usage example.

See `Lib/_pyrepl/mypy.ini` for an example.
## I want to add a new type-checked module
Add it to `typed-stdlib.txt` and run `make_symlinks.py --symlink`.

## I don't see any symlinks in this directory
The symlinks in this directory are skipped in source tarballs
in Python releases. This ensures they don't end up in the SBOM. To
recreate them, run the `make_symlinks.py --symlink` script.
60 changes: 60 additions & 0 deletions Misc/mypy/make_symlinks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#!/usr/bin/env python3
from __future__ import annotations

import argparse
import os
from pathlib import Path

CURRENT_DIR = Path(__file__).parent
MISC_DIR = CURRENT_DIR.parent
REPO_ROOT = MISC_DIR.parent
LIB_DIR = REPO_ROOT / "Lib"
FILE_LIST = CURRENT_DIR / "typed-stdlib.txt"

parser = argparse.ArgumentParser(prog="make_symlinks.py")
parser.add_argument(
"--symlink",
action="store_true",
help="Create symlinks",
)
parser.add_argument(
"--clean",
action="store_true",
help="Delete any pre-existing symlinks",
)

args = parser.parse_args()

if args.clean:
for entry in CURRENT_DIR.glob("*"):
if entry.is_symlink():
entry_at_root = entry.relative_to(REPO_ROOT)
print(f"removing pre-existing {entry_at_root}")
entry.unlink()

for link in FILE_LIST.read_text().splitlines():
link = link.strip()
if not link or link.startswith('#'):
continue

src = LIB_DIR / link
dst = CURRENT_DIR / link
src_at_root = src.relative_to(REPO_ROOT)
dst_at_root = dst.relative_to(REPO_ROOT)
if (
dst.is_symlink()
and src.resolve(strict=True) == dst.resolve(strict=True)
):
continue

if not args.symlink and args.clean:
# when the user called --clean without --symlink, don't report missing
# symlinks that we just deleted ourselves
continue

# we specifically want to create relative-path links with ..
src_rel = os.path.relpath(src, CURRENT_DIR)
action = "symlinking" if args.symlink else "missing symlink to"
print(f"{action} {src_at_root} at {dst_at_root}")
if args.symlink:
os.symlink(src_rel, dst)
4 changes: 4 additions & 0 deletions Misc/mypy/typed-stdlib.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# These libraries in the stdlib can be type-checked.

_colorize.py
_pyrepl
Loading