From e24b6b03886a36461af3381637a33fd8de6bee06 Mon Sep 17 00:00:00 2001 From: Christoph Buelter Date: Thu, 5 Dec 2019 13:56:45 +0100 Subject: [PATCH 1/8] Change -k EXPRESSION matching to be case-insensitive --- src/_pytest/mark/legacy.py | 10 +++++++++- testing/test_collection.py | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/_pytest/mark/legacy.py b/src/_pytest/mark/legacy.py index 3721e3b02..651288cb8 100644 --- a/src/_pytest/mark/legacy.py +++ b/src/_pytest/mark/legacy.py @@ -57,7 +57,15 @@ class KeywordMapping: return cls(mapped_names) def __getitem__(self, subname): - for name in self._names: + """Return whether subname is included within stored names. + + The string inclusion check is case-insensitive. + + """ + subname = subname.lower() + names = [name.lower() for name in self._names] + + for name in names: if subname in name: return True return False diff --git a/testing/test_collection.py b/testing/test_collection.py index 624e9dd4e..fcbfcf5fb 100644 --- a/testing/test_collection.py +++ b/testing/test_collection.py @@ -809,6 +809,40 @@ class TestNodekeywords: reprec = testdir.inline_run("-k repr") reprec.assertoutcome(passed=1, failed=0) + def test_keyword_matching_is_case_insensitive_by_default(self, testdir): + """Check that selection via -k EXPRESSION is case-insensitive. + + Since markers are also added to the node keywords, they too can + be matched without having to think about case sensitivity. + + """ + testdir.makepyfile( + """ + import pytest + + def test_sPeCiFiCToPiC_1(): + assert True + + class TestSpecificTopic_2: + def test(self): + assert True + + @pytest.mark.sPeCiFiCToPic_3 + def test(): + assert True + + @pytest.mark.sPeCiFiCToPic_4 + class Test: + def test(self): + assert True + + """ + ) + num_all_tests_passed = 4 + for expression in ("specifictopic", "SPECIFICTOPIC", "SpecificTopic"): + reprec = testdir.inline_run("-k " + expression) + reprec.assertoutcome(passed=num_all_tests_passed, failed=0) + COLLECTION_ERROR_PY_FILES = dict( test_01_failure=""" From ac5929eef35508d267bc4010cb9b4ae0b6de3f74 Mon Sep 17 00:00:00 2001 From: Christoph Buelter Date: Thu, 5 Dec 2019 14:13:22 +0100 Subject: [PATCH 2/8] Update docs about case-insensitive expression matching --- doc/en/example/markers.rst | 4 ++++ doc/en/usage.rst | 4 ++-- src/_pytest/mark/__init__.py | 3 ++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/doc/en/example/markers.rst b/doc/en/example/markers.rst index 8143b3fd4..e64f31fd5 100644 --- a/doc/en/example/markers.rst +++ b/doc/en/example/markers.rst @@ -148,6 +148,10 @@ which implements a substring match on the test names instead of the exact match on markers that ``-m`` provides. This makes it easy to select tests based on their names: +.. versionadded: 5.3.1/6.0 + +The expression matching is now case-insensitive. + .. code-block:: pytest $ pytest -v -k http # running with the above defined example module diff --git a/doc/en/usage.rst b/doc/en/usage.rst index 245a67b68..527794823 100644 --- a/doc/en/usage.rst +++ b/doc/en/usage.rst @@ -94,8 +94,8 @@ Pytest supports several ways to run and select tests from the command-line. pytest -k "MyClass and not method" -This will run tests which contain names that match the given *string expression*, which can -include Python operators that use filenames, class names and function names as variables. +This will run tests which contain names that match the given *string expression* (case-insensitive), +which can include Python operators that use filenames, class names and function names as variables. The example above will run ``TestMyClass.test_something`` but not ``TestMyClass.test_method_simple``. .. _nodeids: diff --git a/src/_pytest/mark/__init__.py b/src/_pytest/mark/__init__.py index e21e234e7..f493bd839 100644 --- a/src/_pytest/mark/__init__.py +++ b/src/_pytest/mark/__init__.py @@ -52,7 +52,8 @@ def pytest_addoption(parser): "-k 'not test_method and not test_other' will eliminate the matches. " "Additionally keywords are matched to classes and functions " "containing extra names in their 'extra_keyword_matches' set, " - "as well as functions which have names assigned directly to them.", + "as well as functions which have names assigned directly to them. " + "The matching is case-insensitive.", ) group._addoption( From 24d4882d8267b9ee0f4e2d0f046b8343361d2e91 Mon Sep 17 00:00:00 2001 From: Christoph Buelter Date: Thu, 5 Dec 2019 14:20:07 +0100 Subject: [PATCH 3/8] Update authors file and sort the list --- AUTHORS | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/AUTHORS b/AUTHORS index a3e526c5a..105c1be53 100644 --- a/AUTHORS +++ b/AUTHORS @@ -59,12 +59,12 @@ Christian Fetzer Christian Neumüller Christian Theunert Christian Tismer -Christopher Gilling +Christoph Buelter Christopher Dignam +Christopher Gilling CrazyMerlyn Cyrus Maden Damian Skrzypczak -Dhiren Serai Daniel Grana Daniel Hahler Daniel Nuri @@ -79,6 +79,7 @@ David Szotten David Vierra Daw-Ran Liou Denis Kirisov +Dhiren Serai Diego Russo Dmitry Dygalo Dmitry Pribysh From 5a7de2c2cb34d49c3ea3aa0baee4a6b568ef37cd Mon Sep 17 00:00:00 2001 From: Christoph Buelter Date: Thu, 5 Dec 2019 14:28:21 +0100 Subject: [PATCH 4/8] Add changelog file for PR 6316 --- changelog/6316.improvement.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog/6316.improvement.rst diff --git a/changelog/6316.improvement.rst b/changelog/6316.improvement.rst new file mode 100644 index 000000000..6ab7d8717 --- /dev/null +++ b/changelog/6316.improvement.rst @@ -0,0 +1 @@ +Matching of ``-k EXPRESSION`` to test names is now case-insensitive. From 623b3982b0ac8268c70d204c225893c26d7d9f38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20B=C3=BClter?= Date: Thu, 5 Dec 2019 16:59:08 +0100 Subject: [PATCH 5/8] Update doc/en/example/markers.rst Co-Authored-By: Bruno Oliveira --- doc/en/example/markers.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/en/example/markers.rst b/doc/en/example/markers.rst index e64f31fd5..e83beedd0 100644 --- a/doc/en/example/markers.rst +++ b/doc/en/example/markers.rst @@ -148,7 +148,7 @@ which implements a substring match on the test names instead of the exact match on markers that ``-m`` provides. This makes it easy to select tests based on their names: -.. versionadded: 5.3.1/6.0 +.. versionadded: 5.4 The expression matching is now case-insensitive. From a326fa22c6e5ad711ffecd3a8f9432737d0ccc1b Mon Sep 17 00:00:00 2001 From: Christoph Buelter Date: Thu, 5 Dec 2019 17:02:18 +0100 Subject: [PATCH 6/8] Add a failing test to ensure not everything matches by accident --- testing/test_collection.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/testing/test_collection.py b/testing/test_collection.py index fcbfcf5fb..e7bcb60a9 100644 --- a/testing/test_collection.py +++ b/testing/test_collection.py @@ -836,12 +836,15 @@ class TestNodekeywords: def test(self): assert True + def test_failing_5(): + assert False, "This should not match" + """ ) - num_all_tests_passed = 4 + num_matching_tests = 4 for expression in ("specifictopic", "SPECIFICTOPIC", "SpecificTopic"): reprec = testdir.inline_run("-k " + expression) - reprec.assertoutcome(passed=num_all_tests_passed, failed=0) + reprec.assertoutcome(passed=num_matching_tests, failed=0) COLLECTION_ERROR_PY_FILES = dict( From 3a0f436c1a02f41af942e2d9f3d3a64f5fff3db2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20B=C3=BClter?= Date: Fri, 6 Dec 2019 08:40:49 +0100 Subject: [PATCH 7/8] Iterate a generator expression instead of a temporary list Co-Authored-By: Bruno Oliveira --- src/_pytest/mark/legacy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_pytest/mark/legacy.py b/src/_pytest/mark/legacy.py index 651288cb8..766b8f9bd 100644 --- a/src/_pytest/mark/legacy.py +++ b/src/_pytest/mark/legacy.py @@ -63,7 +63,7 @@ class KeywordMapping: """ subname = subname.lower() - names = [name.lower() for name in self._names] + names = (name.lower() for name in self._names) for name in names: if subname in name: From c6ed69a6663657655579e76265750a6dbe9bfab9 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Fri, 6 Dec 2019 08:47:39 -0300 Subject: [PATCH 8/8] Replace 'removal' by 'breaking' changelog category As discussed, sometimes we will need to introduce changes which are not necessarily removals but might break existing suites --- .pre-commit-config.yaml | 4 ++-- changelog/{6316.improvement.rst => 6316.breaking.rst} | 0 changelog/README.rst | 2 +- pyproject.toml | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) rename changelog/{6316.improvement.rst => 6316.breaking.rst} (100%) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0c89a6272..64f3f32ac 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -53,8 +53,8 @@ repos: - id: changelogs-rst name: changelog filenames language: fail - entry: 'changelog files must be named ####.(feature|bugfix|doc|deprecation|removal|vendor|trivial).rst' - exclude: changelog/(\d+\.(feature|improvement|bugfix|doc|deprecation|removal|vendor|trivial).rst|README.rst|_template.rst) + entry: 'changelog files must be named ####.(breaking|bugfix|deprecation|doc|feature|improvement|trivial|vendor).rst' + exclude: changelog/(\d+\.(breaking|bugfix|deprecation|doc|feature|improvement|trivial|vendor).rst|README.rst|_template.rst) files: ^changelog/ - id: py-deprecated name: py library is deprecated diff --git a/changelog/6316.improvement.rst b/changelog/6316.breaking.rst similarity index 100% rename from changelog/6316.improvement.rst rename to changelog/6316.breaking.rst diff --git a/changelog/README.rst b/changelog/README.rst index adabc9ca1..dd0e7dfea 100644 --- a/changelog/README.rst +++ b/changelog/README.rst @@ -18,7 +18,7 @@ Each file should be named like ``..rst``, where * ``bugfix``: fixes a reported bug. * ``doc``: documentation improvement, like rewording an entire session or adding missing docs. * ``deprecation``: feature deprecation. -* ``removal``: feature removal. +* ``breaking``: a change which may break existing suites, such as feature removal or behavior change. * ``vendor``: changes in packages vendored in pytest. * ``trivial``: fixing a small typo or internal change that might be noteworthy. diff --git a/pyproject.toml b/pyproject.toml index 31bf3bf4b..4ac1fd754 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,8 +16,8 @@ title_format = "pytest {version} ({project_date})" template = "changelog/_template.rst" [[tool.towncrier.type]] - directory = "removal" - name = "Removals" + directory = "breaking" + name = "Breaking Changes" showcontent = true [[tool.towncrier.type]]