Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-pytest-mypy-plugins for 
openSUSE:Factory checked in at 2026-07-17 18:47:52
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pytest-mypy-plugins (Old)
 and      /work/SRC/openSUSE:Factory/.python-pytest-mypy-plugins.new.24530 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-pytest-mypy-plugins"

Fri Jul 17 18:47:52 2026 rev:2 rq:1366401 version:4.0.3

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-pytest-mypy-plugins/python-pytest-mypy-plugins.changes
    2025-05-20 09:36:14.264559809 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-pytest-mypy-plugins.new.24530/python-pytest-mypy-plugins.changes
 2026-07-17 18:48:43.227715447 +0200
@@ -1,0 +2,18 @@
+Thu Jul 16 08:25:41 UTC 2026 - Markéta Machová <[email protected]>
+
+- Update to version 4.0.3
+  * Adds official python3.14 support
+  * Allow --mypy-testing-base to be relative by resolving
+    execution_path before cd
+  * Breaking: Errors are now ignored in site-packages by default.
+    The --mypy-only-local-stub flag has been removed and replaced
+    with --mypy-no-silence-site-packages which can be used to
+    restore the previous behavior if needed. 
+  * Breaking: When running in a subprocess (the default),
+    PYTHONPATH is no longer set. With the above change, violations
+    would still be raised in the main module for a test case, but
+    those that were flagged in imported modules would no longer be
+    raised.
+- Skip broken tests
+
+-------------------------------------------------------------------

Old:
----
  pytest_mypy_plugins-3.2.0.tar.gz

New:
----
  _scmsync.obsinfo
  build.specials.obscpio
  pytest_mypy_plugins-4.0.3.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-pytest-mypy-plugins.spec ++++++
--- /var/tmp/diff_new_pack.zMLyYe/_old  2026-07-17 18:48:44.707765435 +0200
+++ /var/tmp/diff_new_pack.zMLyYe/_new  2026-07-17 18:48:44.707765435 +0200
@@ -18,7 +18,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-pytest-mypy-plugins
-Version:        3.2.0
+Version:        4.0.3
 Release:        0
 Summary:        pytest plugin for mypy plugins
 License:        MIT
@@ -67,7 +67,10 @@
 
 %check
 export PYTHONPATH=%{buildroot}:$PYTHONPATH
-%pytest
+# mypy cache does not work in OBS environment
+rm pytest_mypy_plugins/tests/test_mypy_cache.py
+# test_no_silence_site_packages_only and 
test_no_silence_site_packages_and_modify_pythonpath fail with mypy 2.3.0 (no 
idea why it surfaces with our mypy): 
https://github.com/typeddjango/pytest-mypy-plugins/pull/201
+%pytest -k "not test_no_silence_site_packages"
 
 %files %{python_files}
 %{python_sitelib}/pytest_mypy_plugins

++++++ _scmsync.obsinfo ++++++
mtime: 1784290867
commit: cf28e2a15f17807c4f0348b1d48178fe8f2809c54129239f499cc5590a1af842
url: https://src.opensuse.org/python-pytest/python-pytest-mypy-plugins
revision: cf28e2a15f17807c4f0348b1d48178fe8f2809c54129239f499cc5590a1af842
projectscmsync: https://src.opensuse.org/python-pytest/_ObsPrj.git

++++++ build.specials.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/.gitignore new/.gitignore
--- old/.gitignore      1970-01-01 01:00:00.000000000 +0100
+++ new/.gitignore      2026-07-17 14:21:07.000000000 +0200
@@ -0,0 +1 @@
+.osc

++++++ pytest_mypy_plugins-3.2.0.tar.gz -> pytest_mypy_plugins-4.0.3.tar.gz 
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest_mypy_plugins-3.2.0/PKG-INFO 
new/pytest_mypy_plugins-4.0.3/PKG-INFO
--- old/pytest_mypy_plugins-3.2.0/PKG-INFO      2024-12-21 21:11:15.534639800 
+0100
+++ new/pytest_mypy_plugins-4.0.3/PKG-INFO      2026-05-14 09:43:07.924585000 
+0200
@@ -1,6 +1,6 @@
-Metadata-Version: 2.1
+Metadata-Version: 2.4
 Name: pytest-mypy-plugins
-Version: 3.2.0
+Version: 4.0.3
 Summary: pytest plugin for writing tests for mypy plugins
 Home-page: https://github.com/TypedDjango/pytest-mypy-plugins
 Author: Maksim Kurnikov
@@ -8,16 +8,16 @@
 Maintainer: Nikita Sobolev
 Maintainer-email: [email protected]
 License: MIT
-Classifier: Development Status :: 4 - Beta
+Classifier: Development Status :: 5 - Production/Stable
 Classifier: License :: OSI Approved :: MIT License
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.9
 Classifier: Programming Language :: Python :: 3.10
 Classifier: Programming Language :: Python :: 3.11
 Classifier: Programming Language :: Python :: 3.12
 Classifier: Programming Language :: Python :: 3.13
+Classifier: Programming Language :: Python :: 3.14
 Classifier: Typing :: Typed
-Requires-Python: >=3.9
+Requires-Python: >=3.10
 Description-Content-Type: text/markdown
 License-File: LICENSE
 Requires-Dist: Jinja2
@@ -29,6 +29,19 @@
 Requires-Dist: pyyaml
 Requires-Dist: regex
 Requires-Dist: tomlkit>=0.11
+Dynamic: author
+Dynamic: author-email
+Dynamic: classifier
+Dynamic: description
+Dynamic: description-content-type
+Dynamic: home-page
+Dynamic: license
+Dynamic: license-file
+Dynamic: maintainer
+Dynamic: maintainer-email
+Dynamic: requires-dist
+Dynamic: requires-python
+Dynamic: summary
 
 <img src="http://mypy-lang.org/static/mypy_light.svg"; alt="mypy logo" 
width="300px"/>
 
