From 9cc09851e52bbb9a29018b8e53bb8e1afa4b6ff8 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Wed, 22 May 2024 16:18:19 -0400 Subject: [PATCH 01/13] Make sure `isinstance(typing_extensions.ParamSpec("P"), typing.TypeVar)` is unaffected by profiling functions --- CHANGELOG.md | 8 ++++++++ src/test_typing_extensions.py | 37 +++++++++++++++++++++++++++++++++++ src/typing_extensions.py | 2 +- 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d1ac543b..f315d1ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +# Unreleased + +- Fix incorrect behaviour of `typing_extensions.ParamSpec` on Python 3.8 and + 3.9 that meant that + `isinstance(typing_extensions.ParamSpec("P"), typing.TypeVar)` would have a + different result in some situations depending on whether or not a profiling + function had been set using `sys.setprofile`. Patch by Alex Waygood. + # Release 4.12.0rc1 (May 16, 2024) This release focuses on compatibility with the upcoming release of diff --git a/src/test_typing_extensions.py b/src/test_typing_extensions.py index 5d37b5bf..fac50f45 100644 --- a/src/test_typing_extensions.py +++ b/src/test_typing_extensions.py @@ -5020,6 +5020,43 @@ def test_eq(self): # won't be the same. self.assertNotEqual(hash(ParamSpec('P')), hash(P)) + def test_isinstance_results_unaffected_by_presence_of_tracing_function(self): + # See https://github.com/python/typing_extensions/issues/318 + + code = textwrap.dedent( + """\ + import sys, typing + + def trace_call(*args): + return trace_call + + def run(): + sys.modules.pop("typing_extensions", None) + from typing_extensions import ParamSpec + return isinstance(ParamSpec("P"), typing.TypeVar) + + isinstance_result_1 = run() + sys.setprofile(trace_call) + isinstance_result_2 = run() + sys.stdout.write(f"{isinstance_result_1} {isinstance_result_2}") + """ + ) + + # Run this in an isolated process or it pollutes the environment + # and makes other tests fail: + proc = subprocess.run( + [sys.executable, "-c", code], check=True, capture_output=True, text=True, + ) + + # Sanity checks that assert the test is working as expected + self.assertIsInstance(proc.stdout, str) + result1, result2 = proc.stdout.split(" ") + self.assertIn(result1, {"True", "False"}) + self.assertIn(result2, {"True", "False"}) + + # The actual test: + self.assertEqual(result1, result2) + class ConcatenateTests(BaseTestCase): def test_basics(self): diff --git a/src/typing_extensions.py b/src/typing_extensions.py index d549fb69..57e59a8b 100644 --- a/src/typing_extensions.py +++ b/src/typing_extensions.py @@ -1711,7 +1711,7 @@ def kwargs(self): def __init__(self, name, *, bound=None, covariant=False, contravariant=False, infer_variance=False, default=NoDefault): - super().__init__([self]) + list.__init__(self, [self]) self.__name__ = name self.__covariant__ = bool(covariant) self.__contravariant__ = bool(contravariant) From 211e95376d91bfaf725cec8ac73d77cc7dcf1a86 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Wed, 22 May 2024 16:22:37 -0400 Subject: [PATCH 02/13] debug --- src/test_typing_extensions.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/test_typing_extensions.py b/src/test_typing_extensions.py index fac50f45..080c0f7c 100644 --- a/src/test_typing_extensions.py +++ b/src/test_typing_extensions.py @@ -5044,9 +5044,14 @@ def run(): # Run this in an isolated process or it pollutes the environment # and makes other tests fail: - proc = subprocess.run( - [sys.executable, "-c", code], check=True, capture_output=True, text=True, - ) + try: + proc = subprocess.run( + [sys.executable, "-c", code], check=True, capture_output=True, text=True, + ) + except subprocess.CalledProcessError as exc: + print("stdout", exc.stdout, sep="\n") + print("stderr", exc.stderr, sep="\n") + raise # Sanity checks that assert the test is working as expected self.assertIsInstance(proc.stdout, str) From 652df9c5e99b11a715efbf6f955472e535284e91 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Wed, 22 May 2024 16:28:57 -0400 Subject: [PATCH 03/13] try shell=True --- src/test_typing_extensions.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/test_typing_extensions.py b/src/test_typing_extensions.py index 080c0f7c..af7b04fa 100644 --- a/src/test_typing_extensions.py +++ b/src/test_typing_extensions.py @@ -5046,7 +5046,11 @@ def run(): # and makes other tests fail: try: proc = subprocess.run( - [sys.executable, "-c", code], check=True, capture_output=True, text=True, + [sys.executable, "-c", code], + check=True, + capture_output=True, + text=True, + shell=True, ) except subprocess.CalledProcessError as exc: print("stdout", exc.stdout, sep="\n") From 4ebaa0812ea39f19995f8a7203b0eff95a238e2b Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Wed, 22 May 2024 16:31:22 -0400 Subject: [PATCH 04/13] Revert "try shell=True" This reverts commit 652df9c5e99b11a715efbf6f955472e535284e91. --- src/test_typing_extensions.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/test_typing_extensions.py b/src/test_typing_extensions.py index af7b04fa..080c0f7c 100644 --- a/src/test_typing_extensions.py +++ b/src/test_typing_extensions.py @@ -5046,11 +5046,7 @@ def run(): # and makes other tests fail: try: proc = subprocess.run( - [sys.executable, "-c", code], - check=True, - capture_output=True, - text=True, - shell=True, + [sys.executable, "-c", code], check=True, capture_output=True, text=True, ) except subprocess.CalledProcessError as exc: print("stdout", exc.stdout, sep="\n") From 4c3ac10d9c27e431170edec14816dcd7f4a562c7 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Wed, 22 May 2024 16:32:25 -0400 Subject: [PATCH 05/13] try passing all env vars --- src/test_typing_extensions.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/test_typing_extensions.py b/src/test_typing_extensions.py index 080c0f7c..c9c17b7d 100644 --- a/src/test_typing_extensions.py +++ b/src/test_typing_extensions.py @@ -11,6 +11,7 @@ import importlib import inspect import pickle +import os import re import subprocess import tempfile @@ -5046,7 +5047,11 @@ def run(): # and makes other tests fail: try: proc = subprocess.run( - [sys.executable, "-c", code], check=True, capture_output=True, text=True, + [sys.executable, "-c", code], + check=True, + capture_output=True, + text=True, + env=os.environ ) except subprocess.CalledProcessError as exc: print("stdout", exc.stdout, sep="\n") From 4c54e155fff963dab548cee23d5fac1c08254703 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Wed, 22 May 2024 16:33:53 -0400 Subject: [PATCH 06/13] Revert "try passing all env vars" This reverts commit 4c3ac10d9c27e431170edec14816dcd7f4a562c7. --- src/test_typing_extensions.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/test_typing_extensions.py b/src/test_typing_extensions.py index c9c17b7d..080c0f7c 100644 --- a/src/test_typing_extensions.py +++ b/src/test_typing_extensions.py @@ -11,7 +11,6 @@ import importlib import inspect import pickle -import os import re import subprocess import tempfile @@ -5047,11 +5046,7 @@ def run(): # and makes other tests fail: try: proc = subprocess.run( - [sys.executable, "-c", code], - check=True, - capture_output=True, - text=True, - env=os.environ + [sys.executable, "-c", code], check=True, capture_output=True, text=True, ) except subprocess.CalledProcessError as exc: print("stdout", exc.stdout, sep="\n") From b1d71378580d7d9ada7347571b48afe1bc4764dc Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Wed, 22 May 2024 16:34:32 -0400 Subject: [PATCH 07/13] Does this fix things? --- .github/workflows/publish.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index d1da0258..47704723 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -92,8 +92,8 @@ jobs: export path_to_file=$(find dist -type f -name "typing_extensions-*.tar.gz") echo "::notice::Unpacking source distribution: $path_to_file" tar xzf $path_to_file -C dist/ - cd ${path_to_file%.tar.gz} - python src/test_typing_extensions.py + cd ${path_to_file%.tar.gz}/src + python test_typing_extensions.py test-sdist-installed: name: Test installed source distribution From 49cc06a2d903655cf55144dd01b7c6f2da18ebc9 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Thu, 23 May 2024 16:31:36 -0400 Subject: [PATCH 08/13] Does this fix things better? --- .github/workflows/publish.yml | 4 ++-- src/test_typing_extensions.py | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 47704723..d1da0258 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -92,8 +92,8 @@ jobs: export path_to_file=$(find dist -type f -name "typing_extensions-*.tar.gz") echo "::notice::Unpacking source distribution: $path_to_file" tar xzf $path_to_file -C dist/ - cd ${path_to_file%.tar.gz}/src - python test_typing_extensions.py + cd ${path_to_file%.tar.gz} + python src/test_typing_extensions.py test-sdist-installed: name: Test installed source distribution diff --git a/src/test_typing_extensions.py b/src/test_typing_extensions.py index 080c0f7c..0d6637a8 100644 --- a/src/test_typing_extensions.py +++ b/src/test_typing_extensions.py @@ -5046,7 +5046,11 @@ def run(): # and makes other tests fail: try: proc = subprocess.run( - [sys.executable, "-c", code], check=True, capture_output=True, text=True, + [sys.executable, "-c", code], + check=True, + capture_output=True, + text=True, + cwd=".", ) except subprocess.CalledProcessError as exc: print("stdout", exc.stdout, sep="\n") From ae33db8f51c2627705c686c20d3779356110f917 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Thu, 23 May 2024 16:33:32 -0400 Subject: [PATCH 09/13] this? --- src/test_typing_extensions.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test_typing_extensions.py b/src/test_typing_extensions.py index 0d6637a8..e1848c3f 100644 --- a/src/test_typing_extensions.py +++ b/src/test_typing_extensions.py @@ -10,6 +10,7 @@ from functools import lru_cache import importlib import inspect +import os import pickle import re import subprocess @@ -5050,7 +5051,7 @@ def run(): check=True, capture_output=True, text=True, - cwd=".", + env={**os.environ, "PYTHONPATH": "."}, ) except subprocess.CalledProcessError as exc: print("stdout", exc.stdout, sep="\n") From 03a2adec9d4bd6033abf8a40aeface11e996ba97 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Thu, 23 May 2024 16:38:38 -0400 Subject: [PATCH 10/13] debug --- .github/workflows/publish.yml | 2 ++ src/test_typing_extensions.py | 3 +++ 2 files changed, 5 insertions(+) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index d1da0258..0c24f1e7 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -92,7 +92,9 @@ jobs: export path_to_file=$(find dist -type f -name "typing_extensions-*.tar.gz") echo "::notice::Unpacking source distribution: $path_to_file" tar xzf $path_to_file -C dist/ + ls -a cd ${path_to_file%.tar.gz} + ls -a python src/test_typing_extensions.py test-sdist-installed: diff --git a/src/test_typing_extensions.py b/src/test_typing_extensions.py index e1848c3f..0e0f1427 100644 --- a/src/test_typing_extensions.py +++ b/src/test_typing_extensions.py @@ -5027,6 +5027,9 @@ def test_isinstance_results_unaffected_by_presence_of_tracing_function(self): code = textwrap.dedent( """\ import sys, typing + import os + print(f'{os.getcwd()=}') + print(f'{os.environ["PYTHONPATH"]=}') def trace_call(*args): return trace_call From 531120867b3f18c0acbffbff33e29f5f31fc73eb Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Thu, 23 May 2024 16:41:49 -0400 Subject: [PATCH 11/13] Revert "debug" This reverts commit 03a2adec9d4bd6033abf8a40aeface11e996ba97. --- .github/workflows/publish.yml | 2 -- src/test_typing_extensions.py | 3 --- 2 files changed, 5 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 0c24f1e7..d1da0258 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -92,9 +92,7 @@ jobs: export path_to_file=$(find dist -type f -name "typing_extensions-*.tar.gz") echo "::notice::Unpacking source distribution: $path_to_file" tar xzf $path_to_file -C dist/ - ls -a cd ${path_to_file%.tar.gz} - ls -a python src/test_typing_extensions.py test-sdist-installed: diff --git a/src/test_typing_extensions.py b/src/test_typing_extensions.py index 0e0f1427..e1848c3f 100644 --- a/src/test_typing_extensions.py +++ b/src/test_typing_extensions.py @@ -5027,9 +5027,6 @@ def test_isinstance_results_unaffected_by_presence_of_tracing_function(self): code = textwrap.dedent( """\ import sys, typing - import os - print(f'{os.getcwd()=}') - print(f'{os.environ["PYTHONPATH"]=}') def trace_call(*args): return trace_call From 0327e20729d3eb9eacfba6ffff6ed9d951fda1b3 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Thu, 23 May 2024 16:41:59 -0400 Subject: [PATCH 12/13] Revert "this?" This reverts commit ae33db8f51c2627705c686c20d3779356110f917. --- src/test_typing_extensions.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test_typing_extensions.py b/src/test_typing_extensions.py index e1848c3f..0d6637a8 100644 --- a/src/test_typing_extensions.py +++ b/src/test_typing_extensions.py @@ -10,7 +10,6 @@ from functools import lru_cache import importlib import inspect -import os import pickle import re import subprocess @@ -5051,7 +5050,7 @@ def run(): check=True, capture_output=True, text=True, - env={**os.environ, "PYTHONPATH": "."}, + cwd=".", ) except subprocess.CalledProcessError as exc: print("stdout", exc.stdout, sep="\n") From 729c942f143235a761659c7c1db47a57372d0dd9 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Thu, 23 May 2024 16:42:08 -0400 Subject: [PATCH 13/13] Revert "Does this fix things better?" This reverts commit 49cc06a2d903655cf55144dd01b7c6f2da18ebc9. --- .github/workflows/publish.yml | 4 ++-- src/test_typing_extensions.py | 6 +----- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index d1da0258..47704723 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -92,8 +92,8 @@ jobs: export path_to_file=$(find dist -type f -name "typing_extensions-*.tar.gz") echo "::notice::Unpacking source distribution: $path_to_file" tar xzf $path_to_file -C dist/ - cd ${path_to_file%.tar.gz} - python src/test_typing_extensions.py + cd ${path_to_file%.tar.gz}/src + python test_typing_extensions.py test-sdist-installed: name: Test installed source distribution diff --git a/src/test_typing_extensions.py b/src/test_typing_extensions.py index 0d6637a8..080c0f7c 100644 --- a/src/test_typing_extensions.py +++ b/src/test_typing_extensions.py @@ -5046,11 +5046,7 @@ def run(): # and makes other tests fail: try: proc = subprocess.run( - [sys.executable, "-c", code], - check=True, - capture_output=True, - text=True, - cwd=".", + [sys.executable, "-c", code], check=True, capture_output=True, text=True, ) except subprocess.CalledProcessError as exc: print("stdout", exc.stdout, sep="\n")