From d5b20ef18f873878e2160729f7c65ecdf6e9d660 Mon Sep 17 00:00:00 2001 From: Bader Zaidan Date: Tue, 18 Jan 2022 01:07:30 +0100 Subject: [PATCH 1/8] bpo-46421: fix local directory invocation error for unittest --- Lib/unittest/loader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/unittest/loader.py b/Lib/unittest/loader.py index eb18cd0b49cd26..cb3201e393c135 100644 --- a/Lib/unittest/loader.py +++ b/Lib/unittest/loader.py @@ -122,7 +122,7 @@ def loadTestsFromName(self, name, module=None): The method optionally resolves the names relative to a given module. """ - parts = name.split('.') + parts = list(filter(None, (name.split('.')))) error_case, error_message = None, None if module is None: parts_copy = parts[:] From 6a89a1e33719dc94500a6816333a89487a30efc4 Mon Sep 17 00:00:00 2001 From: Bader Zaidan Date: Tue, 18 Jan 2022 01:29:47 +0100 Subject: [PATCH 2/8] bpo-46421: add blurb file --- .../next/Library/2022-01-18-01-29-38.bpo-46421.9LdmNr.rst | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2022-01-18-01-29-38.bpo-46421.9LdmNr.rst diff --git a/Misc/NEWS.d/next/Library/2022-01-18-01-29-38.bpo-46421.9LdmNr.rst b/Misc/NEWS.d/next/Library/2022-01-18-01-29-38.bpo-46421.9LdmNr.rst new file mode 100644 index 00000000000000..03ff27fd7d1a70 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-01-18-01-29-38.bpo-46421.9LdmNr.rst @@ -0,0 +1,3 @@ +Fix a unittest issue where if the command was invoked as ``python -m +unittest`` and the filename(s) began with a dot (.), a ``ValueError`` is +returned. From ecbf1d0dd9c9cb92ec3ba16c0ca5c4ee8a036aee Mon Sep 17 00:00:00 2001 From: Bader Zaidan Date: Tue, 18 Jan 2022 01:30:12 +0100 Subject: [PATCH 3/8] bpo-46421: add contributor name to ACKS --- Misc/ACKS | 1 + 1 file changed, 1 insertion(+) diff --git a/Misc/ACKS b/Misc/ACKS index 7f2e94dfa615f1..1224c6b890d23e 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1985,6 +1985,7 @@ Masazumi Yoshikawa Arnaud Ysmal Bernard Yue Moshe Zadka +Bader Zaidan Elias Zamaria Milan Zamazal Artur Zaprzala From cb4e93f37452f2126f0c7c8675cd4b620de7452c Mon Sep 17 00:00:00 2001 From: Bader Zaidan Date: Tue, 18 Jan 2022 02:37:29 +0100 Subject: [PATCH 4/8] bpo-46421: string stripping directory to pass tests This is a better solution to the unittest fix that passes its own unit tests. Instead of filtering for ``None`` types, I just tear off the first dots in ``name`` --- Lib/unittest/loader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/unittest/loader.py b/Lib/unittest/loader.py index cb3201e393c135..ffbd94ca82d839 100644 --- a/Lib/unittest/loader.py +++ b/Lib/unittest/loader.py @@ -122,7 +122,7 @@ def loadTestsFromName(self, name, module=None): The method optionally resolves the names relative to a given module. """ - parts = list(filter(None, (name.split('.')))) + parts = name.lstrip('.').split('.') error_case, error_message = None, None if module is None: parts_copy = parts[:] From 344a5dd5b457672fd66d5e3a28fdfb69644d8b1e Mon Sep 17 00:00:00 2001 From: Bader Zaidan Date: Sat, 22 Jan 2022 20:47:50 +0100 Subject: [PATCH 5/8] fix-issue-46421: add cmd_line test for unittest call --- Lib/test/test_cmd_line.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index 86ee27485c9642..b1ced45aa1a7f8 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -161,6 +161,19 @@ def test_run_module_bug1764407(self): self.assertTrue(data.find(b'1 loop') != -1) self.assertTrue(data.find(b'__main__.Timer') != -1) + def test_relativedir_bug46421(self): + # Test `python -m unittest` with a relative directory beginning with ./ + # Note: We have to switch to the project's top module's directory, as per + # the python unittest wiki. We will switch back when we are done. + defaultwd = os.getcwd() + projectlibpath = os.path.dirname(__file__).removesuffix("test") + os.chdir(projectlibpath) + # Testing with and without ./ + assert_python_ok('-m', 'unittest', "test/test_longexp.py") + assert_python_ok('-m', 'unittest', "./test/test_longexp.py") + # reset cwd + os.chdir(defaultwd) + def test_run_code(self): # Test expected operation of the '-c' switch # Switch needs an argument From 4034ad5ecb386fa31a52e3279c08482604e7af6a Mon Sep 17 00:00:00 2001 From: Bader Zaidan Date: Sat, 22 Jan 2022 21:14:43 +0100 Subject: [PATCH 6/8] fix-issue-46421: replace chdir with os_helper function --- Lib/test/test_cmd_line.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index b1ced45aa1a7f8..3879a303eab9f8 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -167,12 +167,10 @@ def test_relativedir_bug46421(self): # the python unittest wiki. We will switch back when we are done. defaultwd = os.getcwd() projectlibpath = os.path.dirname(__file__).removesuffix("test") - os.chdir(projectlibpath) - # Testing with and without ./ - assert_python_ok('-m', 'unittest', "test/test_longexp.py") - assert_python_ok('-m', 'unittest', "./test/test_longexp.py") - # reset cwd - os.chdir(defaultwd) + with os_helper.change_cwd(projectlibpath): + # Testing with and without ./ + assert_python_ok('-m', 'unittest', "test/test_longexp.py") + assert_python_ok('-m', 'unittest', "./test/test_longexp.py") def test_run_code(self): # Test expected operation of the '-c' switch From 1e2cda816b4c806a1d6414d0556a6d4c92cc0a7f Mon Sep 17 00:00:00 2001 From: Bader Zaidan Date: Wed, 16 Mar 2022 17:34:30 +0100 Subject: [PATCH 7/8] bpo-46421: Fix leading character in _convert_name --- Lib/unittest/loader.py | 2 +- Lib/unittest/main.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/unittest/loader.py b/Lib/unittest/loader.py index ffbd94ca82d839..eb18cd0b49cd26 100644 --- a/Lib/unittest/loader.py +++ b/Lib/unittest/loader.py @@ -122,7 +122,7 @@ def loadTestsFromName(self, name, module=None): The method optionally resolves the names relative to a given module. """ - parts = name.lstrip('.').split('.') + parts = name.split('.') error_case, error_message = None, None if module is None: parts_copy = parts[:] diff --git a/Lib/unittest/main.py b/Lib/unittest/main.py index e62469aa2a170f..841af4063844df 100644 --- a/Lib/unittest/main.py +++ b/Lib/unittest/main.py @@ -39,7 +39,7 @@ def _convert_name(name): name = rel_path # on Windows both '\' and '/' are used as path # separators. Better to replace both than rely on os.path.sep - return name[:-3].replace('\\', '.').replace('/', '.') + return name[:-3].replace('\\', '.').replace('/', '.').lstrip('.') return name def _convert_names(names): From 4ac8b6b4760dfff3ef160fd82f04779dd5d62cb1 Mon Sep 17 00:00:00 2001 From: Bader Zaidan Date: Wed, 16 Mar 2022 19:01:59 +0100 Subject: [PATCH 8/8] bpo-46421: Replace lstrip with normpath for unittest libraries --- Lib/unittest/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/unittest/main.py b/Lib/unittest/main.py index 841af4063844df..88a188c545cd07 100644 --- a/Lib/unittest/main.py +++ b/Lib/unittest/main.py @@ -39,7 +39,7 @@ def _convert_name(name): name = rel_path # on Windows both '\' and '/' are used as path # separators. Better to replace both than rely on os.path.sep - return name[:-3].replace('\\', '.').replace('/', '.').lstrip('.') + return os.path.normpath(name)[:-3].replace('\\', '.').replace('/', '.') return name def _convert_names(names):