Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-flake8-pyi for
openSUSE:Factory checked in at 2024-04-07 22:13:14
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-flake8-pyi (Old)
and /work/SRC/openSUSE:Factory/.python-flake8-pyi.new.1905 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-flake8-pyi"
Sun Apr 7 22:13:14 2024 rev:14 rq:1165947 version:24.3.1
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-flake8-pyi/python-flake8-pyi.changes
2024-03-26 19:29:52.350701315 +0100
+++
/work/SRC/openSUSE:Factory/.python-flake8-pyi.new.1905/python-flake8-pyi.changes
2024-04-07 22:15:05.050554239 +0200
@@ -1,0 +2,11 @@
+Sun Apr 7 09:02:03 UTC 2024 - Dirk Müller <[email protected]>
+
+- update to 24.3.1:
+ * Y064: Use simpler syntax to define final literal types.
+ * For example, use `x: Final = 42` instead of `x:
+ Final[Literal[42]]`
+ * Y065: Don't use bare `Incomplete` in parameter and return
+ annotations.
+ * Y090: Fix false positive for `tuple[Unpack[Ts]]`.
+
+-------------------------------------------------------------------
Old:
----
flake8_pyi-24.3.0.tar.gz
New:
----
flake8_pyi-24.3.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-flake8-pyi.spec ++++++
--- /var/tmp/diff_new_pack.qYSSD6/_old 2024-04-07 22:15:05.454569043 +0200
+++ /var/tmp/diff_new_pack.qYSSD6/_new 2024-04-07 22:15:05.454569043 +0200
@@ -18,7 +18,7 @@
%{?sle15_python_module_pythons}
Name: python-flake8-pyi
-Version: 24.3.0
+Version: 24.3.1
Release: 0
Summary: A plugin for flake8 to enable linting .pyi files
License: MIT
++++++ flake8_pyi-24.3.0.tar.gz -> flake8_pyi-24.3.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flake8_pyi-24.3.0/.github/workflows/check.yml
new/flake8_pyi-24.3.1/.github/workflows/check.yml
--- old/flake8_pyi-24.3.0/.github/workflows/check.yml 2020-02-02
01:00:00.000000000 +0100
+++ new/flake8_pyi-24.3.1/.github/workflows/check.yml 2020-02-02
01:00:00.000000000 +0100
@@ -36,10 +36,9 @@
- uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- cache: pip
- cache-dependency-path: pyproject.toml
allow-prereleases: true
- - run: pip install -e .[dev]
+ - run: curl -LsSf https://astral.sh/uv/install.sh | sh
+ - run: uv pip install -e .[dev] --system
- run: mypy
flake8:
@@ -50,10 +49,9 @@
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
- python-version: "3.11"
- cache: pip
- cache-dependency-path: pyproject.toml
- - run: pip install -e .[dev]
+ python-version: "3.12"
+ - run: curl -LsSf https://astral.sh/uv/install.sh | sh
+ - run: uv pip install -e .[dev] --system
- run: |
flake8 $(git ls-files | grep 'py$') --color always
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flake8_pyi-24.3.0/.github/workflows/publish.yml
new/flake8_pyi-24.3.1/.github/workflows/publish.yml
--- old/flake8_pyi-24.3.0/.github/workflows/publish.yml 2020-02-02
01:00:00.000000000 +0100
+++ new/flake8_pyi-24.3.1/.github/workflows/publish.yml 2020-02-02
01:00:00.000000000 +0100
@@ -20,7 +20,7 @@
- name: Set up Python 3.10
uses: actions/setup-python@v4
with:
- python-version: "3.10"
+ python-version: "3.12"
- name: Install pypa/build
run: >-
python -m
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/flake8_pyi-24.3.0/.github/workflows/typeshed_primer.yml
new/flake8_pyi-24.3.1/.github/workflows/typeshed_primer.yml
--- old/flake8_pyi-24.3.0/.github/workflows/typeshed_primer.yml 2020-02-02
01:00:00.000000000 +0100
+++ new/flake8_pyi-24.3.1/.github/workflows/typeshed_primer.yml 2020-02-02
01:00:00.000000000 +0100
@@ -39,21 +39,21 @@
- name: Setup Python
uses: actions/setup-python@v4
with:
- python-version: "3.11"
- cache: pip
- cache-dependency-path: new_plugin/pyproject.toml
- - run: pip install flake8-noqa
+ python-version: "3.12"
+ - name: Install uv
+ run: curl -LsSf https://astral.sh/uv/install.sh | sh
+ - run: uv pip install flake8-noqa --system
# We cd so that "old_plugin"/"new_plugin"/typeshed" don't appear in the
error path
- name: flake8 typeshed using target branch
run: |
cd old_plugin
- pip install -e .
+ uv pip install -e . --system
cd ../typeshed
flake8 --exit-zero --color never --output-file ../old_errors.txt
- name: flake8 typeshed using PR branch
run: |
cd new_plugin
- pip install -e .
+ uv pip install -e . --system
cd ../typeshed
flake8 --exit-zero --color never --output-file ../new_errors.txt
- name: Get diff between the two runs
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flake8_pyi-24.3.0/CHANGELOG.md
new/flake8_pyi-24.3.1/CHANGELOG.md
--- old/flake8_pyi-24.3.0/CHANGELOG.md 2020-02-02 01:00:00.000000000 +0100
+++ new/flake8_pyi-24.3.1/CHANGELOG.md 2020-02-02 01:00:00.000000000 +0100
@@ -1,5 +1,15 @@
# Change Log
+## 24.3.1
+
+New error codes:
+* Y064: Use simpler syntax to define final literal types.
+ For example, use `x: Final = 42` instead of `x: Final[Literal[42]]`
+* Y065: Don't use bare `Incomplete` in parameter and return annotations.
+
+Bugfixes:
+* Y090: Fix false positive for `tuple[Unpack[Ts]]`.
+
## 24.3.0
New error codes:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flake8_pyi-24.3.0/ERRORCODES.md
new/flake8_pyi-24.3.1/ERRORCODES.md
--- old/flake8_pyi-24.3.0/ERRORCODES.md 2020-02-02 01:00:00.000000000 +0100
+++ new/flake8_pyi-24.3.1/ERRORCODES.md 2020-02-02 01:00:00.000000000 +0100
@@ -77,6 +77,8 @@
| Y061 | Do not use `None` inside a `Literal[]` slice. For example, use
`Literal["foo"] \| None` instead of `Literal["foo", None]`. While both are
legal according to [PEP 586](https://peps.python.org/pep-0586/), the former is
preferred for stylistic consistency. Note that this warning is not emitted if
Y062 is emitted for the same `Literal[]` slice. For example, `Literal[None,
None, True, True]` only causes Y062 to be emitted. | Style
| Y062 | `Literal[]` slices shouldn't contain duplicates, e.g. `Literal[True,
True]` is not allowed. | Redundant code
| Y063 | Use [PEP 570 syntax](https://peps.python.org/pep-0570/) (e.g. `def
foo(x: int, /) -> None: ...`) to denote positional-only arguments, rather than
[the older Python 3.7-compatible syntax described in PEP
484](https://peps.python.org/pep-0484/#positional-only-arguments) (`def
foo(__x: int) -> None: ...`, etc.). | Style
+| Y064 | Use simpler syntax to define final literal types. For example, use
`x: Final = 42` instead of `x: Final[Literal[42]]`. | Style
+| Y065 | Don't use bare `Incomplete` in argument and return annotations.
Instead, leave them unannotated. Omitting an annotation entirely from a
function will cause some type checkers to view the parameter or return type as
"untyped"; this may result in stricter type-checking on code that makes use of
the stubbed function. | Style
## Warnings disabled by default
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flake8_pyi-24.3.0/PKG-INFO
new/flake8_pyi-24.3.1/PKG-INFO
--- old/flake8_pyi-24.3.0/PKG-INFO 2020-02-02 01:00:00.000000000 +0100
+++ new/flake8_pyi-24.3.1/PKG-INFO 2020-02-02 01:00:00.000000000 +0100
@@ -1,6 +1,6 @@
-Metadata-Version: 2.1
+Metadata-Version: 2.3
Name: flake8-pyi
-Version: 24.3.0
+Version: 24.3.1
Summary: A plugin for flake8 to enable linting .pyi stub files.
Project-URL: Homepage, https://github.com/PyCQA/flake8-pyi
Project-URL: Source, https://github.com/PyCQA/flake8-pyi
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flake8_pyi-24.3.0/pyi.py new/flake8_pyi-24.3.1/pyi.py
--- old/flake8_pyi-24.3.0/pyi.py 2020-02-02 01:00:00.000000000 +0100
+++ new/flake8_pyi-24.3.1/pyi.py 2020-02-02 01:00:00.000000000 +0100
@@ -337,6 +337,7 @@
_is_builtins_object = partial(_is_object, name="object", from_={"builtins"})
_is_builtins_type = partial(_is_object, name="type", from_={"builtins"})
_is_Unused = partial(_is_object, name="Unused", from_={"_typeshed"})
+_is_Incomplete = partial(_is_object, name="Incomplete", from_={"_typeshed"})
_is_Iterable = partial(_is_object, name="Iterable",
from_=_TYPING_OR_COLLECTIONS_ABC)
_is_AsyncIterable = partial(
_is_object, name="AsyncIterable", from_=_TYPING_OR_COLLECTIONS_ABC
@@ -349,6 +350,7 @@
_is_object, name="AsyncGenerator", from_=_TYPING_OR_COLLECTIONS_ABC
)
_is_Generic = partial(_is_object, name="Generic", from_=_TYPING_MODULES)
+_is_Unpack = partial(_is_object, name="Unpack", from_=_TYPING_MODULES)
def _is_object_or_Unused(node: ast.expr | None) -> bool:
@@ -1041,6 +1043,7 @@
long_strings_allowed: NestingCounter
in_function: NestingCounter
visiting_arg: NestingCounter
+ Y061_suppressed: NestingCounter
# This is only relevant for visiting classes
enclosing_class_ctx: EnclosingClassContext | None = None
@@ -1058,6 +1061,7 @@
self.long_strings_allowed = NestingCounter()
self.in_function = NestingCounter()
self.visiting_arg = NestingCounter()
+ self.Y061_suppressed = NestingCounter()
def __repr__(self) -> str:
return f"{self.__class__.__name__}(filename={self.filename!r})"
@@ -1318,7 +1322,14 @@
)
self.visit(node_target)
- self.visit(node_annotation)
+
+ Y064_encountered = self._check_for_Y064_violations(node)
+ if Y064_encountered:
+ with self.Y061_suppressed.enabled():
+ self.visit(node_annotation)
+ else:
+ self.visit(node_annotation)
+
if node_value is not None:
if is_typealias:
self.visit(node_value)
@@ -1354,6 +1365,35 @@
self.generic_visit(node)
self._check_typealias(node=node, alias_name=node.name.id)
+ def _check_for_Y064_violations(self, node: ast.AnnAssign) -> bool:
+ annotation = node.annotation
+
+ if node.value or not isinstance(annotation, ast.Subscript):
+ return False
+
+ value = annotation.value
+ slice_ = annotation.slice
+
+ if (
+ _is_Final(value)
+ and isinstance(slice_, ast.Subscript)
+ and _is_Literal(slice_.value)
+ and isinstance(slice_.slice, ast.Constant)
+ ):
+ final = ast.Name(id="Final", ctx=ast.Load())
+ suggestion = ast.AnnAssign(
+ target=node.target,
+ annotation=final,
+ value=slice_.slice,
+ simple=node.simple,
+ )
+ self.error(
+ node,
+ Y064.format(suggestion=unparse(suggestion),
original=unparse(node)),
+ )
+ return True
+ return False
+
def _check_union_members(
self, members: Sequence[ast.expr], is_pep_604_union: bool
) -> None:
@@ -1499,7 +1539,9 @@
self._visit_slice_tuple(node.slice, subscripted_object_name)
else:
self.visit(node.slice)
- if subscripted_object_name in {"tuple", "Tuple"}:
+ if subscripted_object_name in {"tuple", "Tuple"} and not (
+ isinstance(node.slice, ast.Subscript) and
_is_Unpack(node.slice.value)
+ ):
self._Y090_error(node)
def _visit_typing_Literal(self, node: ast.Subscript) -> None:
@@ -1513,7 +1555,7 @@
Y062_encountered = True
self.error(member_list[1],
Y062.format(unparse(member_list[1])))
- if not Y062_encountered:
+ if not Y062_encountered and not self.Y061_suppressed.active:
if analysis.contains_only_none:
self.error(node.slice, Y061.format(suggestion="None"))
elif analysis.none_members:
@@ -2121,6 +2163,9 @@
with self.in_function.enabled():
self.generic_visit(node)
+ if node.name != "__getattr__" and node.returns and
_is_Incomplete(node.returns):
+ self.error(node.returns, Y065.format(what="return type"))
+
body = node.body
if len(body) > 1:
self.error(body[1], Y048)
@@ -2145,6 +2190,8 @@
def visit_arg(self, node: ast.arg) -> None:
if _is_NoReturn(node.annotation):
self.error(node, Y050)
+ if _is_Incomplete(node.annotation):
+ self.error(node, Y065.format(what=f'parameter "{node.arg}"'))
with self.visiting_arg.enabled():
self.generic_visit(node)
@@ -2366,6 +2413,8 @@
Y061 = 'Y061 None inside "Literal[]" expression. Replace with "{suggestion}"'
Y062 = 'Y062 Duplicate "Literal[]" member "{}"'
Y063 = "Y063 Use PEP-570 syntax to indicate positional-only arguments"
+Y064 = 'Y064 Use "{suggestion}" instead of "{original}"'
+Y065 = 'Y065 Leave {what} unannotated rather than using "Incomplete"'
Y090 = (
'Y090 "{original}" means '
'"a tuple of length 1, in which the sole element is of type {typ!r}". '
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flake8_pyi-24.3.0/tests/incomplete.pyi
new/flake8_pyi-24.3.1/tests/incomplete.pyi
--- old/flake8_pyi-24.3.0/tests/incomplete.pyi 1970-01-01 01:00:00.000000000
+0100
+++ new/flake8_pyi-24.3.1/tests/incomplete.pyi 2020-02-02 01:00:00.000000000
+0100
@@ -0,0 +1,39 @@
+from _typeshed import Incomplete
+from typing_extensions import TypeAlias
+
+IncompleteAlias: TypeAlias = Incomplete # ok
+
+att: Incomplete # ok
+
+def ok(x: Incomplete | None) -> list[Incomplete]: ...
+def aliased(x: IncompleteAlias) -> IncompleteAlias: ... # ok
+def err1(
+ x: Incomplete, # Y065 Leave parameter "x" unannotated rather than using
"Incomplete"
+) -> None: ...
+def err2() -> (
+ Incomplete # Y065 Leave return type unannotated rather than using
"Incomplete"
+): ...
+
+class Foo:
+ att: Incomplete
+ def ok(self, x: Incomplete | None) -> list[Incomplete]: ...
+ def err1(
+ self,
+ x: Incomplete, # Y065 Leave parameter "x" unannotated rather than
using "Incomplete"
+ ) -> None: ...
+ def err2(
+ self,
+ ) -> (
+ Incomplete # Y065 Leave return type unannotated rather than using
"Incomplete"
+ ): ...
+ def __getattr__(
+ self, name: str
+ ) -> Incomplete: ... # allowed in __getattr__ return type
+
+class Bar:
+ def __getattr__(
+ self,
+ name: Incomplete, # Y065 Leave parameter "name" unannotated rather
than using "Incomplete"
+ ) -> Incomplete: ...
+
+def __getattr__(name: str) -> Incomplete: ... # allowed in __getattr__ return
type
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flake8_pyi-24.3.0/tests/literals.pyi
new/flake8_pyi-24.3.1/tests/literals.pyi
--- old/flake8_pyi-24.3.0/tests/literals.pyi 2020-02-02 01:00:00.000000000
+0100
+++ new/flake8_pyi-24.3.1/tests/literals.pyi 2020-02-02 01:00:00.000000000
+0100
@@ -1,4 +1,4 @@
-from typing import Literal
+from typing import Final, Literal
Literal[None] # Y061 None inside "Literal[]" expression. Replace with "None"
Literal[True, None] # Y061 None inside "Literal[]" expression. Replace with
"Literal[True] | None"
@@ -21,3 +21,8 @@
# and there are no None members in the Literal[] slice,
# only emit Y062:
Literal[None, True, None, True] # Y062 Duplicate "Literal[]" member "True"
+
+x: Final[Literal[True]] # Y064 Use "x: Final = True" instead of "x:
Final[Literal[True]]"
+# If Y061 and Y064 both apply, only emit Y064
+y: Final[Literal[None]] # Y064 Use "y: Final = None" instead of "y:
Final[Literal[None]]"
+z: Final[Literal[True, False]]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flake8_pyi-24.3.0/tests/pep646_py311.pyi
new/flake8_pyi-24.3.1/tests/pep646_py311.pyi
--- old/flake8_pyi-24.3.0/tests/pep646_py311.pyi 1970-01-01
01:00:00.000000000 +0100
+++ new/flake8_pyi-24.3.1/tests/pep646_py311.pyi 2020-02-02
01:00:00.000000000 +0100
@@ -0,0 +1,7 @@
+# flags: --extend-select=Y090
+import typing
+
+_Ts = typing.TypeVarTuple("_Ts")
+
+e: tuple[*_Ts]
+f: typing.Tuple[*_Ts] # Y022 Use "tuple[Foo, Bar]" instead of
"typing.Tuple[Foo, Bar]" (PEP 585 syntax)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flake8_pyi-24.3.0/tests/single_element_tuples.pyi
new/flake8_pyi-24.3.1/tests/single_element_tuples.pyi
--- old/flake8_pyi-24.3.0/tests/single_element_tuples.pyi 2020-02-02
01:00:00.000000000 +0100
+++ new/flake8_pyi-24.3.1/tests/single_element_tuples.pyi 2020-02-02
01:00:00.000000000 +0100
@@ -2,7 +2,11 @@
import builtins
import typing
+_Ts = typing.TypeVarTuple("_Ts")
+
a: tuple[int] # Y090 "tuple[int]" means "a tuple of length 1, in which the
sole element is of type 'int'". Perhaps you meant "tuple[int, ...]"?
b: typing.Tuple[builtins.str] # Y022 Use "tuple[Foo, Bar]" instead of
"typing.Tuple[Foo, Bar]" (PEP 585 syntax) # Y090 "typing.Tuple[builtins.str]"
means "a tuple of length 1, in which the sole element is of type
'builtins.str'". Perhaps you meant "typing.Tuple[builtins.str, ...]"?
c: tuple[int, ...]
d: typing.Tuple[builtins.str, builtins.complex] # Y022 Use "tuple[Foo, Bar]"
instead of "typing.Tuple[Foo, Bar]" (PEP 585 syntax)
+e: tuple[typing.Unpack[_Ts]]
+f: typing.Tuple[typing.Unpack[_Ts]] # Y022 Use "tuple[Foo, Bar]" instead of
"typing.Tuple[Foo, Bar]" (PEP 585 syntax)