Skip to content

Commit

Permalink
tests / scripts: blacken and isort (python#4704)
Browse files Browse the repository at this point in the history
I often run black and isort in typeshed root and then have to undo these
changes.

Co-authored-by: hauntsaninja <>
  • Loading branch information
hauntsaninja authored Oct 25, 2020
1 parent 2f13673 commit 48970d3
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 113 deletions.
1 change: 1 addition & 0 deletions .flake8
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

[flake8]
per-file-ignores =
*.py: E203, W503
*.pyi: E301, E302, E305, E501, E701, E741, F401, F403, F405, F822
# Since typing.pyi defines "overload" this is not recognized by flake8 as typing.overload.
# Unfortunately, flake8 does not allow to "noqa" just a specific error inside the file itself.
Expand Down
44 changes: 19 additions & 25 deletions scripts/migrate_script.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@
import os
import os.path
import shutil

from dataclasses import dataclass
from typing import Optional, List, Set, Tuple
from typing import List, Optional, Set, Tuple

# These names may be still discussed so I make them constants.
STDLIB_NAMESPACE = "stdlib"
Expand Down Expand Up @@ -62,6 +61,7 @@
# The latter two are distinguished by is_dir flag.
class PackageBase:
"""Common attributes for packages/modules"""

path: str # full initial path like stdlib/2and3/argparse.pyi
is_dir: bool

Expand All @@ -79,6 +79,7 @@ def name(self) -> str:
@dataclass
class StdLibPackage(PackageBase):
"""Package/module in standard library."""

path: str
py_version: Optional[str] # Can be omitted for Python 2 only packages.
is_dir: bool
Expand All @@ -93,8 +94,7 @@ class ThirdPartyPackage(PackageBase):
requires: List[str] # distributions this depends on


def add_stdlib_packages_from(subdir: str, packages: List[StdLibPackage],
py_version: Optional[str]) -> None:
def add_stdlib_packages_from(subdir: str, packages: List[StdLibPackage], py_version: Optional[str]) -> None:
"""Add standard library packages/modules from a given stdlib/xxx subdirectory.
Append to packages list in-place, use py_version as the minimal supported version.
Expand All @@ -120,30 +120,27 @@ def collect_stdlib_packages() -> Tuple[List[StdLibPackage], List[StdLibPackage]]
return stdlib, py2_stdlib


def add_third_party_packages_from(subdir: str, packages: List[ThirdPartyPackage],
py2_compatible: bool, py3_compatible: bool) -> None:
def add_third_party_packages_from(
subdir: str, packages: List[ThirdPartyPackage], py2_compatible: bool, py3_compatible: bool
) -> None:
"""Add third party packages/modules from a given third_party/xxx subdirectory."""
for name in os.listdir(subdir):
path = os.path.join(subdir, name)
packages.append(ThirdPartyPackage(path, py2_compatible, py3_compatible,
requires=[], is_dir=os.path.isdir(path)))
packages.append(ThirdPartyPackage(path, py2_compatible, py3_compatible, requires=[], is_dir=os.path.isdir(path)))


def collect_third_party_packages() -> Tuple[List[ThirdPartyPackage], List[ThirdPartyPackage]]:
"""Collect third party packages/modules from all current third_party/xxx sub-directories."""
third_party: List[ThirdPartyPackage] = []
py2_third_party: List[ThirdPartyPackage] = []
add_third_party_packages_from("third_party/3", third_party,
py2_compatible=False, py3_compatible=True)
add_third_party_packages_from("third_party/2and3", third_party,
py2_compatible=True, py3_compatible=True)
add_third_party_packages_from("third_party/3", third_party, py2_compatible=False, py3_compatible=True)
add_third_party_packages_from("third_party/2and3", third_party, py2_compatible=True, py3_compatible=True)
# We special-case Python 2 for third party packages like six.
subdir = "third_party/2"
py3_packages = os.listdir("third_party/3")
for name in os.listdir(subdir):
path = os.path.join(subdir, name)
package = ThirdPartyPackage(path, py2_compatible=True, py3_compatible=False,
requires=[], is_dir=os.path.isdir(path))
package = ThirdPartyPackage(path, py2_compatible=True, py3_compatible=False, requires=[], is_dir=os.path.isdir(path))
if name in py3_packages:
# If there is a package with the same name in /2 and /3, we add the former to
# a separate list, packages from there will be put into /python2 sub-directories.
Expand All @@ -168,19 +165,19 @@ def get_top_imported_names(file: str) -> Set[str]:
for node in ast.walk(parsed):
if isinstance(node, ast.Import):
for name in node.names:
top_imported.add(name.name.split('.')[0])
top_imported.add(name.name.split(".")[0])
elif isinstance(node, ast.ImportFrom):
if node.level > 0:
# Relative imports always refer to the current package.
continue
assert node.module
top_imported.add(node.module.split('.')[0])
top_imported.add(node.module.split(".")[0])
return top_imported


def populate_requirements(package: ThirdPartyPackage,
stdlib: List[str], py2_stdlib: List[str],
known_distributions: Set[str]) -> None:
def populate_requirements(
package: ThirdPartyPackage, stdlib: List[str], py2_stdlib: List[str], known_distributions: Set[str]
) -> None:
"""Generate requirements using imports found in a package."""
assert not package.requires, "Populate must be called once"
if not package.is_dir:
Expand Down Expand Up @@ -272,14 +269,12 @@ def generate_metadata(package: ThirdPartyPackage, py2_packages: List[str]) -> st
if not package.py3_compatible:
lines.append("python3 = false")
if package.requires:
distributions = [f'"types-{package_to_distribution.get(dep, dep)}"'
for dep in package.requires]
distributions = [f'"types-{package_to_distribution.get(dep, dep)}"' for dep in package.requires]
lines.append(f"requires = [{', '.join(distributions)}]")
return "\n".join(lines)


def copy_third_party(packages: List[ThirdPartyPackage],
py2_packages: List[ThirdPartyPackage]) -> None:
def copy_third_party(packages: List[ThirdPartyPackage], py2_packages: List[ThirdPartyPackage]) -> None:
"""Refactor the third party part using collected metadata."""
third_party_dir = os.path.join(OUTPUT_DIR, THIRD_PARTY_NAMESPACE)
os.makedirs(third_party_dir, exist_ok=True)
Expand Down Expand Up @@ -325,8 +320,7 @@ def main() -> None:
py2_stdlib_names += [package.name for package in stdlib if package.py_version == "2.7"]

# Collect all known distributions (for sanity checks).
known_distributions = {package_to_distribution.get(package.name, package.name)
for package in third_party + py2_third_party}
known_distributions = {package_to_distribution.get(package.name, package.name) for package in third_party + py2_third_party}

# Compute dependencies between third party packages/modules to populate metadata.
for package in third_party + py2_third_party:
Expand Down
14 changes: 7 additions & 7 deletions tests/check_consistent.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,21 @@
# manually update both files, and this test verifies that they are
# identical. The list below indicates which sets of files must match.

import os
import filecmp
import os

consistent_files = [
{'stdlib/2/builtins.pyi', 'stdlib/2/__builtin__.pyi'},
{'stdlib/2and3/threading.pyi', 'stdlib/2and3/_dummy_threading.pyi'},
{"stdlib/2/builtins.pyi", "stdlib/2/__builtin__.pyi"},
{"stdlib/2and3/threading.pyi", "stdlib/2and3/_dummy_threading.pyi"},
]


def main():
files = [os.path.join(root, file) for root, dir, files in os.walk('.') for file in files]
no_symlink = 'You cannot use symlinks in typeshed, please copy {} to its link.'
files = [os.path.join(root, file) for root, dir, files in os.walk(".") for file in files]
no_symlink = "You cannot use symlinks in typeshed, please copy {} to its link."
for file in files:
_, ext = os.path.splitext(file)
if ext == '.pyi' and os.path.islink(file):
if ext == ".pyi" and os.path.islink(file):
raise ValueError(no_symlink.format(file))
for file1, *others in consistent_files:
f1 = os.path.join(os.getcwd(), file1)
Expand All @@ -34,5 +34,5 @@ def main():
)


if __name__ == '__main__':
if __name__ == "__main__":
main()
2 changes: 1 addition & 1 deletion tests/mypy_selftest.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#!/usr/bin/env python3
"""Script to run mypy against its own code base."""

from pathlib import Path
import subprocess
import sys
import tempfile
from pathlib import Path

MYPY_VERSION = "0.790"

Expand Down
94 changes: 45 additions & 49 deletions tests/mypy_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,26 @@
5. Repeat steps 2-4 for other mypy runs (e.g. --py2)
"""

import argparse
import os
import re
import sys
import argparse

parser = argparse.ArgumentParser(description="Test runner for typeshed. "
"Patterns are unanchored regexps on the full path.")
parser.add_argument('-v', '--verbose', action='count', default=0, help="More output")
parser.add_argument('-n', '--dry-run', action='store_true', help="Don't actually run mypy")
parser.add_argument('-x', '--exclude', type=str, nargs='*', help="Exclude pattern")
parser.add_argument('-p', '--python-version', type=str, nargs='*',
help="These versions only (major[.minor])")
parser.add_argument('--platform',
help="Run mypy for a certain OS platform (defaults to sys.platform)")
parser.add_argument('--warn-unused-ignores', action='store_true',
help="Run mypy with --warn-unused-ignores "
"(hint: only get rid of warnings that are "
"unused for all platforms and Python versions)")
parser = argparse.ArgumentParser(description="Test runner for typeshed. " "Patterns are unanchored regexps on the full path.")
parser.add_argument("-v", "--verbose", action="count", default=0, help="More output")
parser.add_argument("-n", "--dry-run", action="store_true", help="Don't actually run mypy")
parser.add_argument("-x", "--exclude", type=str, nargs="*", help="Exclude pattern")
parser.add_argument("-p", "--python-version", type=str, nargs="*", help="These versions only (major[.minor])")
parser.add_argument("--platform", help="Run mypy for a certain OS platform (defaults to sys.platform)")
parser.add_argument(
"--warn-unused-ignores",
action="store_true",
help="Run mypy with --warn-unused-ignores "
"(hint: only get rid of warnings that are "
"unused for all platforms and Python versions)",
)

parser.add_argument('filter', type=str, nargs='*', help="Include pattern (default all)")
parser.add_argument("filter", type=str, nargs="*", help="Include pattern (default all)")


def log(args, *varargs):
Expand All @@ -41,36 +41,35 @@ def log(args, *varargs):

def match(fn, args, exclude_list):
if exclude_list.match(fn):
log(args, fn, 'exluded by exclude list')
log(args, fn, "exluded by exclude list")
return False
if not args.filter and not args.exclude:
log(args, fn, 'accept by default')
log(args, fn, "accept by default")
return True
if args.exclude:
for f in args.exclude:
if re.search(f, fn):
log(args, fn, 'excluded by pattern', f)
log(args, fn, "excluded by pattern", f)
return False
if args.filter:
for f in args.filter:
if re.search(f, fn):
log(args, fn, 'accepted by pattern', f)
log(args, fn, "accepted by pattern", f)
return True
if args.filter:
log(args, fn, 'rejected (no pattern matches)')
log(args, fn, "rejected (no pattern matches)")
return False
log(args, fn, 'accepted (no exclude pattern matches)')
log(args, fn, "accepted (no exclude pattern matches)")
return True


def libpath(major, minor):
versions = ['%d.%d' % (major, minor)
for minor in reversed(range(minor + 1))]
versions = ["%d.%d" % (major, minor) for minor in reversed(range(minor + 1))]
versions.append(str(major))
versions.append('2and3')
versions.append("2and3")
paths = []
for v in versions:
for top in ['stdlib', 'third_party']:
for top in ["stdlib", "third_party"]:
p = os.path.join(top, v)
if os.path.isdir(p):
paths.append(p)
Expand All @@ -81,8 +80,7 @@ def main():
args = parser.parse_args()

with open(os.path.join(os.path.dirname(__file__), "mypy_exclude_list.txt")) as f:
exclude_list = re.compile("(%s)$" % "|".join(
re.findall(r"^\s*([^\s#]+)\s*(?:#.*)?$", f.read(), flags=re.M)))
exclude_list = re.compile("(%s)$" % "|".join(re.findall(r"^\s*([^\s#]+)\s*(?:#.*)?$", f.read(), flags=re.M)))

try:
from mypy.main import main as mypy_main
Expand All @@ -92,8 +90,7 @@ def main():

versions = [(3, 9), (3, 8), (3, 7), (3, 6), (3, 5), (2, 7)]
if args.python_version:
versions = [v for v in versions
if any(('%d.%d' % v).startswith(av) for av in args.python_version)]
versions = [v for v in versions if any(("%d.%d" % v).startswith(av) for av in args.python_version)]
if not versions:
print("--- no versions selected ---")
sys.exit(1)
Expand All @@ -103,51 +100,50 @@ def main():
for major, minor in versions:
roots = libpath(major, minor)
files = []
seen = {'__builtin__', 'builtins', 'typing'} # Always ignore these.
seen = {"__builtin__", "builtins", "typing"} # Always ignore these.
for root in roots:
names = os.listdir(root)
for name in names:
full = os.path.join(root, name)
mod, ext = os.path.splitext(name)
if mod in seen or mod.startswith('.'):
if mod in seen or mod.startswith("."):
continue
if ext in ['.pyi', '.py']:
if ext in [".pyi", ".py"]:
if match(full, args, exclude_list):
seen.add(mod)
files.append(full)
elif (os.path.isfile(os.path.join(full, '__init__.pyi')) or
os.path.isfile(os.path.join(full, '__init__.py'))):
elif os.path.isfile(os.path.join(full, "__init__.pyi")) or os.path.isfile(os.path.join(full, "__init__.py")):
for r, ds, fs in os.walk(full):
ds.sort()
fs.sort()
for f in fs:
m, x = os.path.splitext(f)
if x in ['.pyi', '.py']:
if x in [".pyi", ".py"]:
fn = os.path.join(r, f)
if match(fn, args, exclude_list):
seen.add(mod)
files.append(fn)
if files:
runs += 1
flags = ['--python-version', '%d.%d' % (major, minor)]
flags.append('--strict-optional')
flags.append('--no-site-packages')
flags.append('--show-traceback')
flags.append('--no-implicit-optional')
flags.append('--disallow-any-generics')
flags.append('--disallow-subclassing-any')
flags = ["--python-version", "%d.%d" % (major, minor)]
flags.append("--strict-optional")
flags.append("--no-site-packages")
flags.append("--show-traceback")
flags.append("--no-implicit-optional")
flags.append("--disallow-any-generics")
flags.append("--disallow-subclassing-any")
if args.warn_unused_ignores:
flags.append('--warn-unused-ignores')
flags.append("--warn-unused-ignores")
if args.platform:
flags.extend(['--platform', args.platform])
sys.argv = ['mypy'] + flags + files
flags.extend(["--platform", args.platform])
sys.argv = ["mypy"] + flags + files
if args.verbose:
print("running", ' '.join(sys.argv))
print("running", " ".join(sys.argv))
else:
print("running mypy", ' '.join(flags), "# with", len(files), "files")
print("running mypy", " ".join(flags), "# with", len(files), "files")
try:
if not args.dry_run:
mypy_main('', sys.stdout, sys.stderr)
mypy_main("", sys.stdout, sys.stderr)
except SystemExit as err:
code = max(code, err.code)
if code:
Expand All @@ -158,5 +154,5 @@ def main():
sys.exit(1)


if __name__ == '__main__':
if __name__ == "__main__":
main()
Loading

0 comments on commit 48970d3

Please sign in to comment.