@@ -241,8 +254,12 @@
   --mypy-extension-hook=MYPY_EXTENSION_HOOK
                         Fully qualified path to the extension hook function,
                         in case you need custom yaml keys. Has to be top-level
-  --mypy-only-local-stub
-                        mypy will ignore errors from site-packages
+  --mypy-no-silence-site-packages
+                        mypy will not silence errors from site-packages
+  --mypy-modify-pythonpath
+                        When running mypy in a subprocess, modify `PYTHONPATH`
+                        to force packages to be treated as site-packages.
+                        Incompatible with `--mypy-same-process`
   --mypy-closed-schema
                         Use closed schema to validate YAML test cases,
                         which won't allow any extra keys
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest_mypy_plugins-3.2.0/README.md 
new/pytest_mypy_plugins-4.0.3/README.md
--- old/pytest_mypy_plugins-3.2.0/README.md     2024-12-21 20:37:31.000000000 
+0100
+++ new/pytest_mypy_plugins-4.0.3/README.md     2026-05-14 09:40:55.000000000 
+0200
@@ -209,8 +209,12 @@
   --mypy-extension-hook=MYPY_EXTENSION_HOOK
                         Fully qualified path to the extension hook function,
                         in case you need custom yaml keys. Has to be top-level
-  --mypy-only-local-stub
-                        mypy will ignore errors from site-packages
+  --mypy-no-silence-site-packages
+                        mypy will not silence errors from site-packages
+  --mypy-modify-pythonpath
+                        When running mypy in a subprocess, modify `PYTHONPATH`
+                        to force packages to be treated as site-packages.
+                        Incompatible with `--mypy-same-process`
   --mypy-closed-schema
                         Use closed schema to validate YAML test cases,
                         which won't allow any extra keys
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest_mypy_plugins-3.2.0/pyproject.toml 
new/pytest_mypy_plugins-4.0.3/pyproject.toml
--- old/pytest_mypy_plugins-3.2.0/pyproject.toml        2024-12-21 
21:10:55.000000000 +0100
+++ new/pytest_mypy_plugins-4.0.3/pyproject.toml        2026-05-14 
09:40:55.000000000 +0200
@@ -9,7 +9,7 @@
 
 [tool.black]
 line-length = 120
-target-version = ["py39"]
+target-version = ["py310"]
 
 [tool.isort]
 include_trailing_comma = true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest_mypy_plugins-3.2.0/pytest_mypy_plugins/collect.py 
new/pytest_mypy_plugins-4.0.3/pytest_mypy_plugins/collect.py
--- old/pytest_mypy_plugins-3.2.0/pytest_mypy_plugins/collect.py        
2024-12-21 21:10:55.000000000 +0100
+++ new/pytest_mypy_plugins-4.0.3/pytest_mypy_plugins/collect.py        
2026-05-14 09:40:55.000000000 +0200
@@ -99,7 +99,8 @@
         for title_node, _contents_node in node.value:
             if title_node.value == "main":
                 starting_line = title_node.start_mark.line + 1
-        mapping["__line__"] = starting_line
+        if "case" in mapping:
+            mapping["__line__"] = starting_line
         return mapping
 
 
