Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-pyupgrade for 
openSUSE:Leap:16.0 checked in at 2025-07-24 08:31:17
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Leap:16.0/python-pyupgrade (Old)
 and      /work/SRC/openSUSE:Leap:16.0/.python-pyupgrade.new.8875 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-pyupgrade"

Thu Jul 24 08:31:17 2025 rev:2 rq:1293740 version:3.19.1

Changes:
--------
--- /work/SRC/openSUSE:Leap:16.0/python-pyupgrade/python-pyupgrade.changes      
2025-05-03 18:45:02.749755246 +0200
+++ 
/work/SRC/openSUSE:Leap:16.0/.python-pyupgrade.new.8875/python-pyupgrade.changes
    2025-07-24 08:31:38.487404172 +0200
@@ -1,0 +2,8 @@
+Mon Apr 28 14:14:57 UTC 2025 - Dirk Müller <dmuel...@suse.com>
+
+- update to 3.19.1:
+  * pyupgrade support for 3.13
+  * run pyupgrade on itself for removal of 3.13 deprecated
+    constructs
+
+-------------------------------------------------------------------

Old:
----
  python-pyupgrade-3.17.0.tar.gz

New:
----
  python-pyupgrade-3.19.1.tar.gz

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

Other differences:
------------------
++++++ python-pyupgrade.spec ++++++
--- /var/tmp/diff_new_pack.TzYaTM/_old  2025-07-24 08:31:38.767415814 +0200
+++ /var/tmp/diff_new_pack.TzYaTM/_new  2025-07-24 08:31:38.771415980 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-pyupgrade
 #
-# 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-pyupgrade
-Version:        3.17.0
+Version:        3.19.1
 Release:        0
 Summary:        A tool to automatically upgrade syntax for newer versions
 License:        MIT

++++++ python-pyupgrade-3.17.0.tar.gz -> python-pyupgrade-3.19.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyupgrade-3.17.0/.github/workflows/main.yml 
new/pyupgrade-3.19.1/.github/workflows/main.yml
--- old/pyupgrade-3.17.0/.github/workflows/main.yml     2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/.github/workflows/main.yml     2024-12-17 
02:50:11.000000000 +0100
@@ -8,12 +8,12 @@
 
 jobs:
   main-windows:
-    uses: asottile/workflows/.github/workflows/tox.yml@v1.6.0
+    uses: asottile/workflows/.github/workflows/tox.yml@v1.8.0
     with:
       env: '["py39"]'
       os: windows-latest
   main-linux:
-    uses: asottile/workflows/.github/workflows/tox.yml@v1.6.0
+    uses: asottile/workflows/.github/workflows/tox.yml@v1.8.0
     with:
       env: '["py39", "py310", "py311", "py312"]'
       os: ubuntu-latest
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyupgrade-3.17.0/.pre-commit-config.yaml 
new/pyupgrade-3.19.1/.pre-commit-config.yaml
--- old/pyupgrade-3.17.0/.pre-commit-config.yaml        2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/.pre-commit-config.yaml        2024-12-17 
02:50:11.000000000 +0100
@@ -1,6 +1,6 @@
 repos:
 -   repo: https://github.com/pre-commit/pre-commit-hooks
-    rev: v4.6.0
+    rev: v5.0.0
     hooks:
     -   id: trailing-whitespace
     -   id: end-of-file-fixer
@@ -10,32 +10,32 @@
     -   id: name-tests-test
     -   id: requirements-txt-fixer
 -   repo: https://github.com/asottile/setup-cfg-fmt
-    rev: v2.5.0
+    rev: v2.7.0
     hooks:
     -   id: setup-cfg-fmt
 -   repo: https://github.com/asottile/reorder-python-imports
-    rev: v3.13.0
+    rev: v3.14.0
     hooks:
     -   id: reorder-python-imports
-        args: [--py38-plus, --add-import, 'from __future__ import annotations']
+        args: [--py39-plus, --add-import, 'from __future__ import annotations']
 -   repo: https://github.com/asottile/add-trailing-comma
     rev: v3.1.0
     hooks:
     -   id: add-trailing-comma
 -   repo: https://github.com/asottile/pyupgrade
-    rev: v3.17.0
+    rev: v3.19.1
     hooks:
     -   id: pyupgrade
-        args: [--py38-plus]
+        args: [--py39-plus]
 -   repo: https://github.com/hhatto/autopep8
     rev: v2.3.1
     hooks:
     -   id: autopep8
 -   repo: https://github.com/PyCQA/flake8
-    rev: 7.1.0
+    rev: 7.1.1
     hooks:
     -   id: flake8
 -   repo: https://github.com/pre-commit/mirrors-mypy
-    rev: v1.11.0
+    rev: v1.13.0
     hooks:
     -   id: mypy
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyupgrade-3.17.0/README.md 
new/pyupgrade-3.19.1/README.md
--- old/pyupgrade-3.17.0/README.md      2024-07-28 20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/README.md      2024-12-17 02:50:11.000000000 +0100
@@ -21,7 +21,7 @@
 
 ```yaml
 -   repo: https://github.com/asottile/pyupgrade
-    rev: v3.17.0
+    rev: v3.19.1
     hooks:
     -   id: pyupgrade
 ```
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyupgrade-3.17.0/pyupgrade/_ast_helpers.py 
new/pyupgrade-3.19.1/pyupgrade/_ast_helpers.py
--- old/pyupgrade-3.17.0/pyupgrade/_ast_helpers.py      2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_ast_helpers.py      2024-12-17 
02:50:11.000000000 +0100
@@ -2,7 +2,7 @@
 
 import ast
 import warnings
-from typing import Container
+from collections.abc import Container
 
 from tokenize_rt import Offset
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyupgrade-3.17.0/pyupgrade/_data.py 
new/pyupgrade-3.19.1/pyupgrade/_data.py
--- old/pyupgrade-3.17.0/pyupgrade/_data.py     2024-07-28 20:38:58.000000000 
+0200
+++ new/pyupgrade-3.19.1/pyupgrade/_data.py     2024-12-17 02:50:11.000000000 
+0100
@@ -3,12 +3,10 @@
 import ast
 import collections
 import pkgutil
+from collections.abc import Iterable
 from typing import Callable
-from typing import Iterable
-from typing import List
 from typing import NamedTuple
 from typing import Protocol
-from typing import Tuple
 from typing import TypeVar
 
 from tokenize_rt import Offset
@@ -16,7 +14,7 @@
 
 from pyupgrade import _plugins
 
-Version = Tuple[int, ...]
+Version = tuple[int, ...]
 
 
 class Settings(NamedTuple):
@@ -33,8 +31,8 @@
 
 
 AST_T = TypeVar('AST_T', bound=ast.AST)
