Repository: python/bedevere (python)

Issue:
Shouldn't Sir classify changes in test modules by "tests" label?
Now we have only this pattern:
https://github.com/python/bedevere/blob/84a2aa48abca4038086e78ea6871f68095f33647/bedevere/prtype.py#L48-L49
to trigger "tests" label.

I believe we could add also ``filepath.name.startswith("_test")`` alternative to mark so also changes in test modules.  PR examples:
* https://github.com/python/cpython/pull/111624
* https://github.com/python/cpython/pull/111591
* https://github.com/python/cpython/pull/111709

It seems to be a safe choice:
```
$ find . -name '_test*'
./Programs/_testembed.c
./PCbuild/_testconsole.vcxproj.filters
./PCbuild/_testclinic.vcxproj
./PCbuild/_testmultiphase.vcxproj
./PCbuild/_testembed.vcxproj
./PCbuild/_testimportmultiple.vcxproj.filters
./PCbuild/_testconsole.vcxproj
./PCbuild/_testbuffer.vcxproj
./PCbuild/_testsinglephase.vcxproj.filters
./PCbuild/_testmultiphase.vcxproj.filters
./PCbuild/_testimportmultiple.vcxproj
./PCbuild/_testclinic.vcxproj.filters
./PCbuild/_testbuffer.vcxproj.filters
./PCbuild/_testinternalcapi.vcxproj.filters
./PCbuild/_testinternalcapi.vcxproj
./PCbuild/_testsinglephase.vcxproj
./PCbuild/_testembed.vcxproj.filters
./PCbuild/_testclinic_limited.vcxproj.filters
./PCbuild/_testcapi.vcxproj.filters
./PCbuild/_testcapi.vcxproj
./PCbuild/_testclinic_limited.vcxproj
./Lib/test/_test_eintr.py
./Lib/test/_test_venv_multiprocessing.py
./Lib/test/test_unittest/_test_warnings.py
./Lib/test/_test_atexit.py
./Lib/test/test_zipfile/_path/_test_params.py
./Lib/test/_test_multiprocessing.py
./Lib/test/_test_embed_structseq.py
./Lib/test/_test_embed_set_config.py
./Modules/_testcapi
./Modules/_testcapi_feature_macros.inc
./Modules/_testimportmultiple.c
./Modules/_testinternalcapi
./Modules/_testmultiphase.c
./Modules/_testclinic_limited.c
./Modules/_testclinic.c
./Modules/clinic/_testclinic.c.h
./Modules/clinic/_testclinic_depr.c.h
./Modules/clinic/_testinternalcapi.c.h
./Modules/clinic/_testmultiphase.c.h
./Modules/clinic/_testclinic_limited.c.h
./Modules/_testcapimodule.c
./Modules/_testsinglephase.c
./Modules/_testinternalcapi.c
./Modules/_testbuffer.c
./PC/clinic/_testconsole.c.h
./PC/_testconsole.c
```


Pull request:
Add the "tests" label also for files, starting with "_test"
closes #605

Patch:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 27ac99b..42a684c 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -19,7 +19,7 @@ jobs:
     steps:
       - uses: actions/checkout@v4
       - name: Set up Python ${{ matrix.python-version }}
-        uses: actions/setup-python@v4
+        uses: actions/setup-python@v5
         id: python-install
         with:
           python-version: ${{ matrix.python-version }}
diff --git a/bedevere/prtype.py b/bedevere/prtype.py
index 0105e50..8f58a1c 100644
--- a/bedevere/prtype.py
+++ b/bedevere/prtype.py
@@ -43,9 +43,9 @@ async def classify_by_filepaths(gh, pull_request, filenames):
         if util.is_news_dir(filename):
             news = True
         filepath = pathlib.PurePath(filename)
-        if filepath.suffix == ".rst":
+        if filepath.suffix == ".rst" or filepath.name == ".nitignore":
             docs = True
-        elif filepath.name.startswith("test_"):
+        elif filepath.name.startswith(("test_", "_test")):
             tests = True
         else:
             return pr_labels