@@ -204,9 +205,14 @@
         "Has to be top-level.",
     )
     group.addoption(
-        "--mypy-only-local-stub",
+        "--mypy-no-silence-site-packages",
         action="store_true",
-        help="mypy will ignore errors from site-packages",
+        help="mypy will not silence errors from site-packages",
+    )
+    group.addoption(
+        "--mypy-modify-pythonpath",
+        action="store_true",
+        help="When running mypy in a subprocess, modify `PYTHONPATH` to force 
packages to be treated as site-packages. Incompatible with 
`--mypy-same-process`",
     )
     group.addoption(
         "--mypy-closed-schema",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest_mypy_plugins-3.2.0/pytest_mypy_plugins/configs.py 
new/pytest_mypy_plugins-4.0.3/pytest_mypy_plugins/configs.py
--- old/pytest_mypy_plugins-3.2.0/pytest_mypy_plugins/configs.py        
2024-12-21 20:37:31.000000000 +0100
+++ new/pytest_mypy_plugins-4.0.3/pytest_mypy_plugins/configs.py        
2026-05-14 09:40:55.000000000 +0200
@@ -32,11 +32,11 @@
         with open(base_pyproject_toml_fpath) as f:
             toml_config = tomlkit.parse(f.read())
     else:
-        # Emtpy document with `[tool.mypy` empty table,
+        # Empty document with `[tool.mypy]` empty table,
         # useful for overrides further.
         toml_config = tomlkit.document()
 
-    if "tool" not in toml_config or "mypy" not in toml_config["tool"]:  # 
type: ignore[operator]
+    if "tool" not in toml_config or "mypy" not in toml_config["tool"]:
         tool = tomlkit.table(is_super_table=True)
         tool.append("mypy", tomlkit.table())
         toml_config.append("tool", tool)
@@ -46,15 +46,15 @@
             additional_mypy_config = 
f"{_TOML_TABLE_NAME}\n{dedent(additional_mypy_config)}"
 
         additional_data = tomlkit.parse(additional_mypy_config)
-        toml_config["tool"]["mypy"].update(  # type: ignore[index, union-attr]
-            additional_data["tool"]["mypy"].value.items(),  # type: 
ignore[index]
+        toml_config["tool"]["mypy"].update(
+            additional_data["tool"]["mypy"].value.items(),
         )
 
     mypy_config_file_path = execution_path / "pyproject.toml"
     with mypy_config_file_path.open("w") as f:
         # We don't want the whole config file, because it can contain
         # other sections like `[tool.isort]`, we only need `[tool.mypy]` part.
-        tool_mypy = toml_config["tool"]["mypy"]  # type: ignore[index]
+        tool_mypy = toml_config["tool"]["mypy"]
 
         # construct toml output
         min_toml = tomlkit.document()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest_mypy_plugins-3.2.0/pytest_mypy_plugins/item.py 
new/pytest_mypy_plugins-4.0.3/pytest_mypy_plugins/item.py
--- old/pytest_mypy_plugins-3.2.0/pytest_mypy_plugins/item.py   2024-12-21 
20:55:06.000000000 +0100
+++ new/pytest_mypy_plugins-4.0.3/pytest_mypy_plugins/item.py   2026-05-14 
09:40:55.000000000 +0200
@@ -1,3 +1,4 @@
+import glob
 import importlib
 import io
 import os
@@ -27,6 +28,7 @@
 from mypy import build
 from mypy.fscache import FileSystemCache
 from mypy.main import process_options
+from mypy.metastore import FilesystemMetadataStore, MetadataStore, 
SqliteMetadataStore
 
 from pytest_mypy_plugins import configs, utils
 from pytest_mypy_plugins.collect import File, YamlTestFile
@@ -137,17 +139,20 @@
 class MypyExecutor:
     def __init__(
         self,
+        *,
         same_process: bool,
         rootdir: Union[Path, None],
         execution_path: Path,
         environment_variables: Dict[str, Any],
         mypy_executable: str,
+        modify_pythonpath: bool,
     ) -> None:
         self.rootdir = rootdir
         self.same_process = same_process
         self.execution_path = execution_path
         self.mypy_executable = mypy_executable
         self.environment_variables = environment_variables
+        self.modify_pythonpath = modify_pythonpath
 
     def execute(self, mypy_cmd_options: List[str]) -> Tuple[int, Tuple[str, 
str]]:
         # Returns (returncode, (stdout, stderr))
@@ -157,8 +162,10 @@
             return self._typecheck_in_new_subprocess(mypy_cmd_options)
 
     def _typecheck_in_new_subprocess(self, mypy_cmd_options: List[Any]) -> 
Tuple[int, Tuple[str, str]]:
-        # add current directory to path
-        self._collect_python_path(self.rootdir)
+        if self.modify_pythonpath:
+            # add current directory to path
+            self._collect_python_path(self.rootdir)
+
         # adding proper MYPYPATH variable
         self._collect_mypy_path(self.rootdir)
 
@@ -263,7 +270,7 @@
         disable_cache: bool,
         mypy_executor: MypyExecutor,
         output_checker: OutputChecker,
-        test_only_local_stub: bool,
+        no_silence_site_packages: bool,
         incremental_cache_dir: str,
     ) -> None:
         self.files = files
@@ -273,7 +280,7 @@
         self.mypy_executor = mypy_executor
         self.disable_cache = disable_cache
         self.output_checker = output_checker
-        self.test_only_local_stub = test_only_local_stub
+        self.no_silence_site_packages = no_silence_site_packages
         self.incremental_cache_dir = incremental_cache_dir
 
     def run(self) -> None:
@@ -301,7 +308,7 @@
             "--no-pretty",
             "--hide-error-context",
         ]
-        if not self.test_only_local_stub:
+        if self.no_silence_site_packages:
             mypy_cmd_options.append("--no-silence-site-packages")
         if not self.disable_cache:
             mypy_cmd_options.extend(["--cache-dir", 
self.incremental_cache_dir])
@@ -338,7 +345,8 @@
         self.additional_mypy_config = mypy_config
         self.parsed_test_data = parsed_test_data
         self.same_process = self.config.option.mypy_same_process
-        self.test_only_local_stub = self.config.option.mypy_only_local_stub
+        self.modify_pythonpath = self.config.option.mypy_modify_pythonpath
+        self.no_silence_site_packages = 
self.config.option.mypy_no_silence_site_packages
 
         # config parameters
         self.root_directory = self.config.option.mypy_testing_base
@@ -358,25 +366,68 @@
         self.incremental_cache_dir = os.path.join(self.root_directory, 
".mypy_cache")
 
     def remove_cache_files(self, fpath_no_suffix: Path) -> None:
-        cache_file = Path(self.incremental_cache_dir)
-        cache_file /= ".".join([str(part) for part in sys.version_info[:2]])
-        for part in fpath_no_suffix.parts:
-            cache_file /= part
-
-        data_json_file = cache_file.with_suffix(".data.json")
-        if data_json_file.exists():
-            data_json_file.unlink()
-        meta_json_file = cache_file.with_suffix(".meta.json")
-        if meta_json_file.exists():
-            meta_json_file.unlink()
+        cache_dir = os.path.join(
+            self.incremental_cache_dir,
+            ".".join([str(part) for part in sys.version_info[:2]]),
+        )
+        if not os.path.isdir(cache_dir):
+            return
 
-        for parent_dir in cache_file.parents:
+        # Build entry names to remove for each path component so 
namespace-package
+        # cache entries are also cleaned (e.g. "pkg.*", "pkg/sub.*", 
"pkg/sub/mod.*").
+        suffixes = (
+            ".meta.json",
+            ".data.json",
+            ".err.json",
+            ".meta.ff",
+            ".data.ff",
+            ".err.ff",
+            # mypy >= 2.0 also writes a `.meta_ex` companion file
+            ".meta_ex.json",
+            ".meta_ex.ff",
+        )
+        entries: list[str] = []
+        accumulated = ""
+        for i, part in enumerate(fpath_no_suffix.parts):
             if (
-                parent_dir.exists()
-                and len(list(parent_dir.iterdir())) == 0
-                and str(self.incremental_cache_dir) in str(parent_dir)
+                i == 0
+                and part.endswith("-stubs")
+                and os.path.isdir(os.path.join(cache_dir, 
part.removesuffix("-stubs")))
             ):