-TokenFunc = Callable[[int, List[Token]], None]
-ASTFunc = Callable[[State, AST_T, ast.AST], Iterable[Tuple[Offset, TokenFunc]]]
+TokenFunc = Callable[[int, list[Token]], None]
+ASTFunc = Callable[[State, AST_T, ast.AST], Iterable[tuple[Offset, TokenFunc]]]
 
 RECORD_FROM_IMPORTS = frozenset((
     '__future__',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyupgrade-3.17.0/pyupgrade/_main.py 
new/pyupgrade-3.19.1/pyupgrade/_main.py
--- old/pyupgrade-3.17.0/pyupgrade/_main.py     2024-07-28 20:38:58.000000000 
+0200
+++ new/pyupgrade-3.19.1/pyupgrade/_main.py     2024-12-17 02:50:11.000000000 
+0100
@@ -5,8 +5,8 @@
 import re
 import sys
 import tokenize
-from typing import Match
-from typing import Sequence
+from collections.abc import Sequence
+from re import Match
 
 from tokenize_rt import NON_CODING_TOKENS
 from tokenize_rt import parse_string_literal
@@ -378,6 +378,10 @@
         '--py312-plus',
         action='store_const', dest='min_version', const=(3, 12),
     )
+    parser.add_argument(
+        '--py313-plus',
+        action='store_const', dest='min_version', const=(3, 13),
+    )
     args = parser.parse_args(argv)
 
     ret = 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pyupgrade-3.17.0/pyupgrade/_plugins/collections_abc.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/collections_abc.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/collections_abc.py  2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/collections_abc.py  2024-12-17 
02:50:11.000000000 +0100
@@ -2,7 +2,7 @@
 
 import ast
 import functools
-from typing import Iterable
+from collections.abc import Iterable
 
 from tokenize_rt import Offset
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyupgrade-3.17.0/pyupgrade/_plugins/constant_fold.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/constant_fold.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/constant_fold.py    2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/constant_fold.py    2024-12-17 
02:50:11.000000000 +0100
@@ -1,7 +1,7 @@
 from __future__ import annotations
 
 import ast
-from typing import Iterable
+from collections.abc import Iterable
 
 from tokenize_rt import Offset
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pyupgrade-3.17.0/pyupgrade/_plugins/datetime_utc_alias.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/datetime_utc_alias.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/datetime_utc_alias.py       
2024-07-28 20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/datetime_utc_alias.py       
2024-12-17 02:50:11.000000000 +0100
@@ -2,7 +2,7 @@
 
 import ast
 import functools
-from typing import Iterable
+from collections.abc import Iterable
 
 from tokenize_rt import Offset
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pyupgrade-3.17.0/pyupgrade/_plugins/defauldict_lambda.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/defauldict_lambda.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/defauldict_lambda.py        
2024-07-28 20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/defauldict_lambda.py        
1970-01-01 01:00:00.000000000 +0100
@@ -1,81 +0,0 @@
-from __future__ import annotations
-
-import ast
-import functools
-from typing import Iterable
-
-from tokenize_rt import Offset
-from tokenize_rt import Token
-
-from pyupgrade._ast_helpers import ast_to_offset
-from pyupgrade._ast_helpers import is_name_attr
-from pyupgrade._data import register
-from pyupgrade._data import State
-from pyupgrade._data import TokenFunc
-from pyupgrade._token_helpers import find_op
-from pyupgrade._token_helpers import parse_call_args
-
-
-def _eligible_lambda_replacement(lambda_expr: ast.Lambda) -> str | None:
-    if isinstance(lambda_expr.body, ast.Constant):
-        if lambda_expr.body.value == 0:
-            return type(lambda_expr.body.value).__name__
-        elif lambda_expr.body.value == '':
-            return 'str'
-        else:
-            return None
-    elif isinstance(lambda_expr.body, ast.List) and not lambda_expr.body.elts:
-        return 'list'
-    elif isinstance(lambda_expr.body, ast.Tuple) and not lambda_expr.body.elts:
-        return 'tuple'
-    elif isinstance(lambda_expr.body, ast.Dict) and not lambda_expr.body.keys:
-        return 'dict'
-    elif (
-            isinstance(lambda_expr.body, ast.Call) and
-            isinstance(lambda_expr.body.func, ast.Name) and
-            not lambda_expr.body.args and
-            not lambda_expr.body.keywords and
-            lambda_expr.body.func.id in {'dict', 'list', 'set', 'tuple'}
-    ):
-        return lambda_expr.body.func.id
-    else:
-        return None
-
-
-def _fix_defaultdict_first_arg(
-        i: int,
-        tokens: list[Token],
-        *,
-        replacement: str,
-) -> None:
-    start = find_op(tokens, i, '(')
-    func_args, end = parse_call_args(tokens, start)
-
-    tokens[slice(*func_args[0])] = [Token('CODE', replacement)]
-
-
-@register(ast.Call)
-def visit_Call(
-        state: State,
-        node: ast.Call,
-        parent: ast.AST,
-) -> Iterable[tuple[Offset, TokenFunc]]:
-    if (
-            is_name_attr(
-                node.func,
-                state.from_imports,
-                ('collections',),
-                ('defaultdict',),
-            ) and
-            node.args and
-            isinstance(node.args[0], ast.Lambda)
-    ):
-        replacement = _eligible_lambda_replacement(node.args[0])
-        if replacement is None:
-            return
-
-        func = functools.partial(
-            _fix_defaultdict_first_arg,
-            replacement=replacement,
-        )
-        yield ast_to_offset(node), func
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pyupgrade-3.17.0/pyupgrade/_plugins/default_encoding.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/default_encoding.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/default_encoding.py 2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/default_encoding.py 2024-12-17 
02:50:11.000000000 +0100
@@ -1,7 +1,7 @@
 from __future__ import annotations
 
 import ast
-from typing import Iterable
+from collections.abc import Iterable
 
 from tokenize_rt import Offset
 from tokenize_rt import Token
@@ -12,12 +12,12 @@
 from pyupgrade._data import State
 from pyupgrade._data import TokenFunc
 from pyupgrade._string_helpers import is_codec
+from pyupgrade._token_helpers import find_call
 from pyupgrade._token_helpers import find_closing_bracket
-from pyupgrade._token_helpers import find_op
 
 
 def _fix_default_encoding(i: int, tokens: list[Token]) -> None:
-    i = find_op(tokens, i + 1, '(')
+    i = find_call(tokens, i + 1)
     j = find_closing_bracket(tokens, i)
     del tokens[i + 1:j]
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pyupgrade-3.17.0/pyupgrade/_plugins/defaultdict_lambda.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/defaultdict_lambda.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/defaultdict_lambda.py       
1970-01-01 01:00:00.000000000 +0100
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/defaultdict_lambda.py       
2024-12-17 02:50:11.000000000 +0100
@@ -0,0 +1,81 @@
+from __future__ import annotations
+
+import ast
+import functools
+from collections.abc import Iterable
+
+from tokenize_rt import Offset
+from tokenize_rt import Token
+
+from pyupgrade._ast_helpers import ast_to_offset
+from pyupgrade._ast_helpers import is_name_attr
+from pyupgrade._data import register
+from pyupgrade._data import State
+from pyupgrade._data import TokenFunc
+from pyupgrade._token_helpers import find_op
+from pyupgrade._token_helpers import parse_call_args
+
+
+def _eligible_lambda_replacement(lambda_expr: ast.Lambda) -> str | None:
+    if isinstance(lambda_expr.body, ast.Constant):
+        if lambda_expr.body.value == 0:
+            return type(lambda_expr.body.value).__name__
+        elif lambda_expr.body.value == '':
+            return 'str'
+        else:
+            return None
+    elif isinstance(lambda_expr.body, ast.List) and not lambda_expr.body.elts:
+        return 'list'
+    elif isinstance(lambda_expr.body, ast.Tuple) and not lambda_expr.body.elts:
+        return 'tuple'
+    elif isinstance(lambda_expr.body, ast.Dict) and not lambda_expr.body.keys:
+        return 'dict'
+    elif (
+            isinstance(lambda_expr.body, ast.Call) and
+            isinstance(lambda_expr.body.func, ast.Name) and
+            not lambda_expr.body.args and
+            not lambda_expr.body.keywords and
+            lambda_expr.body.func.id in {'dict', 'list', 'set', 'tuple'}
+    ):
+        return lambda_expr.body.func.id
+    else:
+        return None
+
+
+def _fix_defaultdict_first_arg(
+        i: int,
+        tokens: list[Token],
+        *,
+        replacement: str,
+) -> None:
+    start = find_op(tokens, i, '(')
+    func_args, end = parse_call_args(tokens, start)
+
+    tokens[slice(*func_args[0])] = [Token('CODE', replacement)]
+
+
+@register(ast.Call)
+def visit_Call(
+        state: State,
+        node: ast.Call,
+        parent: ast.AST,
+) -> Iterable[tuple[Offset, TokenFunc]]:
+    if (
+            is_name_attr(
+                node.func,
+                state.from_imports,
+                ('collections',),
+                ('defaultdict',),
+            ) and
+            node.args and
+            isinstance(node.args[0], ast.Lambda)
+    ):
+        replacement = _eligible_lambda_replacement(node.args[0])
+        if replacement is None:
+            return
+
+        func = functools.partial(
+            _fix_defaultdict_first_arg,
+            replacement=replacement,
+        )
+        yield ast_to_offset(node), func
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyupgrade-3.17.0/pyupgrade/_plugins/dict_literals.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/dict_literals.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/dict_literals.py    2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/dict_literals.py    2024-12-17 
02:50:11.000000000 +0100
@@ -2,7 +2,7 @@
 
 import ast
 import functools
-from typing import Iterable
+from collections.abc import Iterable
 
 from tokenize_rt import Offset
 from tokenize_rt import Token
@@ -53,6 +53,7 @@
         parent: ast.AST,
 ) -> Iterable[tuple[Offset, TokenFunc]]:
     if (
+            not isinstance(parent, ast.FormattedValue) and
             isinstance(node.func, ast.Name) and
             node.func.id == 'dict' and
             len(node.args) == 1 and
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyupgrade-3.17.0/pyupgrade/_plugins/exceptions.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/exceptions.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/exceptions.py       2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/exceptions.py       2024-12-17 
02:50:11.000000000 +0100
@@ -2,7 +2,7 @@
 
 import ast
 import functools
-from typing import Iterable
+from collections.abc import Iterable
 from typing import NamedTuple
 
 from tokenize_rt import Offset
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyupgrade-3.17.0/pyupgrade/_plugins/format_locals.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/format_locals.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/format_locals.py    2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/format_locals.py    2024-12-17 
02:50:11.000000000 +0100
@@ -1,7 +1,7 @@
 from __future__ import annotations
 
 import ast
-from typing import Iterable
+from collections.abc import Iterable
 
 from tokenize_rt import Offset
 from tokenize_rt import rfind_string_parts
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyupgrade-3.17.0/pyupgrade/_plugins/fstrings.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/fstrings.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/fstrings.py 2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/fstrings.py 2024-12-17 
02:50:11.000000000 +0100
@@ -1,7 +1,7 @@
 from __future__ import annotations
 
 import ast
-from typing import Iterable
+from collections.abc import Iterable
 
 from tokenize_rt import Offset
 from tokenize_rt import parse_string_literal
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pyupgrade-3.17.0/pyupgrade/_plugins/identity_equality.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/identity_equality.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/identity_equality.py        
2024-07-28 20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/identity_equality.py        
2024-12-17 02:50:11.000000000 +0100
@@ -2,7 +2,7 @@
 
 import ast
 import functools
-from typing import Iterable
+from collections.abc import Iterable
 
 from tokenize_rt import Offset
 from tokenize_rt import Token
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyupgrade-3.17.0/pyupgrade/_plugins/imports.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/imports.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/imports.py  2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/imports.py  2024-12-17 
02:50:11.000000000 +0100
@@ -4,8 +4,8 @@
 import bisect
 import collections
 import functools
-from typing import Iterable
-from typing import Mapping
+from collections.abc import Iterable
+from collections.abc import Mapping
 from typing import NamedTuple
 
 from tokenize_rt import Offset
@@ -21,7 +21,7 @@
 from pyupgrade._token_helpers import indented_amount
 
 # GENERATED VIA generate-imports
-# Using reorder-python-imports==3.13.0
+# Using reorder-python-imports==3.14.0
 REMOVALS = {
     (3,): {
         '__future__': {
@@ -223,6 +223,23 @@
         ('typing_extensions', 'dataclass_transform'): 'typing',
         ('typing_extensions', 'override'): 'typing',
     },
+    (3, 13): {
+        ('typing_extensions', 'AsyncContextManager'): 'typing',
+        ('typing_extensions', 'AsyncGenerator'): 'typing',
+        ('typing_extensions', 'ContextManager'): 'typing',
+        ('typing_extensions', 'Generator'): 'typing',
+        ('typing_extensions', 'NoDefault'): 'typing',
+        ('typing_extensions', 'ParamSpec'): 'typing',
+        ('typing_extensions', 'Protocol'): 'typing',
+        ('typing_extensions', 'ReadOnly'): 'typing',
+        ('typing_extensions', 'TypeIs'): 'typing',
+        ('typing_extensions', 'TypeVar'): 'typing',
+        ('typing_extensions', 'TypeVarTuple'): 'typing',
+        ('typing_extensions', 'TypedDict'): 'typing',
+        ('typing_extensions', 'get_protocol_members'): 'typing',
+        ('typing_extensions', 'is_protocol'): 'typing',
+        ('typing_extensions', 'runtime_checkable'): 'typing',
+    },
 }
 REPLACE_MODS = {
     'six.moves.BaseHTTPServer': 'http.server',
@@ -281,7 +298,7 @@
 # END GENERATED
 
 
-@functools.lru_cache(maxsize=None)
+@functools.cache
 def _for_version(
         version: tuple[int, ...],
         *,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyupgrade-3.17.0/pyupgrade/_plugins/io_open.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/io_open.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/io_open.py  2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/io_open.py  2024-12-17 
02:50:11.000000000 +0100
@@ -1,7 +1,7 @@
 from __future__ import annotations
 
 import ast
-from typing import Iterable
+from collections.abc import Iterable
 
 from tokenize_rt import Offset
 from tokenize_rt import Token
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyupgrade-3.17.0/pyupgrade/_plugins/legacy.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/legacy.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/legacy.py   2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/legacy.py   2024-12-17 
02:50:11.000000000 +0100
@@ -4,9 +4,9 @@
 import collections
 import contextlib
 import functools
+from collections.abc import Generator
+from collections.abc import Iterable
 from typing import Any
-from typing import Generator
-from typing import Iterable
 
 from tokenize_rt import Offset
 from tokenize_rt import Token
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyupgrade-3.17.0/pyupgrade/_plugins/lru_cache.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/lru_cache.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/lru_cache.py        2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/lru_cache.py        2024-12-17 
02:50:11.000000000 +0100
@@ -2,7 +2,7 @@
 
 import ast
 import functools
-from typing import Iterable
+from collections.abc import Iterable
 
 from tokenize_rt import Offset
 from tokenize_rt import Token
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pyupgrade-3.17.0/pyupgrade/_plugins/metaclass_type.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/metaclass_type.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/metaclass_type.py   2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/metaclass_type.py   2024-12-17 
02:50:11.000000000 +0100
@@ -1,7 +1,7 @@
 from __future__ import annotations
 
 import ast
-from typing import Iterable
+from collections.abc import Iterable
 
 from tokenize_rt import Offset
 from tokenize_rt import Token
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyupgrade-3.17.0/pyupgrade/_plugins/mock.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/mock.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/mock.py     2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/mock.py     2024-12-17 
02:50:11.000000000 +0100
@@ -1,7 +1,7 @@
 from __future__ import annotations
 
 import ast
-from typing import Iterable
+from collections.abc import Iterable
 
 from tokenize_rt import Offset
 from tokenize_rt import Token
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pyupgrade-3.17.0/pyupgrade/_plugins/native_literals.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/native_literals.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/native_literals.py  2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/native_literals.py  2024-12-17 
02:50:11.000000000 +0100
@@ -2,7 +2,7 @@
 
 import ast
 import functools
-from typing import Iterable
+from collections.abc import Iterable
 
 from tokenize_rt import Offset
 from tokenize_rt import Token
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pyupgrade-3.17.0/pyupgrade/_plugins/new_style_classes.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/new_style_classes.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/new_style_classes.py        
2024-07-28 20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/new_style_classes.py        
2024-12-17 02:50:11.000000000 +0100
@@ -1,7 +1,7 @@
 from __future__ import annotations
 
 import ast
-from typing import Iterable
+from collections.abc import Iterable
 
 from tokenize_rt import Offset
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyupgrade-3.17.0/pyupgrade/_plugins/open_mode.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/open_mode.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/open_mode.py        2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/open_mode.py        2024-12-17 
02:50:11.000000000 +0100
@@ -3,7 +3,7 @@
 import ast
 import functools
 import itertools
-from typing import Iterable
+from collections.abc import Iterable
 from typing import NamedTuple
 
 from tokenize_rt import Offset
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pyupgrade-3.17.0/pyupgrade/_plugins/percent_format.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/percent_format.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/percent_format.py   2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/percent_format.py   2024-12-17 
02:50:11.000000000 +0100
@@ -3,12 +3,11 @@
 import ast
 import functools
 import re
-from typing import Generator
-from typing import Iterable
-from typing import Match
+from collections.abc import Generator
+from collections.abc import Iterable
+from re import Match
+from re import Pattern
 from typing import Optional
-from typing import Pattern
-from typing import Tuple
 
 from tokenize_rt import Offset
 from tokenize_rt import Token
@@ -23,14 +22,14 @@
 from pyupgrade._token_helpers import remove_brace
 from pyupgrade._token_helpers import victims
 
-PercentFormatPart = Tuple[
+PercentFormatPart = tuple[
     Optional[str],
     Optional[str],
     Optional[str],
     Optional[str],
     str,
 ]
-PercentFormat = Tuple[str, Optional[PercentFormatPart]]
+PercentFormat = tuple[str, Optional[PercentFormatPart]]
 
 MAPPING_KEY_RE = re.compile(r'\(([^()]*)\)')
 CONVERSION_FLAG_RE = re.compile('[#0+ -]*')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyupgrade-3.17.0/pyupgrade/_plugins/set_literals.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/set_literals.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/set_literals.py     2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/set_literals.py     2024-12-17 
02:50:11.000000000 +0100
@@ -2,7 +2,7 @@
 
 import ast
 import functools
-from typing import Iterable
+from collections.abc import Iterable
 
 from tokenize_rt import Offset
 from tokenize_rt import Token
@@ -50,6 +50,7 @@
         parent: ast.AST,
 ) -> Iterable[tuple[Offset, TokenFunc]]:
     if (
+            not isinstance(parent, ast.FormattedValue) and
             isinstance(node.func, ast.Name) and
             node.func.id == 'set' and
             len(node.args) == 1 and
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyupgrade-3.17.0/pyupgrade/_plugins/shlex_join.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/shlex_join.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/shlex_join.py       2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/shlex_join.py       2024-12-17 
02:50:11.000000000 +0100
@@ -2,7 +2,7 @@
 
 import ast
 import functools
-from typing import Iterable
+from collections.abc import Iterable
 
 from tokenize_rt import NON_CODING_TOKENS
 from tokenize_rt import Offset
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pyupgrade-3.17.0/pyupgrade/_plugins/six_base_classes.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/six_base_classes.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/six_base_classes.py 2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/six_base_classes.py 2024-12-17 
02:50:11.000000000 +0100
@@ -1,7 +1,7 @@
 from __future__ import annotations
 
 import ast
-from typing import Iterable
+from collections.abc import Iterable
 
 from tokenize_rt import Offset
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyupgrade-3.17.0/pyupgrade/_plugins/six_calls.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/six_calls.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/six_calls.py        2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/six_calls.py        2024-12-17 
02:50:11.000000000 +0100
@@ -2,7 +2,7 @@
 
 import ast
 import functools
-from typing import Iterable
+from collections.abc import Iterable
 
 from tokenize_rt import Offset
 from tokenize_rt import Token
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pyupgrade-3.17.0/pyupgrade/_plugins/six_metaclasses.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/six_metaclasses.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/six_metaclasses.py  2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/six_metaclasses.py  2024-12-17 
02:50:11.000000000 +0100
@@ -1,7 +1,7 @@
 from __future__ import annotations
 
 import ast
-from typing import Iterable
+from collections.abc import Iterable
 
 from tokenize_rt import NON_CODING_TOKENS
 from tokenize_rt import Offset
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pyupgrade-3.17.0/pyupgrade/_plugins/six_remove_decorators.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/six_remove_decorators.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/six_remove_decorators.py    
2024-07-28 20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/six_remove_decorators.py    
2024-12-17 02:50:11.000000000 +0100
@@ -1,7 +1,7 @@
 from __future__ import annotations
 
 import ast
-from typing import Iterable
+from collections.abc import Iterable
 
 from tokenize_rt import Offset
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyupgrade-3.17.0/pyupgrade/_plugins/six_simple.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/six_simple.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/six_simple.py       2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/six_simple.py       2024-12-17 
02:50:11.000000000 +0100
@@ -2,7 +2,7 @@
 
 import ast
 import functools
-from typing import Iterable
+from collections.abc import Iterable
 
 from tokenize_rt import Offset
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pyupgrade-3.17.0/pyupgrade/_plugins/subprocess_run.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/subprocess_run.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/subprocess_run.py   2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/subprocess_run.py   2024-12-17 
02:50:11.000000000 +0100
@@ -2,7 +2,7 @@
 
 import ast
 import functools
-from typing import Iterable
+from collections.abc import Iterable
 
 from tokenize_rt import Offset
 from tokenize_rt import Token
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pyupgrade-3.17.0/pyupgrade/_plugins/type_of_primitive.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/type_of_primitive.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/type_of_primitive.py        
2024-07-28 20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/type_of_primitive.py        
2024-12-17 02:50:11.000000000 +0100
@@ -2,7 +2,7 @@
 
 import ast
 import functools
-from typing import Iterable
+from collections.abc import Iterable
 
 from tokenize_rt import Offset
 from tokenize_rt import Token
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pyupgrade-3.17.0/pyupgrade/_plugins/typing_classes.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/typing_classes.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/typing_classes.py   2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/typing_classes.py   2024-12-17 
02:50:11.000000000 +0100
@@ -2,7 +2,7 @@
 
 import ast
 import functools
-from typing import Iterable
+from collections.abc import Iterable
 
 from tokenize_rt import Offset
 from tokenize_rt import Token
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyupgrade-3.17.0/pyupgrade/_plugins/typing_pep563.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/typing_pep563.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/typing_pep563.py    2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/typing_pep563.py    2024-12-17 
02:50:11.000000000 +0100
@@ -3,8 +3,8 @@
 import ast
 import functools
 import sys
-from typing import Iterable
-from typing import Sequence
+from collections.abc import Iterable
+from collections.abc import Sequence
 
 from tokenize_rt import Offset
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyupgrade-3.17.0/pyupgrade/_plugins/typing_pep585.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/typing_pep585.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/typing_pep585.py    2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/typing_pep585.py    2024-12-17 
02:50:11.000000000 +0100
@@ -2,7 +2,7 @@
 
 import ast
 import functools
-from typing import Iterable
+from collections.abc import Iterable
 
 from tokenize_rt import Offset
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyupgrade-3.17.0/pyupgrade/_plugins/typing_pep604.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/typing_pep604.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/typing_pep604.py    2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/typing_pep604.py    2024-12-17 
02:50:11.000000000 +0100
@@ -3,7 +3,7 @@
 import ast
 import functools
 import sys
-from typing import Iterable
+from collections.abc import Iterable
 
 from tokenize_rt import NON_CODING_TOKENS
 from tokenize_rt import Offset
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pyupgrade-3.17.0/pyupgrade/_plugins/typing_pep646_unpack.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/typing_pep646_unpack.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/typing_pep646_unpack.py     
2024-07-28 20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/typing_pep646_unpack.py     
2024-12-17 02:50:11.000000000 +0100
@@ -1,7 +1,7 @@
 from __future__ import annotations
 
 import ast
-from typing import Iterable
+from collections.abc import Iterable
 
 from tokenize_rt import Offset
 from tokenize_rt import Token
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pyupgrade-3.17.0/pyupgrade/_plugins/typing_pep696_typevar_defaults.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/typing_pep696_typevar_defaults.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/typing_pep696_typevar_defaults.py   
2024-07-28 20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/typing_pep696_typevar_defaults.py   
2024-12-17 02:50:11.000000000 +0100
@@ -1,7 +1,7 @@
 from __future__ import annotations
 
 import ast
-from typing import Iterable
+from collections.abc import Iterable
 
 from tokenize_rt import Offset
 from tokenize_rt import Token
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyupgrade-3.17.0/pyupgrade/_plugins/typing_text.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/typing_text.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/typing_text.py      2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/typing_text.py      2024-12-17 
02:50:11.000000000 +0100
@@ -2,7 +2,7 @@
 
 import ast
 import functools
-from typing import Iterable
+from collections.abc import Iterable
 
 from tokenize_rt import Offset
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pyupgrade-3.17.0/pyupgrade/_plugins/unittest_aliases.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/unittest_aliases.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/unittest_aliases.py 2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/unittest_aliases.py 2024-12-17 
02:50:11.000000000 +0100
@@ -2,7 +2,7 @@
 
 import ast
 import functools
-from typing import Iterable
+from collections.abc import Iterable
 
 from tokenize_rt import Offset
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pyupgrade-3.17.0/pyupgrade/_plugins/unpack_list_comprehension.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/unpack_list_comprehension.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/unpack_list_comprehension.py        
2024-07-28 20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/unpack_list_comprehension.py        
2024-12-17 02:50:11.000000000 +0100
@@ -1,7 +1,7 @@
 from __future__ import annotations
 
 import ast
-from typing import Iterable
+from collections.abc import Iterable
 
 from tokenize_rt import Offset
 from tokenize_rt import Token
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pyupgrade-3.17.0/pyupgrade/_plugins/versioned_branches.py 
new/pyupgrade-3.19.1/pyupgrade/_plugins/versioned_branches.py
--- old/pyupgrade-3.17.0/pyupgrade/_plugins/versioned_branches.py       
2024-07-28 20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_plugins/versioned_branches.py       
2024-12-17 02:50:11.000000000 +0100
@@ -1,8 +1,8 @@
 from __future__ import annotations
 
 import ast
+from collections.abc import Iterable
 from typing import cast
-from typing import Iterable
 
 from tokenize_rt import Offset
 from tokenize_rt import Token
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyupgrade-3.17.0/pyupgrade/_string_helpers.py 
new/pyupgrade-3.19.1/pyupgrade/_string_helpers.py
--- old/pyupgrade-3.17.0/pyupgrade/_string_helpers.py   2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_string_helpers.py   2024-12-17 
02:50:11.000000000 +0100
@@ -1,14 +1,13 @@
 from __future__ import annotations
 
 import codecs
-import re
 import string
 from typing import Optional
-from typing import Tuple
 
-NAMED_UNICODE_RE = re.compile(r'(?<!\\)(?:\\\\)*(\\N\{[^}]+\})')
+from tokenize_rt import curly_escape
+from tokenize_rt import NAMED_UNICODE_RE
 
-DotFormatPart = Tuple[str, Optional[str], Optional[str], Optional[str]]
+DotFormatPart = tuple[str, Optional[str], Optional[str], Optional[str]]
 
 _stdlib_parse_format = string.Formatter().parse
 
@@ -54,16 +53,6 @@
     return ''.join(_convert_tup(tup) for tup in parsed)
 
 
-def curly_escape(s: str) -> str:
-    parts = NAMED_UNICODE_RE.split(s)
-    return ''.join(
-        part.replace('{', '{{').replace('}', '}}')
-        if not NAMED_UNICODE_RE.fullmatch(part)
-        else part
-        for part in parts
-    )
-
-
 def is_codec(encoding: str, name: str) -> bool:
     try:
         return codecs.lookup(encoding).name == name
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyupgrade-3.17.0/pyupgrade/_token_helpers.py 
new/pyupgrade-3.19.1/pyupgrade/_token_helpers.py
--- old/pyupgrade-3.17.0/pyupgrade/_token_helpers.py    2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/pyupgrade/_token_helpers.py    2024-12-17 
02:50:11.000000000 +0100
@@ -2,8 +2,8 @@
 
 import ast
 import keyword
+from collections.abc import Sequence
 from typing import NamedTuple
-from typing import Sequence
 
 from tokenize_rt import NON_CODING_TOKENS
 from tokenize_rt import Token
@@ -48,6 +48,20 @@
     return _find_token(tokens, i, 'OP', src)
 
 
+def find_call(tokens: list[Token], i: int) -> int:
+    depth = 0
+    while depth or not tokens[i].matches(name='OP', src='('):
+        if is_open(tokens[i]):  # pragma: >3.12 cover
+            depth += 1
+        elif is_close(tokens[i]):
+            # why max(...)? --
+            # ("something").method(...)
+            #  ^--start   target--^
+            depth = max(depth - 1, 0)
+        i += 1
+    return i
+
+
 def find_end(tokens: list[Token], i: int) -> int:
     while tokens[i].name != 'NEWLINE':
         i += 1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyupgrade-3.17.0/setup.cfg 
new/pyupgrade-3.19.1/setup.cfg
--- old/pyupgrade-3.17.0/setup.cfg      2024-07-28 20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/setup.cfg      2024-12-17 02:50:11.000000000 +0100
@@ -1,6 +1,6 @@
 [metadata]
 name = pyupgrade
-version = 3.17.0
+version = 3.19.1
 description = A tool to automatically upgrade syntax for newer versions.
 long_description = file: README.md
 long_description_content_type = text/markdown
@@ -19,7 +19,7 @@
 [options]
 packages = find:
 install_requires =
-    tokenize-rt>=5.2.0
+    tokenize-rt>=6.1.0
 python_requires = >=3.9
 
 [options.packages.find]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pyupgrade-3.17.0/tests/features/defauldict_lambda_test.py 
new/pyupgrade-3.19.1/tests/features/defauldict_lambda_test.py
--- old/pyupgrade-3.17.0/tests/features/defauldict_lambda_test.py       
2024-07-28 20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/tests/features/defauldict_lambda_test.py       
1970-01-01 01:00:00.000000000 +0100
@@ -1,220 +0,0 @@
-from __future__ import annotations
-
-import pytest
-
-from pyupgrade._data import Settings
-from pyupgrade._main import _fix_plugins
-
-
-@pytest.mark.parametrize(
-    ('s',),
-    (
-        pytest.param(
-            'from collections import defaultdict as dd\n\n'
-            'dd(lambda: set())\n',
-            id='not following as imports',
-        ),
-        pytest.param(
-            'from collections2 import defaultdict\n\n'
-            'dd(lambda: dict())\n',
-            id='not following unknown import',
-        ),
-        pytest.param(
-            'from .collections import defaultdict\n'
-            'defaultdict(lambda: list())\n',
-            id='relative imports',
-        ),
-        pytest.param(
-            'from collections import defaultdict\n\n'
-            'defaultdict(lambda: {1}))\n',
-            id='non empty set',
-        ),
-        pytest.param(
-            'from collections import defaultdict\n\n'
-            'defaultdict(lambda: [1]))\n'
-            'defaultdict(lambda: list([1])))\n',
-            id='non empty list',
-        ),
-        pytest.param(
-            'from collections import defaultdict\n\n'
-            'defaultdict(lambda: {1: 2})\n',
-            id='non empty dict, literal',
-        ),
-        pytest.param(
-            'from collections import defaultdict\n\n'
-            'defaultdict(lambda: dict([(1,2),])))\n',
-            id='non empty dict, call with args',
-        ),
-        pytest.param(
-            'from collections import defaultdict\n\n'
-            'defaultdict(lambda: dict(a=[1]))\n',
-            id='non empty dict, call with kwargs',
-        ),
-        pytest.param(
-            'from collections import defaultdict\n\n'
-            'defaultdict(lambda: (1,))\n',
-            id='non empty tuple, literal',
-        ),
-        pytest.param(
-            'from collections import defaultdict\n\n'
-            'defaultdict(lambda: tuple([1]))\n',
-            id='non empty tuple, calls with arg',
-        ),
-        pytest.param(
-            'from collections import defaultdict\n\n'
-            'defaultdict(lambda: "AAA")\n'
-            'defaultdict(lambda: \'BBB\')\n',
-            id='non empty string',
-        ),
-        pytest.param(
-            'from collections import defaultdict\n\n'
-            'defaultdict(lambda: 10)\n'
-            'defaultdict(lambda: -2)\n',
-            id='non zero integer',
-        ),
-        pytest.param(
-            'from collections import defaultdict\n\n'
-            'defaultdict(lambda: 0.2)\n'
-            'defaultdict(lambda: 0.00000001)\n'
-            'defaultdict(lambda: -2.3)\n',
-            id='non zero float',
-        ),
-        pytest.param(
-            'import collections\n'
-            'collections.defaultdict(lambda: None)\n',
-            id='lambda: None is not equivalent to defaultdict()',
-        ),
-    ),
-)
-def test_fix_noop(s):
-    assert _fix_plugins(s, settings=Settings()) == s
-
-
-@pytest.mark.parametrize(
-    ('s', 'expected'),
-    (
-        pytest.param(
-            'from collections import defaultdict\n\n'
-            'defaultdict(lambda: set())\n',
-            'from collections import defaultdict\n\n'
-            'defaultdict(set)\n',
-            id='call with attr, set()',
-        ),
-        pytest.param(
-            'from collections import defaultdict\n\n'
-            'defaultdict(lambda: list())\n',
-            'from collections import defaultdict\n\n'
-            'defaultdict(list)\n',
-            id='call with attr, list()',
-        ),
-        pytest.param(
-            'from collections import defaultdict\n\n'
-            'defaultdict(lambda: dict())\n',
-            'from collections import defaultdict\n\n'
-            'defaultdict(dict)\n',
-            id='call with attr, dict()',
-        ),
-        pytest.param(
-            'from collections import defaultdict\n\n'
-            'defaultdict(lambda: tuple())\n',
-            'from collections import defaultdict\n\n'
-            'defaultdict(tuple)\n',
-            id='call with attr, tuple()',
-        ),
-        pytest.param(
-            'from collections import defaultdict\n\n'
-            'defaultdict(lambda: [])\n',
-            'from collections import defaultdict\n\n'
-            'defaultdict(list)\n',
-            id='call with attr, []',
-        ),
-        pytest.param(
-            'from collections import defaultdict\n\n'
-            'defaultdict(lambda: {})\n',
-            'from collections import defaultdict\n\n'
-            'defaultdict(dict)\n',
-            id='call with attr, {}',
-        ),
-        pytest.param(
-            'from collections import defaultdict\n\n'
-            'defaultdict(lambda: ())\n',
-            'from collections import defaultdict\n\n'
-            'defaultdict(tuple)\n',
-            id='call with attr, ()',
-        ),
-        pytest.param(
-            'from collections import defaultdict\n\n'
-            'defaultdict(lambda: "")\n',
-            'from collections import defaultdict\n\n'
-            'defaultdict(str)\n',
-            id='call with attr, empty string (double quote)',
-        ),
-        pytest.param(
-            'from collections import defaultdict\n\n'
-            'defaultdict(lambda: \'\')\n',
-            'from collections import defaultdict\n\n'
-            'defaultdict(str)\n',
-            id='call with attr, empty string (single quote)',
-        ),
-        pytest.param(
-            'from collections import defaultdict\n\n'
-            'defaultdict(lambda: 0)\n',
-            'from collections import defaultdict\n\n'
-            'defaultdict(int)\n',
-            id='call with attr, int',
-        ),
-        pytest.param(
-            'from collections import defaultdict\n\n'
-            'defaultdict(lambda: 0.0)\n',
-            'from collections import defaultdict\n\n'
-            'defaultdict(float)\n',
-            id='call with attr, float',
-        ),
-        pytest.param(
-            'from collections import defaultdict\n\n'
-            'defaultdict(lambda: 0.0000)\n',
-            'from collections import defaultdict\n\n'
-            'defaultdict(float)\n',
-            id='call with attr, long float',
-        ),
-        pytest.param(
-            'from collections import defaultdict\n\n'
-            'defaultdict(lambda: [], {1: []})\n',
-            'from collections import defaultdict\n\n'
-            'defaultdict(list, {1: []})\n',
-            id='defauldict with kwargs',
-        ),
-        pytest.param(
-            'import collections\n\n'
-            'collections.defaultdict(lambda: set())\n'
-            'collections.defaultdict(lambda: list())\n'
-            'collections.defaultdict(lambda: dict())\n'
-            'collections.defaultdict(lambda: tuple())\n'
-            'collections.defaultdict(lambda: [])\n'
-            'collections.defaultdict(lambda: {})\n'
-            'collections.defaultdict(lambda: "")\n'
-            'collections.defaultdict(lambda: \'\')\n'
-            'collections.defaultdict(lambda: 0)\n'
-            'collections.defaultdict(lambda: 0.0)\n'
-            'collections.defaultdict(lambda: 0.00000)\n'
-            'collections.defaultdict(lambda: 0j)\n',
-            'import collections\n\n'
-            'collections.defaultdict(set)\n'
-            'collections.defaultdict(list)\n'
-            'collections.defaultdict(dict)\n'
-            'collections.defaultdict(tuple)\n'
-            'collections.defaultdict(list)\n'
-            'collections.defaultdict(dict)\n'
-            'collections.defaultdict(str)\n'
-            'collections.defaultdict(str)\n'
-            'collections.defaultdict(int)\n'
-            'collections.defaultdict(float)\n'
-            'collections.defaultdict(float)\n'
-            'collections.defaultdict(complex)\n',
-            id='call with attr',
-        ),
-    ),
-)
-def test_fix_defaultdict(s, expected):
-    ret = _fix_plugins(s, settings=Settings())
-    assert ret == expected
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pyupgrade-3.17.0/tests/features/default_encoding_test.py 
new/pyupgrade-3.19.1/tests/features/default_encoding_test.py
--- old/pyupgrade-3.17.0/tests/features/default_encoding_test.py        
2024-07-28 20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/tests/features/default_encoding_test.py        
2024-12-17 02:50:11.000000000 +0100
@@ -38,6 +38,11 @@
             'f"{x}(".encode()',
             id='3.12+ handle open brace in fstring',
         ),
+        pytest.param(
+            'f"{foo(bar)}(".encode("utf-8")',
+            'f"{foo(bar)}(".encode()',
+            id='f-string with function call',
+        ),
     ),
 )
 def test_fix_encode(s, expected):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pyupgrade-3.17.0/tests/features/defaultdict_lambda_test.py 
new/pyupgrade-3.19.1/tests/features/defaultdict_lambda_test.py
--- old/pyupgrade-3.17.0/tests/features/defaultdict_lambda_test.py      
1970-01-01 01:00:00.000000000 +0100
+++ new/pyupgrade-3.19.1/tests/features/defaultdict_lambda_test.py      
2024-12-17 02:50:11.000000000 +0100
@@ -0,0 +1,220 @@
+from __future__ import annotations
+
+import pytest
+
+from pyupgrade._data import Settings
+from pyupgrade._main import _fix_plugins
+
+
+@pytest.mark.parametrize(
+    ('s',),
+    (
+        pytest.param(
+            'from collections import defaultdict as dd\n\n'
+            'dd(lambda: set())\n',
+            id='not following as imports',
+        ),
+        pytest.param(
+            'from collections2 import defaultdict\n\n'
+            'dd(lambda: dict())\n',
+            id='not following unknown import',
+        ),
+        pytest.param(
+            'from .collections import defaultdict\n'
+            'defaultdict(lambda: list())\n',
+            id='relative imports',
+        ),
+        pytest.param(
+            'from collections import defaultdict\n\n'
+            'defaultdict(lambda: {1}))\n',
+            id='non empty set',
+        ),
+        pytest.param(
+            'from collections import defaultdict\n\n'
+            'defaultdict(lambda: [1]))\n'
+            'defaultdict(lambda: list([1])))\n',
+            id='non empty list',
+        ),
+        pytest.param(
+            'from collections import defaultdict\n\n'
+            'defaultdict(lambda: {1: 2})\n',
+            id='non empty dict, literal',
+        ),
+        pytest.param(
+            'from collections import defaultdict\n\n'
+            'defaultdict(lambda: dict([(1,2),])))\n',
+            id='non empty dict, call with args',
+        ),
+        pytest.param(
+            'from collections import defaultdict\n\n'
+            'defaultdict(lambda: dict(a=[1]))\n',
+            id='non empty dict, call with kwargs',
+        ),
+        pytest.param(
+            'from collections import defaultdict\n\n'
+            'defaultdict(lambda: (1,))\n',
+            id='non empty tuple, literal',
+        ),
+        pytest.param(
+            'from collections import defaultdict\n\n'
+            'defaultdict(lambda: tuple([1]))\n',
+            id='non empty tuple, calls with arg',
+        ),
+        pytest.param(
+            'from collections import defaultdict\n\n'
+            'defaultdict(lambda: "AAA")\n'
+            'defaultdict(lambda: \'BBB\')\n',
+            id='non empty string',
+        ),
+        pytest.param(
+            'from collections import defaultdict\n\n'
+            'defaultdict(lambda: 10)\n'
+            'defaultdict(lambda: -2)\n',
+            id='non zero integer',
+        ),
+        pytest.param(
+            'from collections import defaultdict\n\n'
+            'defaultdict(lambda: 0.2)\n'
+            'defaultdict(lambda: 0.00000001)\n'
+            'defaultdict(lambda: -2.3)\n',
+            id='non zero float',
+        ),
+        pytest.param(
+            'import collections\n'
+            'collections.defaultdict(lambda: None)\n',
+            id='lambda: None is not equivalent to defaultdict()',
+        ),
+    ),
+)
+def test_fix_noop(s):
+    assert _fix_plugins(s, settings=Settings()) == s
+
+
+@pytest.mark.parametrize(
+    ('s', 'expected'),
+    (
+        pytest.param(
+            'from collections import defaultdict\n\n'
+            'defaultdict(lambda: set())\n',
+            'from collections import defaultdict\n\n'
+            'defaultdict(set)\n',
+            id='call with attr, set()',
+        ),
+        pytest.param(
+            'from collections import defaultdict\n\n'
+            'defaultdict(lambda: list())\n',
+            'from collections import defaultdict\n\n'
+            'defaultdict(list)\n',
+            id='call with attr, list()',
+        ),
+        pytest.param(
+            'from collections import defaultdict\n\n'
+            'defaultdict(lambda: dict())\n',
+            'from collections import defaultdict\n\n'
+            'defaultdict(dict)\n',
+            id='call with attr, dict()',
+        ),
+        pytest.param(
+            'from collections import defaultdict\n\n'
+            'defaultdict(lambda: tuple())\n',
+            'from collections import defaultdict\n\n'
+            'defaultdict(tuple)\n',
+            id='call with attr, tuple()',
+        ),
+        pytest.param(
+            'from collections import defaultdict\n\n'
+            'defaultdict(lambda: [])\n',
+            'from collections import defaultdict\n\n'
+            'defaultdict(list)\n',
+            id='call with attr, []',
+        ),
+        pytest.param(
+            'from collections import defaultdict\n\n'
+            'defaultdict(lambda: {})\n',
+            'from collections import defaultdict\n\n'
+            'defaultdict(dict)\n',
+            id='call with attr, {}',
+        ),
+        pytest.param(
+            'from collections import defaultdict\n\n'
+            'defaultdict(lambda: ())\n',
+            'from collections import defaultdict\n\n'
+            'defaultdict(tuple)\n',
+            id='call with attr, ()',
+        ),
+        pytest.param(
+            'from collections import defaultdict\n\n'
+            'defaultdict(lambda: "")\n',
+            'from collections import defaultdict\n\n'
+            'defaultdict(str)\n',
+            id='call with attr, empty string (double quote)',
+        ),
+        pytest.param(
+            'from collections import defaultdict\n\n'
+            'defaultdict(lambda: \'\')\n',
+            'from collections import defaultdict\n\n'
+            'defaultdict(str)\n',
+            id='call with attr, empty string (single quote)',
+        ),
+        pytest.param(
+            'from collections import defaultdict\n\n'
+            'defaultdict(lambda: 0)\n',
+            'from collections import defaultdict\n\n'
+            'defaultdict(int)\n',
+            id='call with attr, int',
+        ),
+        pytest.param(
+            'from collections import defaultdict\n\n'
+            'defaultdict(lambda: 0.0)\n',
+            'from collections import defaultdict\n\n'
+            'defaultdict(float)\n',
+            id='call with attr, float',
+        ),
+        pytest.param(
+            'from collections import defaultdict\n\n'
+            'defaultdict(lambda: 0.0000)\n',
+            'from collections import defaultdict\n\n'
+            'defaultdict(float)\n',
+            id='call with attr, long float',
+        ),
+        pytest.param(
+            'from collections import defaultdict\n\n'
+            'defaultdict(lambda: [], {1: []})\n',
+            'from collections import defaultdict\n\n'
+            'defaultdict(list, {1: []})\n',
+            id='defauldict with kwargs',
+        ),
+        pytest.param(
+            'import collections\n\n'
+            'collections.defaultdict(lambda: set())\n'
+            'collections.defaultdict(lambda: list())\n'
+            'collections.defaultdict(lambda: dict())\n'
+            'collections.defaultdict(lambda: tuple())\n'
+            'collections.defaultdict(lambda: [])\n'
+            'collections.defaultdict(lambda: {})\n'
+            'collections.defaultdict(lambda: "")\n'
+            'collections.defaultdict(lambda: \'\')\n'
+            'collections.defaultdict(lambda: 0)\n'
+            'collections.defaultdict(lambda: 0.0)\n'
+            'collections.defaultdict(lambda: 0.00000)\n'
+            'collections.defaultdict(lambda: 0j)\n',
+            'import collections\n\n'
+            'collections.defaultdict(set)\n'
+            'collections.defaultdict(list)\n'
+            'collections.defaultdict(dict)\n'
+            'collections.defaultdict(tuple)\n'
+            'collections.defaultdict(list)\n'
+            'collections.defaultdict(dict)\n'
+            'collections.defaultdict(str)\n'
+            'collections.defaultdict(str)\n'
+            'collections.defaultdict(int)\n'
+            'collections.defaultdict(float)\n'
+            'collections.defaultdict(float)\n'
+            'collections.defaultdict(complex)\n',
+            id='call with attr',
+        ),
+    ),
+)
+def test_fix_defaultdict(s, expected):
+    ret = _fix_plugins(s, settings=Settings())
+    assert ret == expected
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pyupgrade-3.17.0/tests/features/dict_literals_test.py 
new/pyupgrade-3.19.1/tests/features/dict_literals_test.py
--- old/pyupgrade-3.17.0/tests/features/dict_literals_test.py   2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/tests/features/dict_literals_test.py   2024-12-17 
02:50:11.000000000 +0100
@@ -19,6 +19,10 @@
         # Don't rewrite kwargd dicts
         'dict(((a, b) for a, b in y), x=1)',
         'dict(((a, b) for a, b in y), **kwargs)',
+        pytest.param(
+            'f"{dict((a, b) for a, b in y)}"',
+            id='directly inside f-string placeholder',
+        ),
     ),
 )
 def test_fix_dict_noop(s):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyupgrade-3.17.0/tests/features/set_literals_test.py 
