Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-typeguard for
openSUSE:Factory checked in at 2025-03-06 14:48:09
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-typeguard (Old)
and /work/SRC/openSUSE:Factory/.python-typeguard.new.19136 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-typeguard"
Thu Mar 6 14:48:09 2025 rev:9 rq:1250003 version:4.4.2
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-typeguard/python-typeguard.changes
2024-11-21 15:13:54.553685669 +0100
+++
/work/SRC/openSUSE:Factory/.python-typeguard.new.19136/python-typeguard.changes
2025-03-06 14:48:35.341088108 +0100
@@ -1,0 +2,17 @@
+Tue Mar 4 09:14:50 UTC 2025 - Nico Krapp <[email protected]>
+
+- drop unneeded dependency
+
+-------------------------------------------------------------------
+Fri Feb 28 09:51:28 UTC 2025 - John Paul Adrian Glaubitz
<[email protected]>
+
+- Update to 4.4.2
+ * Fixed ``TypeCheckError`` in unpacking assignment involving
+ properties of a parameter of the function
+ * Fixed display of module name for forward references
+ * Fixed ``TypeError`` when using an assignment expression
+ * Fixed ``ValueError: no signature found for builtin`` when
+ checking against a protocol and a matching attribute in the
+ subject is a built-in function
+
+-------------------------------------------------------------------
Old:
----
typeguard-4.4.1-gh.tar.gz
New:
----
typeguard-4.4.2-gh.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-typeguard.spec ++++++
--- /var/tmp/diff_new_pack.pI4pOB/_old 2025-03-06 14:48:37.313170810 +0100
+++ /var/tmp/diff_new_pack.pI4pOB/_new 2025-03-06 14:48:37.317170977 +0100
@@ -1,7 +1,7 @@
#
# spec file for package python-typeguard
#
-# Copyright (c) 2024 SUSE LLC
+# Copyright (c) 2025 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
%{?sle15_python_module_pythons}
Name: python-typeguard
-Version: 4.4.1
+Version: 4.4.2
Release: 0
Summary: Library for runtime checking of Python types
License: MIT
@@ -33,7 +33,6 @@
BuildRequires: fdupes
BuildRequires: python-rpm-macros
BuildArch: noarch
-Requires: python-importlib-metadata >= 3.6
Requires: python-typing-extensions >= 4.10.0
%python_subpackages
++++++ typeguard-4.4.1-gh.tar.gz -> typeguard-4.4.2-gh.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/typeguard-4.4.1/.github/workflows/test.yml
new/typeguard-4.4.2/.github/workflows/test.yml
--- old/typeguard-4.4.1/.github/workflows/test.yml 2024-11-03
13:04:35.000000000 +0100
+++ new/typeguard-4.4.2/.github/workflows/test.yml 2025-02-16
17:27:08.000000000 +0100
@@ -10,7 +10,7 @@
strategy:
fail-fast: false
matrix:
- python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", pypy-3.10]
+ python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14",
pypy-3.10]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/typeguard-4.4.1/.pre-commit-config.yaml
new/typeguard-4.4.2/.pre-commit-config.yaml
--- old/typeguard-4.4.1/.pre-commit-config.yaml 2024-11-03 13:04:35.000000000
+0100
+++ new/typeguard-4.4.2/.pre-commit-config.yaml 2025-02-16 17:27:08.000000000
+0100
@@ -14,14 +14,14 @@
- id: trailing-whitespace
- repo: https://github.com/astral-sh/ruff-pre-commit
- rev: v0.7.2
+ rev: v0.8.6
hooks:
- id: ruff
args: [--fix, --show-fixes]
- id: ruff-format
- repo: https://github.com/pre-commit/mirrors-mypy
- rev: v1.13.0
+ rev: v1.14.1
hooks:
- id: mypy
additional_dependencies: [ "typing_extensions" ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/typeguard-4.4.1/docs/versionhistory.rst
new/typeguard-4.4.2/docs/versionhistory.rst
--- old/typeguard-4.4.1/docs/versionhistory.rst 2024-11-03 13:04:35.000000000
+0100
+++ new/typeguard-4.4.2/docs/versionhistory.rst 2025-02-16 17:27:08.000000000
+0100
@@ -4,6 +4,19 @@
This library adheres to
`Semantic Versioning 2.0 <https://semver.org/#semantic-versioning-200>`_.
+**4.4.2** (2025-02-16)
+
+- Fixed ``TypeCheckError`` in unpacking assignment involving properties of a
parameter
+ of the function (`#506 <https://github.com/agronholm/typeguard/issues/506>`_;
+ regression introduced in v4.4.1)
+- Fixed display of module name for forward references
+ (`#492 <https://github.com/agronholm/typeguard/pull/492>`_; PR by
@JelleZijlstra)
+- Fixed ``TypeError`` when using an assignment expression
+ (`#510 <https://github.com/agronholm/typeguard/issues/510>`_; PR by
@JohannesK71083)
+- Fixed ``ValueError: no signature found for builtin`` when checking against a
protocol
+ and a matching attribute in the subject is a built-in function
+ (`#504 <https://github.com/agronholm/typeguard/issues/504>`_)
+
**4.4.1** (2024-11-03)
- Dropped Python 3.8 support
@@ -22,9 +35,6 @@
- Fixed checks against annotations wrapped in ``NotRequired`` not being run
unless the
``NotRequired`` is a forward reference
(`#454 <https://github.com/agronholm/typeguard/issues/454>`_)
-- Fixed the ``pytest_ignore_collect`` hook in the pytest plugin blocking
default pytest
- collection ignoring behavior by returning ``None`` instead of ``False``
- (PR by @mgorny)
**4.4.0** (2024-10-27)
@@ -32,8 +42,6 @@
(`#465 <https://github.com/agronholm/typeguard/pull/465>`_)
- Fixed basic support for intersection protocols
(`#490 <https://github.com/agronholm/typeguard/pull/490>`_; PR by
@antonagestam)
-- Fixed protocol checks running against the class of an instance and not the
instance
- itself (this produced wrong results for non-method member checks)
**4.3.0** (2024-05-27)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/typeguard-4.4.1/pyproject.toml
new/typeguard-4.4.2/pyproject.toml
--- old/typeguard-4.4.1/pyproject.toml 2024-11-03 13:04:35.000000000 +0100
+++ new/typeguard-4.4.2/pyproject.toml 2025-02-16 17:27:08.000000000 +0100
@@ -22,6 +22,7 @@
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
]
requires-python = ">= 3.9"
dependencies = [
@@ -99,7 +100,7 @@
pretty = true
[tool.tox]
-env_list = ["py39", "py310", "py311", "py312", "py313"]
+env_list = ["py39", "py310", "py311", "py312", "py313", "py314"]
skip_missing_interpreters = true
[tool.tox.env_run_base]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/typeguard-4.4.1/src/typeguard/_checkers.py
new/typeguard-4.4.2/src/typeguard/_checkers.py
--- old/typeguard-4.4.1/src/typeguard/_checkers.py 2024-11-03
13:04:35.000000000 +0100
+++ new/typeguard-4.4.2/src/typeguard/_checkers.py 2025-02-16
17:27:08.000000000 +0100
@@ -533,7 +533,7 @@
) -> None:
if origin_type.__bound__ is not None:
annotation = (
- Type[origin_type.__bound__] if subclass_check else
origin_type.__bound__
+ type[origin_type.__bound__] if subclass_check else
origin_type.__bound__
)
check_type_internal(value, annotation, memo)
elif origin_type.__constraints__:
@@ -648,7 +648,12 @@
def check_signature_compatible(subject: type, protocol: type, attrname: str)
-> None:
- subject_sig = inspect.signature(getattr(subject, attrname))
+ subject_attr = getattr(subject, attrname)
+ try:
+ subject_sig = inspect.signature(subject_attr)
+ except ValueError:
+ return # this can happen with builtins where the signature cannot be
retrieved
+
protocol_sig = inspect.signature(getattr(protocol, attrname))
protocol_type: typing.Literal["instance", "class", "static"] = "instance"
subject_type: typing.Literal["instance", "class", "static"] = "instance"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/typeguard-4.4.1/src/typeguard/_decorators.py
new/typeguard-4.4.2/src/typeguard/_decorators.py
--- old/typeguard-4.4.1/src/typeguard/_decorators.py 2024-11-03
13:04:35.000000000 +0100
+++ new/typeguard-4.4.2/src/typeguard/_decorators.py 2025-02-16
17:27:08.000000000 +0100
@@ -117,7 +117,10 @@
new_function.__module__ = f.__module__
new_function.__name__ = f.__name__
new_function.__qualname__ = f.__qualname__
- new_function.__annotations__ = f.__annotations__
+ if sys.version_info >= (3, 14):
+ new_function.__annotate__ = f.__annotate__
+ else:
+ new_function.__annotations__ = f.__annotations__
new_function.__doc__ = f.__doc__
new_function.__defaults__ = f.__defaults__
new_function.__kwdefaults__ = f.__kwdefaults__
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/typeguard-4.4.1/src/typeguard/_transformer.py
new/typeguard-4.4.2/src/typeguard/_transformer.py
--- old/typeguard-4.4.1/src/typeguard/_transformer.py 2024-11-03
13:04:35.000000000 +0100
+++ new/typeguard-4.4.2/src/typeguard/_transformer.py 2025-02-16
17:27:08.000000000 +0100
@@ -1073,8 +1073,9 @@
path.insert(0, exp.id)
name = prefix + ".".join(path)
- annotation =
self._memo.variable_annotations.get(exp.id)
- if annotation:
+ if len(path) == 1 and (
+ annotation :=
self._memo.variable_annotations.get(exp.id)
+ ):
annotations_.append((Constant(name), annotation))
check_required = True
else:
@@ -1137,8 +1138,20 @@
func_name,
[
node.value,
- Constant(node.target.id),
- annotation,
+ List(
+ [
+ List(
+ [
+ Tuple(
+ [Constant(node.target.id), annotation],
+ ctx=Load(),
+ )
+ ],
+ ctx=Load(),
+ )
+ ],
+ ctx=Load(),
+ ),
self._memo.get_memo_name(),
],
[],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/typeguard-4.4.1/src/typeguard/_utils.py
new/typeguard-4.4.2/src/typeguard/_utils.py
--- old/typeguard-4.4.1/src/typeguard/_utils.py 2024-11-03 13:04:35.000000000
+0100
+++ new/typeguard-4.4.2/src/typeguard/_utils.py 2025-02-16 17:27:08.000000000
+0100
@@ -11,7 +11,15 @@
if TYPE_CHECKING:
from ._memo import TypeCheckMemo
-if sys.version_info >= (3, 13):
+if sys.version_info >= (3, 14):
+ from typing import get_args, get_origin
+
+ def evaluate_forwardref(forwardref: ForwardRef, memo: TypeCheckMemo) ->
Any:
+ return forwardref.evaluate(
+ globals=memo.globals, locals=memo.locals, type_params=()
+ )
+
+elif sys.version_info >= (3, 13):
from typing import get_args, get_origin
def evaluate_forwardref(forwardref: ForwardRef, memo: TypeCheckMemo) ->
Any:
@@ -85,7 +93,11 @@
name += f"[{formatted_args}]"
- module = getattr(type_, "__module__", None)
+ # For ForwardRefs, use the module stored on the object if available
+ if hasattr(type_, "__forward_module__"):
+ module = type_.__forward_module__
+ else:
+ module = getattr(type_, "__module__", None)
if module and module not in (None, "typing", "typing_extensions",
"builtins"):
name = module + "." + name
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/typeguard-4.4.1/tests/deferredannos.py
new/typeguard-4.4.2/tests/deferredannos.py
--- old/typeguard-4.4.1/tests/deferredannos.py 1970-01-01 01:00:00.000000000
+0100
+++ new/typeguard-4.4.2/tests/deferredannos.py 2025-02-16 17:27:08.000000000
+0100
@@ -0,0 +1,10 @@
+from typeguard import typechecked
+
+
+@typechecked
+def uses_forwardref(x: NotYetDefined) -> NotYetDefined: # noqa: F821
+ return x
+
+
+class NotYetDefined:
+ pass
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/typeguard-4.4.1/tests/dummymodule.py
new/typeguard-4.4.2/tests/dummymodule.py
--- old/typeguard-4.4.1/tests/dummymodule.py 2024-11-03 13:04:35.000000000
+0100
+++ new/typeguard-4.4.2/tests/dummymodule.py 2025-02-16 17:27:08.000000000
+0100
@@ -74,6 +74,9 @@
@typechecked
class DummyClass(metaclass=Metaclass):
+ bar: str
+ baz: int
+
def type_checked_method(self, x: int, y: int) -> int:
return x * y
@@ -270,6 +273,11 @@
return x, y, z
+@typechecked
+def attribute_assign_unpacking(obj: DummyClass) -> None:
+ obj.bar, obj.baz = "foo", 123123
+
+
@typechecked(forward_ref_policy=ForwardRefPolicy.ERROR)
def override_forward_ref_policy(value: "NonexistentType") -> None: # noqa:
F821
pass
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/typeguard-4.4.1/tests/mypy/test_type_annotations.py
new/typeguard-4.4.2/tests/mypy/test_type_annotations.py
--- old/typeguard-4.4.1/tests/mypy/test_type_annotations.py 2024-11-03
13:04:35.000000000 +0100
+++ new/typeguard-4.4.2/tests/mypy/test_type_annotations.py 2025-02-16
17:27:08.000000000 +0100
@@ -1,14 +1,12 @@
+import json
import os
import platform
-import re
import subprocess
-from typing import Dict, List
import pytest
POSITIVE_FILE = "positive.py"
NEGATIVE_FILE = "negative.py"
-LINE_PATTERN = NEGATIVE_FILE + ":([0-9]+):"
pytestmark = [
pytest.mark.skipif(
@@ -18,8 +16,8 @@
]
-def get_mypy_cmd(filename: str) -> List[str]:
- return ["mypy", "--strict", filename]
+def get_mypy_cmd(filename: str) -> list[str]:
+ return ["mypy", "-O", "json", "--strict", filename]
def get_negative_mypy_output() -> str:
@@ -34,7 +32,7 @@
return output
-def get_expected_errors() -> Dict[int, str]:
+def get_expected_errors() -> dict[int, str]:
"""
Extract the expected errors from comments in the negative examples file.
"""
@@ -46,14 +44,14 @@
for idx, line in enumerate(lines):
line = line.rstrip()
if "# error" in line:
- expected[idx + 1] = line[line.index("# error") + 2 :]
+ expected[idx + 1] = line[line.index("# error") + 9 :]
# Sanity check. Should update if negative.py changes.
assert len(expected) == 9
return expected
-def get_mypy_errors() -> Dict[int, str]:
+def get_mypy_errors() -> dict[int, str]:
"""
Extract the errors from running mypy on the negative examples file.
"""
@@ -61,10 +59,8 @@
got = {}
for line in mypy_output.splitlines():
- m = re.match(LINE_PATTERN, line)
- if m is None:
- continue
- got[int(m.group(1))] = line[len(m.group(0)) + 1 :]
+ error = json.loads(line)
+ got[error["line"]] = f"{error['message']} [{error['code']}]"
return got
@@ -109,5 +105,6 @@
]
for idx, expected, got in mismatches:
print(f"Line {idx}", f"Expected: {expected}", f"Got: {got}",
sep="\n\t")
+
if mismatches:
raise RuntimeError("Error messages changed")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/typeguard-4.4.1/tests/test_checkers.py
new/typeguard-4.4.2/tests/test_checkers.py
--- old/typeguard-4.4.1/tests/test_checkers.py 2024-11-03 13:04:35.000000000
+0100
+++ new/typeguard-4.4.2/tests/test_checkers.py 2025-02-16 17:27:08.000000000
+0100
@@ -2,6 +2,7 @@
import sys
import types
from contextlib import nullcontext
+from datetime import timedelta
from functools import partial
from io import BytesIO, StringIO
from pathlib import Path
@@ -1383,6 +1384,18 @@
f"be a class method but it's an instance method"
)
+ def test_builtin_signature_check(self) -> None:
+ class MyProtocol(Protocol):
+ def attr(self) -> None:
+ pass
+
+ class Foo:
+ attr = timedelta
+
+ # Foo.attr is incompatible but timedelta has not inspectable signature
so the
+ # check is skipped
+ check_type(Foo(), MyProtocol)
+
class TestRecursiveType:
def test_valid(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/typeguard-4.4.1/tests/test_instrumentation.py
new/typeguard-4.4.2/tests/test_instrumentation.py
--- old/typeguard-4.4.1/tests/test_instrumentation.py 2024-11-03
13:04:35.000000000 +0100
+++ new/typeguard-4.4.2/tests/test_instrumentation.py 2025-02-16
17:27:08.000000000 +0100
@@ -1,4 +1,5 @@
import asyncio
+import importlib
import sys
import warnings
from importlib import import_module
@@ -8,15 +9,16 @@
import pytest
from pytest import FixtureRequest
-from typeguard import TypeCheckError, config, install_import_hook,
suppress_type_checks
+from typeguard import TypeCheckError, install_import_hook, suppress_type_checks
from typeguard._importhook import OPTIMIZATION
pytestmark = pytest.mark.filterwarnings("error:no type annotations present")
this_dir = Path(__file__).parent
dummy_module_path = this_dir / "dummymodule.py"
-cached_module_path = Path(
+instrumented_cached_module_path = Path(
cache_from_source(str(dummy_module_path), optimization=OPTIMIZATION)
)
+cached_module_path = Path(cache_from_source(str(dummy_module_path)))
# This block here is to test the recipe mentioned in the user guide
if "pytest" in sys.modules:
@@ -35,27 +37,50 @@
return request.param
[email protected](scope="module")
-def dummymodule(method: str):
- config.debug_instrumentation = True
+def _fixture_module(name: str, method: str):
+ # config.debug_instrumentation = True
sys.path.insert(0, str(this_dir))
try:
- sys.modules.pop("dummymodule", None)
- if cached_module_path.exists():
- cached_module_path.unlink()
-
+ # sys.modules.pop(name, None)
if method == "typechecked":
- return import_module("dummymodule")
+ if cached_module_path.exists():
+ cached_module_path.unlink()
+
+ if name in sys.modules:
+ module = import_module(name)
+ importlib.reload(module)
+ else:
+ module = import_module(name)
+ return module
+
+ if instrumented_cached_module_path.exists():
+ instrumented_cached_module_path.unlink()
- with install_import_hook(["dummymodule"]):
+ with install_import_hook([name]):
with warnings.catch_warnings():
warnings.filterwarnings("error", module="typeguard")
- module = import_module("dummymodule")
+ if name in sys.modules:
+ module = import_module(name)
+ importlib.reload(module)
+ else:
+ module = import_module(name)
return module
finally:
sys.path.remove(str(this_dir))
[email protected](scope="module")
+def dummymodule(method: str):
+ return _fixture_module("dummymodule", method)
+
+
[email protected](scope="module")
+def deferredannos(method: str):
+ if sys.version_info < (3, 14):
+ raise pytest.skip("Deferred annotations are only supported in Python
3.14+")
+ return _fixture_module("deferredannos", method)
+
+
def test_type_checked_func(dummymodule):
assert dummymodule.type_checked_func(2, 3) == 6
@@ -250,6 +275,11 @@
)
+def test_attribute_assign_unpacking(dummymodule):
+ foo = dummymodule.DummyClass()
+ dummymodule.attribute_assign_unpacking(foo)
+
+
def test_unpacking_assign_star_no_annotation_fail(dummymodule):
with pytest.raises(
TypeCheckError, match=r"value assigned to z \(bytes\) is not an
instance of str"
@@ -330,6 +360,7 @@
def test_typevar_forwardref(dummymodule):
+ print(f"id of typevar_forwardref: {id(dummymodule.typevar_forwardref):x}")
instance = dummymodule.typevar_forwardref(dummymodule.DummyClass)
assert isinstance(instance, dummymodule.DummyClass)
@@ -342,3 +373,16 @@
def test_suppress_annotated_multi_assignment(dummymodule):
with suppress_type_checks():
assert dummymodule.multi_assign_single_value() == (6, 6, 6)
+
+
+class TestUsesForwardRef:
+ def test_success(self, deferredannos):
+ obj = deferredannos.NotYetDefined()
+ assert deferredannos.uses_forwardref(obj) is obj
+
+ def test_failure(self, deferredannos):
+ with pytest.raises(
+ TypeCheckError,
+ match=r'argument "x" \(int\) is not an instance of
deferredannos.NotYetDefined',
+ ):
+ deferredannos.uses_forwardref(1)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/typeguard-4.4.1/tests/test_transformer.py
new/typeguard-4.4.2/tests/test_transformer.py
--- old/typeguard-4.4.1/tests/test_transformer.py 2024-11-03
13:04:35.000000000 +0100
+++ new/typeguard-4.4.2/tests/test_transformer.py 2025-02-16
17:27:08.000000000 +0100
@@ -1475,7 +1475,7 @@
def foo() -> None:
memo = TypeCheckMemo(globals(), locals())
x: int
- if (x := check_variable_assignment(otherfunc(), 'x', int, \
+ if (x := check_variable_assignment(otherfunc(), [[('x',
int)]], \
memo)):
pass
"""
@@ -1504,7 +1504,7 @@
def foo(x: int) -> None:
memo = TypeCheckMemo(globals(), locals())
check_argument_types('foo', {'x': (x, int)}, memo)
- if (x := check_variable_assignment(otherfunc(), 'x', int,
memo)):
+ if (x := check_variable_assignment(otherfunc(), [[('x',
int)]], memo)):
pass
"""
).strip()