-                parent_dir.rmdir()
+                part = part.removesuffix("-stubs")
+            accumulated = f"{accumulated}/{part}" if accumulated else part
+            entries.extend(accumulated + s for s in suffixes)
+
+        stores: list[MetadataStore] = []
+
+        # mypy >= 2.0 shards the sqlite cache across `cache.{i}.db` files 
instead of one `cache.db` file
+        # https://github.com/python/mypy/pull/21292
+        shard_dbs = glob.glob(os.path.join(cache_dir, "cache.*.db"))
+        if shard_dbs:
+            try:
+                # `num_shards` was added in mypy 2.0; pinned lint mypy is 
older.
+                stores.append(SqliteMetadataStore(cache_dir, 
num_shards=len(shard_dbs)))  # type: ignore[call-arg]
+            except TypeError:
+                # For backward compatibility with `SqliteMetadataStore` with 
no `num_shards` arg.
+                stores.append(SqliteMetadataStore(cache_dir))
+        elif os.path.isfile(os.path.join(cache_dir, "cache.db")):
+            stores.append(SqliteMetadataStore(cache_dir))
+        stores.append(FilesystemMetadataStore(cache_dir))
+
+        for store in stores:
+            try:
+                for entry in entries:
+                    try:
+                        store.remove(entry)
+                    except FileNotFoundError:
+                        pass
+                store.commit()
+            finally:
+                # ``MetadataStore.close`` was added in mypy 1.20; guard for 
older
+                # mypy versions that are still within our supported range 
(>=1.3).
+                close = getattr(store, "close", None)
+                if close is not None:
+                    close()
 
     def execute_extension_hook(self) -> None:
         extension_hook_fqname = self.config.option.mypy_extension_hook
@@ -406,7 +457,7 @@
             ):
                 self.execute_extension_hook()
 
-            execution_path = Path(temp_dir.name)
+            execution_path = Path(temp_dir.name).absolute()
             with utils.cd(execution_path):
                 mypy_executor = MypyExecutor(
                     same_process=self.same_process,
@@ -414,6 +465,7 @@
                     rootdir=rootdir,
                     environment_variables=self.environment_variables,
                     mypy_executable=mypy_executable,
+                    modify_pythonpath=self.modify_pythonpath,
                 )
 
                 output_checker = OutputChecker(
@@ -428,12 +480,12 @@
                     disable_cache=self.disable_cache,
                     mypy_executor=mypy_executor,
                     output_checker=output_checker,
-                    test_only_local_stub=self.test_only_local_stub,
+                    no_silence_site_packages=self.no_silence_site_packages,
                     incremental_cache_dir=self.incremental_cache_dir,
                 ).run()
         finally:
             temp_dir.cleanup()
-            # remove created modules
+            # remove created modules from the shared cache
             if not self.disable_cache:
                 for file in self.files:
                     path = Path(file.path)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest_mypy_plugins-3.2.0/pytest_mypy_plugins/tests/test-parametrized.yml 
new/pytest_mypy_plugins-4.0.3/pytest_mypy_plugins/tests/test-parametrized.yml
--- 
old/pytest_mypy_plugins-3.2.0/pytest_mypy_plugins/tests/test-parametrized.yml   
    2024-12-21 20:37:31.000000000 +0100
+++ 
new/pytest_mypy_plugins-4.0.3/pytest_mypy_plugins/tests/test-parametrized.yml   
    2026-05-14 09:40:55.000000000 +0200
@@ -1,9 +1,11 @@
 - case: only_main
   parametrized:
     - a: 1
-      revealed_type: builtins.int
+      revealed_type: int
     - a: 1.0
-      revealed_type: builtins.float
+      revealed_type: float
+    - a: {a: "test"}
+      revealed_type: dict[str, str]
   main: |
     a = {{ a }}
     reveal_type(a)  # N: Revealed type is "{{ revealed_type }}"
@@ -32,9 +34,9 @@
 - case: with_out
   parametrized:
     - what: cat
-      rt: builtins.str
+      rt: str
     - what: dog
-      rt: builtins.str
+      rt: str
   main: |
     animal = '{{ what }}'
     reveal_type(animal)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest_mypy_plugins-3.2.0/pytest_mypy_plugins/tests/test-regex-assertions.yml
 
new/pytest_mypy_plugins-4.0.3/pytest_mypy_plugins/tests/test-regex-assertions.yml
--- 
old/pytest_mypy_plugins-3.2.0/pytest_mypy_plugins/tests/test-regex-assertions.yml
   2024-12-21 20:37:31.000000000 +0100
+++ 
new/pytest_mypy_plugins-4.0.3/pytest_mypy_plugins/tests/test-regex-assertions.yml
   2026-05-14 09:40:55.000000000 +0200
@@ -4,7 +4,7 @@
     a = 1
     b = 'hello'
 
-    reveal_type(a)  # N: Revealed type is "builtins.int"
+    reveal_type(a)  # N: Revealed type is "int"
     reveal_type(b)  # N: .*str.*
 
 - case: expected_message_regex_with_out
@@ -61,7 +61,7 @@
 
     def foo(bar: str, ham: int = 42) -> Set[Union[str, int]]:
       return {bar, ham}
-    reveal_type(foo)  # NR: Revealed type is "def \(bar: builtins\.str, ham: 
builtins\.int =\) -> .*"
+    reveal_type(foo)  # NR: Revealed type is "def \(bar: str, ham: int =\) -> 
.*"
 
 - case: regex_against_callable_out
   regex: yes
@@ -72,4 +72,4 @@
       return {bar, ham}
     reveal_type(foo)
   out: |
-    main:5: note: Revealed type is "def \(bar: builtins\.str, ham: 
builtins\.int =\) -> .*"
+    main:5: note: Revealed type is "def \(bar: str, ham: int =\) -> .*"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest_mypy_plugins-3.2.0/pytest_mypy_plugins/tests/test-simple-cases.yml 
new/pytest_mypy_plugins-4.0.3/pytest_mypy_plugins/tests/test-simple-cases.yml
--- 
old/pytest_mypy_plugins-3.2.0/pytest_mypy_plugins/tests/test-simple-cases.yml   
    2024-12-21 20:37:31.000000000 +0100
+++ 
new/pytest_mypy_plugins-4.0.3/pytest_mypy_plugins/tests/test-simple-cases.yml   
    2026-05-14 09:40:55.000000000 +0200