new/pyupgrade-3.19.1/tests/features/set_literals_test.py
--- old/pyupgrade-3.17.0/tests/features/set_literals_test.py    2024-07-28 
20:38:58.000000000 +0200
+++ new/pyupgrade-3.19.1/tests/features/set_literals_test.py    2024-12-17 
02:50:11.000000000 +0100
@@ -14,6 +14,14 @@
         # Don't touch weird looking function calls -- use autopep8 or such
         # first
         'set ((1, 2))',
+        pytest.param(
+            'f"{set((1, 2))}"',
+            id='set directly inside f-string placeholder',
+        ),
+        pytest.param(
+            'f"{set(x for x in y)}"',
+            id='set comp directly inside f-string placeholder',
+        ),
     ),
 )
 def test_fix_sets_noop(s):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyupgrade-3.17.0/tests/main_test.py 
new/pyupgrade-3.19.1/tests/main_test.py
--- old/pyupgrade-3.17.0/tests/main_test.py     2024-07-28 20:38:58.000000000 
+0200
+++ new/pyupgrade-3.19.1/tests/main_test.py     2024-12-17 02:50:11.000000000 
+0100
@@ -25,6 +25,8 @@
 x=version_info
 def f():
     global x, y
+
+f'hello snowman: \\N{SNOWMAN}'
 '''
     f = tmpdir.join('f.py')
     f.write(s)

Reply via email to