From 8eecadd7b9b0f97ae6f8a42e263d048157d0947d Mon Sep 17 00:00:00 2001 From: Akuli Date: Sun, 28 Nov 2021 13:15:30 +0200 Subject: [PATCH 1/6] stubtest_stdlib: fail if there are unused allowlist entries --- .../workflows/stubtest-unused-allowlist.yml | 61 ------------------- .github/workflows/stubtest.yml | 2 +- .github/workflows/tests.yml | 2 +- tests/stubtest_unused.py | 50 --------------- 4 files changed, 2 insertions(+), 113 deletions(-) delete mode 100644 .github/workflows/stubtest-unused-allowlist.yml delete mode 100755 tests/stubtest_unused.py diff --git a/.github/workflows/stubtest-unused-allowlist.yml b/.github/workflows/stubtest-unused-allowlist.yml deleted file mode 100644 index 706064de659a..000000000000 --- a/.github/workflows/stubtest-unused-allowlist.yml +++ /dev/null @@ -1,61 +0,0 @@ -name: Remove unused stubtest allowlist entries - -on: - workflow_dispatch: - schedule: - - cron: '0 4 * * *' - -permissions: - contents: write - pull-requests: write - -jobs: - stubtest: - if: github.repository == 'python/typeshed' - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: ["ubuntu-latest", "windows-latest", "macos-latest"] - python-version: ["3.6", "3.7", "3.8", "3.9", "3.10"] - fail-fast: false - - steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} on ${{ matrix.os }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: pip install $(grep mypy== requirements-tests-py3.txt) - - name: Run stubtest - shell: bash - run: ./tests/stubtest_unused.py | tee stubtest-output-${{ matrix.os }}-${{ matrix.python-version }} - - name: Store output - uses: actions/upload-artifact@v2 - with: - name: stubtest-output - path: stubtest-output-${{ matrix.os }}-${{ matrix.python-version }} - - collate: - if: github.repository == 'python/typeshed' - runs-on: ubuntu-latest - needs: stubtest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 - - name: Get stubtest outputs - uses: actions/download-artifact@v2 - with: - name: stubtest-output - - name: Collate duplicates - run: cat stubtest-output-* | sort -u | tee stubtest-output - - name: Remove entries from allowlists - run: python scripts/update-stubtest-allowlist.py stubtest-output - - name: Create pull request - # v3.8.2 - uses: peter-evans/create-pull-request@052fc72b4198ba9fbc81b818c6e1859f747d49a8 - with: - token: ${{ secrets.GITHUB_TOKEN }} - commit-message: Remove unused stubtest allowlist entries - title: "[gh-action] Remove unused stubtest allowlist entries" - base: master diff --git a/.github/workflows/stubtest.yml b/.github/workflows/stubtest.yml index ba957e9a3160..82531452a8b9 100644 --- a/.github/workflows/stubtest.yml +++ b/.github/workflows/stubtest.yml @@ -33,7 +33,7 @@ jobs: - name: Install dependencies run: pip install $(grep tomli== requirements-tests-py3.txt) $(grep mypy== requirements-tests-py3.txt) - name: Run stubtest - run: python tests/stubtest_stdlib.py --ignore-unused-allowlist + run: python tests/stubtest_stdlib.py stubtest-third-party: name: Check third party stubs with stubtest diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 6bf959aaaa31..8b4bbcc85f3e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -109,7 +109,7 @@ jobs: - name: Install dependencies run: pip install $(grep tomli== requirements-tests-py3.txt) $(grep mypy== requirements-tests-py3.txt) - name: Run stubtest - run: python tests/stubtest_stdlib.py --ignore-unused-allowlist + run: python tests/stubtest_stdlib.py stubtest-third-party: name: Check third party stubs with stubtest diff --git a/tests/stubtest_unused.py b/tests/stubtest_unused.py deleted file mode 100755 index c2b52fbbb8c7..000000000000 --- a/tests/stubtest_unused.py +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env python3 - -# Runs stubtest and prints each unused allowlist entry with filename. -import subprocess -import sys -from pathlib import Path -from typing import List, Tuple - -_UNUSED_NOTE = "note: unused allowlist entry " -_ALLOWLIST_PATH = Path("tests") / "stubtest_allowlists" - - -def main() -> None: - unused = run_stubtest() - with_filenames = [] - for uu in unused: - with_filenames.extend(unused_files(uu)) - for file, uu in with_filenames: - print(file + ":" + uu) - - -def run_stubtest() -> List[str]: - proc = subprocess.run([sys.executable, "tests/stubtest_stdlib.py"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - output = proc.stdout.decode("utf-8").splitlines() - return [line[len(_UNUSED_NOTE) :].strip() for line in output if line.startswith(_UNUSED_NOTE)] - - -def unused_files(unused: str) -> List[Tuple[str, str]]: - version = "py{}{}".format(sys.version_info[0], sys.version_info[1]) - files = ["py3_common.txt", version + ".txt", sys.platform + ".txt", sys.platform + "-" + version + ".txt"] - found = [] - for file in files: - path = _ALLOWLIST_PATH / file - if find_unused_in_file(unused, path): - found.append((path.as_posix(), unused)) - if not found: - raise ValueError("unused item {} not found in any allowlist file".format(unused)) - return found - - -def find_unused_in_file(unused: str, path: Path) -> bool: - try: - with open(path) as f: - return any(line.strip().split(" ")[0] == unused for line in f) - except FileNotFoundError: - return False - - -if __name__ == "__main__": - main() From 1265cb461cd0efe4e700993fb7b4f34e7abcf5f9 Mon Sep 17 00:00:00 2001 From: Akuli Date: Sun, 28 Nov 2021 13:24:32 +0200 Subject: [PATCH 2/6] improve print --- tests/stubtest_stdlib.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/stubtest_stdlib.py b/tests/stubtest_stdlib.py index 9918555654b3..8d4d04910823 100755 --- a/tests/stubtest_stdlib.py +++ b/tests/stubtest_stdlib.py @@ -57,7 +57,10 @@ def run_stubtest(typeshed_dir: Path) -> int: "\nCommand run was: {}\n".format(" ".join(cmd)), file=sys.stderr, ) - print("stubtest failed", file=sys.stderr) + print("\n\n", file=sys.stderr) + print( + f'To fix "unused allowlist" errors, remove the corresponding entries from {allowlist_dir}', file=sys.stderr + ) return e.returncode else: print("stubtest succeeded", file=sys.stderr) From 4cf57c2639dbcd2d07ba65dd3d8dfc70e8f59a45 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 28 Nov 2021 11:25:09 +0000 Subject: [PATCH 3/6] [pre-commit.ci] auto fixes from pre-commit.com hooks --- tests/stubtest_stdlib.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/stubtest_stdlib.py b/tests/stubtest_stdlib.py index 8d4d04910823..8b3976a2b12e 100755 --- a/tests/stubtest_stdlib.py +++ b/tests/stubtest_stdlib.py @@ -58,9 +58,7 @@ def run_stubtest(typeshed_dir: Path) -> int: file=sys.stderr, ) print("\n\n", file=sys.stderr) - print( - f'To fix "unused allowlist" errors, remove the corresponding entries from {allowlist_dir}', file=sys.stderr - ) + print(f'To fix "unused allowlist" errors, remove the corresponding entries from {allowlist_dir}', file=sys.stderr) return e.returncode else: print("stubtest succeeded", file=sys.stderr) From 151fe4859a756f1593fb52fd510ff4161367b316 Mon Sep 17 00:00:00 2001 From: Akuli Date: Sun, 28 Nov 2021 11:35:00 +0000 Subject: [PATCH 4/6] Remove unused stubtest allowlist entries --- tests/stubtest_allowlists/py310.txt | 6 ------ tests/stubtest_allowlists/py39.txt | 3 --- tests/stubtest_allowlists/py3_common.txt | 1 - 3 files changed, 10 deletions(-) diff --git a/tests/stubtest_allowlists/py310.txt b/tests/stubtest_allowlists/py310.txt index 80598ad95b41..08cd87aa632d 100644 --- a/tests/stubtest_allowlists/py310.txt +++ b/tests/stubtest_allowlists/py310.txt @@ -23,7 +23,6 @@ _collections_abc.MutableMapping.__setitem__ _collections_abc.MutableMapping.pop _collections_abc.MutableMapping.setdefault -_dummy_thread ast.Bytes.__new__ ast.Ellipsis.__new__ ast.ExtSlice.__new__ @@ -48,7 +47,6 @@ collections.abc.ValuesView.__reversed__ contextvars.Context.__init__ # Default C __init__ signature is wrong dataclasses.field dataclasses.KW_ONLY -dummy_threading enum.Enum._generate_next_value_ fractions.Fraction.__new__ # overload is too complicated for stubtest to resolve functools.partialmethod.__get__ @@ -69,7 +67,6 @@ platform.uname_result.__new__ platform.uname_result._fields platform.uname_result.processor queue.SimpleQueue.__init__ # Default C __init__ signature is wrong -smtplib.LMTP.__init__ ssl.PROTOCOL_SSLv3 # Depends on ssl compilation ssl.RAND_egd # Depends on openssl compilation symtable.SymbolTable.has_exec @@ -133,8 +130,6 @@ importlib.machinery.BuiltinImporter.exec_module importlib.machinery.FrozenImporter.create_module importlib.machinery.PathFinder.invalidate_caches importlib.metadata.MetadataPathFinder.invalidate_caches -locale.strcoll -locale.strxfrm logging.Formatter.__init__ logging.LoggerAdapter.__init__ logging.PercentStyle.__init__ @@ -168,7 +163,6 @@ sqlite3.dbapi2.Row.keys sqlite3.dbapi2.complete_statement ssl.SSLContext.__new__ ssl._create_unverified_context -ssl.get_server_certificate typing.SupportsRound.__round__ unicodedata.ucnhash_CAPI unittest.mock.create_autospec diff --git a/tests/stubtest_allowlists/py39.txt b/tests/stubtest_allowlists/py39.txt index af60959573bf..80df8d088cb0 100644 --- a/tests/stubtest_allowlists/py39.txt +++ b/tests/stubtest_allowlists/py39.txt @@ -6,7 +6,6 @@ _collections_abc.AsyncGenerator.ag_running _collections_abc.ItemsView.__reversed__ _collections_abc.KeysView.__reversed__ _collections_abc.ValuesView.__reversed__ -_dummy_thread ast.Bytes.__new__ ast.Ellipsis.__new__ ast.ExtSlice.__new__ @@ -38,7 +37,6 @@ collections.abc.KeysView.__reversed__ collections.abc.ValuesView.__reversed__ contextvars.Context.__init__ # Default C __init__ signature is wrong dataclasses.field -dummy_threading enum.Enum._generate_next_value_ fractions.Fraction.__new__ # overload is too complicated for stubtest to resolve functools.partialmethod.__get__ @@ -60,7 +58,6 @@ platform.uname_result._fields platform.uname_result.processor queue.SimpleQueue.__init__ # Default C __init__ signature is wrong sched.Event.__doc__ # __slots__ is overridden -smtplib.LMTP.__init__ ssl.PROTOCOL_SSLv3 # Depends on ssl compilation ssl.RAND_egd # Depends on openssl compilation symtable.SymbolTable.has_exec diff --git a/tests/stubtest_allowlists/py3_common.txt b/tests/stubtest_allowlists/py3_common.txt index c449bf197cde..14963eb441a7 100644 --- a/tests/stubtest_allowlists/py3_common.txt +++ b/tests/stubtest_allowlists/py3_common.txt @@ -11,7 +11,6 @@ _collections_abc.Generator.gi_yieldfrom _collections_abc.Mapping.get # Adding None to the Union messed up mypy _collections_abc.Sequence.index # Supporting None in end is not mandatory _csv.Dialect.__init__ # C __init__ signature is inaccurate -_dummy_threading _socket.* _threading_local.local.__new__ _typeshed.* # Utility types for typeshed, doesn't exist at runtime From e0ff3ac5cff753fa8b2146533e99d1121a6572b1 Mon Sep 17 00:00:00 2001 From: Akuli Date: Sun, 28 Nov 2021 13:47:21 +0200 Subject: [PATCH 5/6] add _dummy_threading exclude back manually --- tests/stubtest_allowlists/py36.txt | 1 + tests/stubtest_allowlists/py37.txt | 1 + tests/stubtest_allowlists/py38.txt | 1 + 3 files changed, 3 insertions(+) diff --git a/tests/stubtest_allowlists/py36.txt b/tests/stubtest_allowlists/py36.txt index b4c0e2d2f7f0..f10811e38ce1 100644 --- a/tests/stubtest_allowlists/py36.txt +++ b/tests/stubtest_allowlists/py36.txt @@ -2,6 +2,7 @@ _collections_abc.AsyncGenerator.ag_await _collections_abc.AsyncGenerator.ag_code _collections_abc.AsyncGenerator.ag_frame _collections_abc.AsyncGenerator.ag_running +_dummy_threading asyncio.Future.__init__ # Usually initialized from c object asyncio.exceptions # Added in Python 3.8 asyncio.format_helpers # Added in Python 3.7 diff --git a/tests/stubtest_allowlists/py37.txt b/tests/stubtest_allowlists/py37.txt index 968cfd67cccf..cc23ab809094 100644 --- a/tests/stubtest_allowlists/py37.txt +++ b/tests/stubtest_allowlists/py37.txt @@ -2,6 +2,7 @@ _collections_abc.AsyncGenerator.ag_await _collections_abc.AsyncGenerator.ag_code _collections_abc.AsyncGenerator.ag_frame _collections_abc.AsyncGenerator.ag_running +_dummy_threading asyncio.compat # Removed in 3.7 asyncio.Future.__init__ # Usually initialized from c object asyncio.Future._callbacks # Usually initialized from c object diff --git a/tests/stubtest_allowlists/py38.txt b/tests/stubtest_allowlists/py38.txt index 249e9c4a56b5..5188b0510c4f 100644 --- a/tests/stubtest_allowlists/py38.txt +++ b/tests/stubtest_allowlists/py38.txt @@ -5,6 +5,7 @@ _collections_abc.AsyncGenerator.ag_running _collections_abc.ItemsView.__reversed__ _collections_abc.KeysView.__reversed__ _collections_abc.ValuesView.__reversed__ +_dummy_threading ast.Bytes.__new__ ast.Ellipsis.__new__ ast.NameConstant.__new__ From 58306fe3208a2204399c510feb3df67f1dc0ef89 Mon Sep 17 00:00:00 2001 From: Akuli Date: Wed, 1 Dec 2021 12:06:43 +0200 Subject: [PATCH 6/6] manually remove logging __init__ allowlist entries --- tests/stubtest_allowlists/py310.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/stubtest_allowlists/py310.txt b/tests/stubtest_allowlists/py310.txt index 00321ad49789..e24c02c03294 100644 --- a/tests/stubtest_allowlists/py310.txt +++ b/tests/stubtest_allowlists/py310.txt @@ -124,9 +124,6 @@ tkinter.EventType.__new__ _markupbase.ParserBase.error asyncio.proactor_events._ProactorReadPipeTransport.__init__ distutils.command.bdist_wininst -logging.Formatter.__init__ -logging.LoggerAdapter.__init__ -logging.PercentStyle.__init__ py_compile.main pyclbr.Class.__init__ pyclbr.Function.__init__