@@ -6,8 +6,8 @@
     class MyClass:
         pass
 
-    reveal_type(a)  # N: Revealed type is "builtins.int"
-    reveal_type(b)  # N: Revealed type is "builtins.str"
+    reveal_type(a)  # N: Revealed type is "int"
+    reveal_type(b)  # N: Revealed type is "str"
 
 
 - case: revealed_type_with_environment
@@ -19,8 +19,8 @@
 
     b = 'hello'
 
-    reveal_type(a)  # N: Revealed type is "builtins.int"
-    reveal_type(b)  # N: Revealed type is "builtins.str"
+    reveal_type(a)  # N: Revealed type is "int"
+    reveal_type(b)  # N: Revealed type is "str"
   env:
     - DJANGO_SETTINGS_MODULE=mysettings
 
@@ -28,7 +28,7 @@
 - case: revealed_type_with_disabled_cache
   main: |
     a = 1
-    reveal_type(a)  # N: Revealed type is "builtins.int"
+    reveal_type(a)  # N: Revealed type is "int"
   disable_cache: true
 
 
@@ -37,13 +37,13 @@
     a = 1
     reveal_type(a)
   out: |
-    main:2: note: Revealed type is "builtins.int"
+    main:2: note: Revealed type is "int"
 
 
 - case: create_files
   main: |
     a = 1
-    reveal_type(a)  # N: Revealed type is "builtins.int"
+    reveal_type(a)  # N: Revealed type is "int"
   files:
     - path: myapp/__init__.py
     - path: myapp/models.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest_mypy_plugins-3.2.0/pytest_mypy_plugins/tests/test_mypy_cache.py 
