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 <dmuel...@suse.com>
+
+- 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)

Reply via email to