diff --git a/dev-requirements.txt b/dev-requirements.txt
index c543d73..1ce5352 100644
--- a/dev-requirements.txt
+++ b/dev-requirements.txt
@@ -1,6 +1,6 @@
 -r requirements.txt
 asynctest==0.13.0
-pytest==7.4.3
-pytest-asyncio==0.21.1
+pytest==7.4.4
+pytest-asyncio==0.23.2
 pytest-aiohttp==1.0.5
 pytest-cov==4.1.0
diff --git a/requirements.txt b/requirements.txt
index f011003..89ad864 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,4 @@
-aiohttp==3.9.0b0
+aiohttp==3.9.1
 appdirs==1.4.4
 async-timeout==4.0.3
 cachetools==5.3.2
@@ -9,5 +9,5 @@ packaging==23.2
 pyparsing==3.1.1
 six==1.16.0
 uritemplate==4.1.1
-yarl==1.9.2
-sentry-sdk==1.33.1
+yarl==1.9.4
+sentry-sdk==1.39.1


Test patch:
diff --git a/tests/test_prtype.py b/tests/test_prtype.py
index 4fcaf0c..8cb76da 100644
--- a/tests/test_prtype.py
+++ b/tests/test_prtype.py
@@ -85,6 +85,26 @@ async def test_docs_no_news():
     assert gh.post_data[0] == [Labels.docs.value, Labels.skip_news.value]
 
 
+async def test_docs_no_news_with_dotnitignore():
+    filenames = {"path/to/docs1.rst", "path/to/.nitignore"}
+    issue = {"labels": [], "labels_url": "https://api.github.com/some/label"}
+    gh = FakeGH(getitem=issue)
+    event_data = {
+        "action": "opened",
+        "number": 1234,
+        "pull_request": {
+            "url": "https://api.github.com/repos/cpython/python/pulls/1234",
+            "statuses_url": "https://api.github.com/some/status",
+            "issue_url": "https://api.github.com/repos/cpython/python/issue/1234",
+        },
+    }
+    await prtype.classify_by_filepaths(gh, event_data["pull_request"], filenames)
+    assert gh.getitem_url == "https://api.github.com/repos/cpython/python/issue/1234"
+    assert len(gh.post_url) == 1
+    assert gh.post_url[0] == "https://api.github.com/some/label"
+    assert gh.post_data[0] == [Labels.docs.value, Labels.skip_news.value]
+
+
 async def test_docs_and_news():
     filenames = {"/path/to/docs1.rst", f"Misc/NEWS.d/next/Lib/{GOOD_BASENAME}"}
     issue = {"labels": [], "labels_url": "https://api.github.com/some/label"}
@@ -125,6 +145,26 @@ async def test_tests_only():
     assert gh.post_data[0] == [Labels.tests.value]
 
 
+async def test_tests_and_testmods_only():
+    filenames = {"/path/to/_testmod.c", "_test_module.c", "test_capi,py"}
+    issue = {"labels": [], "labels_url": "https://api.github.com/some/label"}
+    gh = FakeGH(getitem=issue)
+    event_data = {
+        "action": "opened",
+        "number": 1234,
+        "pull_request": {
+            "url": "https://api.github.com/repos/cpython/python/pulls/1234",
+            "statuses_url": "https://api.github.com/some/status",
+            "issue_url": "https://api.github.com/repos/cpython/python/issue/1234",
+        },
+    }
+    await prtype.classify_by_filepaths(gh, event_data["pull_request"], filenames)
+    assert gh.getitem_url == "https://api.github.com/repos/cpython/python/issue/1234"
+    assert len(gh.post_url) == 1
+    assert gh.post_url[0] == "https://api.github.com/some/label"
+    assert gh.post_data[0] == [Labels.tests.value]
+
+
 async def test_docs_and_tests():
     filenames = {"/path/to/docs.rst", "test_docs2.py"}
     issue = {