new/pytest_mypy_plugins-4.0.3/pytest_mypy_plugins/tests/test_mypy_cache.py
--- old/pytest_mypy_plugins-3.2.0/pytest_mypy_plugins/tests/test_mypy_cache.py  
1970-01-01 01:00:00.000000000 +0100
+++ new/pytest_mypy_plugins-4.0.3/pytest_mypy_plugins/tests/test_mypy_cache.py  
2026-05-14 09:40:55.000000000 +0200
@@ -0,0 +1,242 @@
+import glob
+import os
+import subprocess
+from collections.abc import Generator
+from pathlib import Path
+from sys import version_info
+from tempfile import TemporaryDirectory
+
+import pytest
+from mypy.metastore import FilesystemMetadataStore, MetadataStore, 
SqliteMetadataStore
+
+
+def test_non_test_case_files_remain(temp_dir: Path) -> None:
+    """
+    Tests that cache files not associated with ``files`` in a test case do not 
get removed.
+
+    Assumes that cache files will be generated for typeshed's ``builtins.pyi`` 
when running any test case.
+    """
+
+    cache_dir = temp_dir / ".mypy_cache" / 
f"{version_info[0]}.{version_info[1]}"
+    # pytest and mypy hasn't been run yet, so no cache should exist
+    assert not cache_dir.is_dir()
+
+    make_yaml_test_file(
+        temp_dir,
+        """
+- case: test_non_test_case_files_cache_files_remain
+  main: |
+        """,
+    )
+    res = subprocess.run(
+        ["pytest", f"--mypy-testing-base={temp_dir}"], cwd=temp_dir, 
stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT
+    )
+
+    # pytest was invoked correctly and there are no failures unrelated to tests
+    assert res.returncode in (pytest.ExitCode.OK, pytest.ExitCode.TESTS_FAILED)
+    # Cache files should not be deleted
+    assert get_created_cache_files(cache_dir, ("builtins",))
+
+
+CACHE_FILES_REMOVED_TEST_DATA = {
+    "single_module_distribution": (
+        """
+- case: single_module_distribution
+  main: |
+    import my_mod
+  files:
+    - path: my_mod.py
+        """,
+        ("my_mod",),
+    ),
+    "standard_package": (
+        """
+- case: standard_package
+  main: |
+    import my_pkg.my_mod
+    import my_pkg.my_subpkg.my_mod
+  files:
+    - path: my_pkg/__init__.py
+    - path: my_pkg/my_mod.py
+    - path: my_pkg/my_subpkg/__init__.py
+    - path: my_pkg/my_subpkg/my_mod.py
+        """,
+        ("my_pkg/__init__", "my_pkg/my_mod", "my_pkg/my_subpkg/__init__", 
"my_pkg/my_subpkg/my_mod"),
+    ),
+    "namespace_package": (
+        """
+- case: namespace_package
+  main: |
+    import my_nspkg.my_mod
+    import my_nspkg.my_nssubpkg.my_mod
+  files:
+    - path: my_nspkg/my_mod.py
+    - path: my_nspkg/my_nssubpkg/my_mod.py
+        """,
+        ("my_nspkg", "my_nspkg/my_mod", "my_nspkg/my_nssubpkg", 
"my_nspkg/my_nssubpkg/my_mod"),
+    ),
+    "standard_stub_package": (
+        """
+- case: standard_stub_package
+  main: |
+    import my_pkg.my_mod
+    import my_pkg.my_subpkg.my_mod
+  files:
+    - path: my_pkg-stubs/__init__.pyi
+    - path: my_pkg-stubs/my_mod.pyi
+    - path: my_pkg-stubs/my_subpkg/__init__.pyi
+    - path: my_pkg-stubs/my_subpkg/my_mod.pyi
+        """,
+        ("my_pkg/__init__", "my_pkg/my_mod", "my_pkg/my_subpkg/__init__", 
"my_pkg/my_subpkg/my_mod"),
+    ),
+    "namespace_stub_package": (
+        """
+- case: namespace_stub_package
+  main: |
+    import my_nspkg.my_mod
+    import my_nspkg.my_nssubpkg.my_mod
+  files:
+    - path: my_nspkg-stubs/my_mod.pyi
+    - path: my_nspkg-stubs/my_nssubpkg/my_mod.pyi
+        """,
+        ("my_nspkg", "my_nspkg/my_mod", "my_nspkg/my_nssubpkg", 
"my_nspkg/my_nssubpkg/my_mod"),
+    ),
+    "mixed_modules_and_packages": (
+        """
+- case: mixed_modules_and_packages
+  main: |
+    import my_mod
+    import my_pkg.my_submod
+    import my_pkg.my_nssubpkg.my_submod
+    import my_nspkg.my_submod
+    import my_nspkg.my_subpkg
+    import my_stubpkg.my_submod
+    import my_stubpkg.my_subpkg.my_submod
+    import my_nsstubpkg.my_subpkg
+  files:
+  - path: my_mod.py
+  - path: my_pkg/__init__.py
+  - path: my_pkg/my_submod.pyi
+  - path: my_pkg/my_nssubpkg/my_submod.pyi
+  - path: my_nspkg/my_submod.pyi
+  - path: my_nspkg/my_subpkg/__init__.py
+  - path: my_stubpkg-stubs/__init__.pyi
+  - path: my_stubpkg-stubs/my_submod.pyi
+  - path: my_stubpkg-stubs/my_subpkg/my_submod.pyi
+  - path: my_nsstubpkg-stubs/my_subpkg/__init__.pyi
+        """,
+        (
+            "my_mod",
+            "my_pkg/__init__",
+            "my_pkg/my_submod",
+            "my_pkg/my_nssubpkg",
+            "my_pkg/my_nssubpkg/my_submod",
+            "my_nspkg",
+            "my_nspkg/my_submod",
+            "my_nspkg/my_subpkg",
+            "my_nspkg/my_subpkg/__init__",
+            "my_stubpkg/__init__",
+            "my_stubpkg/my_submod",
+            "my_stubpkg/my_subpkg",
+            "my_stubpkg/my_subpkg/my_submod",
+            "my_nsstubpkg",
+            "my_nsstubpkg/my_subpkg/__init__",
+        ),
+    ),
+}
+
+
[email protected](
+    "mypy_cache_config",
+    [
+        pytest.param("", id="default"),
+        pytest.param("sqlite_cache = False\n", id="no-sqlite"),
+        pytest.param("fixed_format_cache = False\n", id="no-fixed-format"),
+        pytest.param("sqlite_cache = False\nfixed_format_cache = False\n", 
id="legacy"),
+    ],
+)
[email protected](
+    ("contents", "module_fpaths_no_suffix"),
+    CACHE_FILES_REMOVED_TEST_DATA.values(),
+    ids=CACHE_FILES_REMOVED_TEST_DATA.keys(),
+)
+def test_cache_files_removed(
+    temp_dir: Path, contents: str, module_fpaths_no_suffix: tuple[str, ...], 
mypy_cache_config: str
+) -> None:
+    """Tests that cache files associated with ``files`` in a test case get 
removed"""
+
+    cache_dir = temp_dir / ".mypy_cache" / 
f"{version_info[0]}.{version_info[1]}"
+    # pytest and mypy hasn't been run yet, so no cache should exist
+    assert not cache_dir.is_dir()
+
+    if mypy_cache_config:
+        config_lines = mypy_cache_config.strip().splitlines()
+        indented = "\n".join(f"    {line}" for line in config_lines)
+        contents = contents.replace("  main: |", f"  mypy_config: 
|\n{indented}\n  main: |")
+
+    make_yaml_test_file(temp_dir, contents)
+    res = subprocess.run(
+        ["pytest", f"--mypy-testing-base={temp_dir}"], cwd=temp_dir, 
stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT
+    )
+
+    # pytest was invoked correctly and there are no failures unrelated to tests
+    assert res.returncode in (pytest.ExitCode.OK, pytest.ExitCode.TESTS_FAILED)
+    # Cache files exist but test case cache files are removed
+    assert get_created_cache_files(cache_dir, ("builtins",))
+    assert not get_created_cache_files(cache_dir, module_fpaths_no_suffix)
+
+
[email protected]
+def temp_dir() -> Generator[Path]:
+    """
+    Create a temporary directory to run each test case in an isolated process.
+
+    Test files and the mypy cache is expected to be created in this temporary 
directory, and is deleted upon test case
+    completion.
+    """
+
+    with TemporaryDirectory() as d:
+        yield Path(d)
+
+
+def make_yaml_test_file(
+    root_dir: Path,
+    contents: str,
+    /,
+    *,
+    file_base_name: str = "test-case",
+) -> str:
+    path = root_dir / f"{file_base_name}.yml"
+    path.write_text(contents)
+    return str(path)
+
+
+def get_created_cache_files(cache_dir: Path, module_rel_paths_no_suffix: 
tuple[str, ...]) -> list[str]:
+    stores: list[MetadataStore] = []
+    cache_dir_str = str(cache_dir)
+    # mypy >= 2.0 shards the sqlite cache across `cache.{i}.db` files instead 
of one `cache.db` file
+    shard_dbs = glob.glob(os.path.join(cache_dir_str, "cache.*.db"))
+    if shard_dbs:
+        try:
+            # `num_shards` was added in mypy 2.0; pinned lint mypy is older.
+            stores.append(SqliteMetadataStore(cache_dir_str, 
num_shards=len(shard_dbs)))  # type: ignore[call-arg]
+        except TypeError:
+            stores.append(SqliteMetadataStore(cache_dir_str))
+    elif (cache_dir / "cache.db").is_file():
+        stores.append(SqliteMetadataStore(cache_dir_str))
+    if cache_dir.is_dir():
+        stores.append(FilesystemMetadataStore(cache_dir_str))
+
+    created = []
+    for store in stores:
+        try:
+            for entry in store.list_all():
+                if any(os.path.normpath(entry).startswith(rel_path + ".") for 
rel_path in module_rel_paths_no_suffix):
+                    created.append(entry)
+        finally:
+            # See PR #188: mypy < 1.20 does not have MetadataStore.close
+            close = getattr(store, "close", None)
+            if close is not None:
+                close()
+
+    return created
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest_mypy_plugins-3.2.0/pytest_mypy_plugins/tests/test_site_packages.py 
new/pytest_mypy_plugins-4.0.3/pytest_mypy_plugins/tests/test_site_packages.py
--- 
old/pytest_mypy_plugins-3.2.0/pytest_mypy_plugins/tests/test_site_packages.py   
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/pytest_mypy_plugins-4.0.3/pytest_mypy_plugins/tests/test_site_packages.py   
    2026-05-14 09:40:55.000000000 +0200
@@ -0,0 +1,161 @@
+import os.path
+import site
+import subprocess
+from pathlib import Path
+
+import pytest
+
+
+def test_default(tmp_path: Path) -> None:
+    make_yaml_test_file(
+        tmp_path,
+        """
+- case: test_non_test_case_files_cache_files_remain
+  mypy_config: |
+    strict=true
+  main: |
+    import subpkg
+
+    a: str
+    a / 2
+  files:
+    - path: subpkg.py
+      content: |
+        a: str
+        a / 2
+  out: |
+    main:4: error: Unsupported operand types for / ("str" and "int")  
[operator]
+    subpkg:2: error: Unsupported operand types for / ("str" and "int")  
[operator]
+        """,
+    )
+    res = subprocess.run(
+        [
+            "pytest",
+            f"--mypy-testing-base={tmp_path}",
+        ],
+        cwd=tmp_path,
+        stdout=subprocess.DEVNULL,
+        stderr=subprocess.STDOUT,
+    )
+    assert res.returncode == pytest.ExitCode.OK
+
+
+def test_modify_pythonpath_only(tmp_path: Path) -> None:
+    make_yaml_test_file(
+        tmp_path,
+        """
+- case: test_non_test_case_files_cache_files_remain
+  mypy_config: |
+    strict=true
+  main: |
+    import subpkg
+
+    a: str
+    a / 2
+  files:
+    - path: subpkg.py
+      content: |
+        a: str
+        a / 2  # Modifying `PYTHONPATH` causes this to not raise an error as 
expected.
+  out: |
+    main:4: error: Unsupported operand types for / ("str" and "int")  
[operator]
+        """,
+    )
+    res = subprocess.run(
+        [
+            "pytest",
+            f"--mypy-testing-base={tmp_path}",
+            "--mypy-modify-pythonpath",
+        ],
+        cwd=tmp_path,
+        stdout=subprocess.DEVNULL,
+        stderr=subprocess.STDOUT,
+    )
+    assert res.returncode == pytest.ExitCode.OK
+
+
+def test_no_silence_site_packages_only(tmp_path: Path) -> None:
+    make_yaml_test_file(
+        tmp_path,
+        """
+- case: test_non_test_case_files_cache_files_remain
+  mypy_config: |
+    strict=true
+  main: |
+    import subpkg
+
+    a: str
+    a / 2
+  files:
+    - path: subpkg.py
+      content: |
+        a: str
+        a / 2
+  out: |
+    {site_packages_path}/mypy/typeshed/stdlib/types.pyi:716: error: Class 
cannot subclass "Any" (has type "Any")  [misc]
+    main:4: error: Unsupported operand types for / ("str" and "int")  
[operator]
+    subpkg:2: error: Unsupported operand types for / ("str" and "int")  
[operator]
+        """,
+    )
+    res = subprocess.run(
+        [
+            "pytest",
+            f"--mypy-testing-base={tmp_path}",
+            "--mypy-no-silence-site-packages",
+        ],
+        cwd=tmp_path,
+        stdout=subprocess.DEVNULL,
+        stderr=subprocess.STDOUT,
+    )
+    assert res.returncode == pytest.ExitCode.OK
+
+
+def test_no_silence_site_packages_and_modify_pythonpath(tmp_path: Path) -> 
None:
+    make_yaml_test_file(
+        tmp_path,
+        """
+- case: test_non_test_case_files_cache_files_remain
+  mypy_config: |
+    strict=true
+  main: |
+    import subpkg
+
+    a: str
+    a / 2
+  files:
+    - path: subpkg.py
+      content: |
+        a: str
+        a / 2
+  out: |
+    {site_packages_path}/mypy/typeshed/stdlib/types.pyi:716: error: Class 
cannot subclass "Any" (has type "Any")  [misc]
+    main:4: error: Unsupported operand types for / ("str" and "int")  
[operator]
+    subpkg:2: error: Unsupported operand types for / ("str" and "int")  
[operator]
+        """,
+    )
+    res = subprocess.run(
+        [
+            "pytest",
+            f"--mypy-testing-base={tmp_path}",
+            "--mypy-no-silence-site-packages",
+            "--mypy-modify-pythonpath",
+        ],
+        cwd=tmp_path,
+        stdout=subprocess.DEVNULL,
+        stderr=subprocess.STDOUT,
+    )
+    assert res.returncode == pytest.ExitCode.OK
+
+
+def make_yaml_test_file(
+    root_dir: Path,
+    contents: str,
+    /,
+    *,
+    file_base_name: str = "test-case",
+) -> None:
+    output_path = root_dir.joinpath(file_base_name).with_suffix(".yml")
+    site_packages_path: Path | str = Path(site.getsitepackages()[0])
+    site_packages_path = os.path.relpath(site_packages_path, start=output_path)
+    contents = contents.format(site_packages_path=site_packages_path)
+    output_path.write_text(contents)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest_mypy_plugins-3.2.0/pytest_mypy_plugins.egg-info/PKG-INFO 
new/pytest_mypy_plugins-4.0.3/pytest_mypy_plugins.egg-info/PKG-INFO
--- old/pytest_mypy_plugins-3.2.0/pytest_mypy_plugins.egg-info/PKG-INFO 
2024-12-21 21:11:15.000000000 +0100
+++ new/pytest_mypy_plugins-4.0.3/pytest_mypy_plugins.egg-info/PKG-INFO 
2026-05-14 09:43:07.000000000 +0200
@@ -1,6 +1,6 @@
-Metadata-Version: 2.1
+Metadata-Version: 2.4
 Name: pytest-mypy-plugins
-Version: 3.2.0
+Version: 4.0.3
 Summary: pytest plugin for writing tests for mypy plugins
 Home-page: https://github.com/TypedDjango/pytest-mypy-plugins
 Author: Maksim Kurnikov
@@ -8,16 +8,16 @@
 Maintainer: Nikita Sobolev
 Maintainer-email: [email protected]
 License: MIT
-Classifier: Development Status :: 4 - Beta
+Classifier: Development Status :: 5 - Production/Stable
 Classifier: License :: OSI Approved :: MIT License
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.9
 Classifier: Programming Language :: Python :: 3.10
 Classifier: Programming Language :: Python :: 3.11
 Classifier: Programming Language :: Python :: 3.12
 Classifier: Programming Language :: Python :: 3.13
+Classifier: Programming Language :: Python :: 3.14
 Classifier: Typing :: Typed
-Requires-Python: >=3.9
+Requires-Python: >=3.10
 Description-Content-Type: text/markdown
 License-File: LICENSE
 Requires-Dist: Jinja2
@@ -29,6 +29,19 @@
 Requires-Dist: pyyaml
 Requires-Dist: regex
 Requires-Dist: tomlkit>=0.11
+Dynamic: author
+Dynamic: author-email
+Dynamic: classifier
+Dynamic: description
+Dynamic: description-content-type
+Dynamic: home-page
+Dynamic: license
+Dynamic: license-file
+Dynamic: maintainer
+Dynamic: maintainer-email
+Dynamic: requires-dist
+Dynamic: requires-python
+Dynamic: summary
 
 <img src="http://mypy-lang.org/static/mypy_light.svg"; alt="mypy logo" 
width="300px"/>
 
@@ -241,8 +254,12 @@
   --mypy-extension-hook=MYPY_EXTENSION_HOOK
                         Fully qualified path to the extension hook function,
                         in case you need custom yaml keys. Has to be top-level
-  --mypy-only-local-stub
-                        mypy will ignore errors from site-packages
+  --mypy-no-silence-site-packages
+                        mypy will not silence errors from site-packages
+  --mypy-modify-pythonpath
+                        When running mypy in a subprocess, modify `PYTHONPATH`
+                        to force packages to be treated as site-packages.
+                        Incompatible with `--mypy-same-process`
   --mypy-closed-schema
                         Use closed schema to validate YAML test cases,
                         which won't allow any extra keys
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pytest_mypy_plugins-3.2.0/pytest_mypy_plugins.egg-info/SOURCES.txt 
new/pytest_mypy_plugins-4.0.3/pytest_mypy_plugins.egg-info/SOURCES.txt
--- old/pytest_mypy_plugins-3.2.0/pytest_mypy_plugins.egg-info/SOURCES.txt      
2024-12-21 21:11:15.000000000 +0100
+++ new/pytest_mypy_plugins-4.0.3/pytest_mypy_plugins.egg-info/SOURCES.txt      
2026-05-14 09:43:07.000000000 +0200
@@ -28,6 +28,8 @@
 pytest_mypy_plugins/tests/test-simple-cases.yml
 pytest_mypy_plugins/tests/test_explicit_configs.py
 pytest_mypy_plugins/tests/test_input_schema.py
+pytest_mypy_plugins/tests/test_mypy_cache.py
+pytest_mypy_plugins/tests/test_site_packages.py
 pytest_mypy_plugins/tests/test_utils.py
 pytest_mypy_plugins/tests/test_configs/mypy1.ini
 pytest_mypy_plugins/tests/test_configs/mypy2.ini
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest_mypy_plugins-3.2.0/requirements.txt 
new/pytest_mypy_plugins-4.0.3/requirements.txt
--- old/pytest_mypy_plugins-3.2.0/requirements.txt      2024-12-21 
21:10:55.000000000 +0100
+++ new/pytest_mypy_plugins-4.0.3/requirements.txt      2026-05-14 
09:40:55.000000000 +0200
@@ -4,5 +4,5 @@
 types-PyYAML
 types-setuptools
 types-regex
-mypy==1.13
+mypy==1.20.2
 -e .
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest_mypy_plugins-3.2.0/setup.py 
new/pytest_mypy_plugins-4.0.3/setup.py
--- old/pytest_mypy_plugins-3.2.0/setup.py      2024-12-21 21:10:55.000000000 
+0100
+++ new/pytest_mypy_plugins-4.0.3/setup.py      2026-05-14 09:41:41.000000000 
+0200
@@ -17,7 +17,7 @@
 
 setup(
     name="pytest-mypy-plugins",
-    version="3.2.0",
+    version="4.0.3",
     description="pytest plugin for writing tests for mypy plugins",
     long_description=readme,
     long_description_content_type="text/markdown",
@@ -31,19 +31,19 @@
     # the following makes a plugin available to pytest
     entry_points={"pytest11": ["pytest-mypy-plugins = 
pytest_mypy_plugins.collect"]},
     install_requires=dependencies,
-    python_requires=">=3.9",
+    python_requires=">=3.10",
     package_data={
         "pytest_mypy_plugins": ["py.typed", "schema.json"],
     },
     classifiers=[
-        "Development Status :: 4 - Beta",
+        "Development Status :: 5 - Production/Stable",
         "License :: OSI Approved :: MIT License",
         "Programming Language :: Python :: 3",
-        "Programming Language :: Python :: 3.9",
         "Programming Language :: Python :: 3.10",
         "Programming Language :: Python :: 3.11",
         "Programming Language :: Python :: 3.12",
         "Programming Language :: Python :: 3.13",
+        "Programming Language :: Python :: 3.14",
         "Typing :: Typed",
     ],
 )

Reply via email to