Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-pyupgrade for
openSUSE:Factory checked in at 2022-01-06 15:51:19
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pyupgrade (Old)
and /work/SRC/openSUSE:Factory/.python-pyupgrade.new.1896 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pyupgrade"
Thu Jan 6 15:51:19 2022 rev:21 rq:944190 version:2.31.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-pyupgrade/python-pyupgrade.changes
2021-11-20 02:39:56.684620864 +0100
+++
/work/SRC/openSUSE:Factory/.python-pyupgrade.new.1896/python-pyupgrade.changes
2022-01-06 15:52:04.152997148 +0100
@@ -1,0 +2,32 @@
+Mon Jan 3 11:37:47 UTC 2022 - Sebastian Wagner <[email protected]>
+
+- - update to version 2.31.0:
+ - rewrite string formatting with **locals()
+- update to version 2.30.1:
+ - don't rewrite six.reraise with named args
+- update to version 2.30.0:
+ - rewrite abspath(__file__) to __file__ in py39+
+ - fix __path__ type annotation
+ - fix the diff output of `forced str("native") literals` section
+ - improve coverage pragmas with covdefaults 2.1
+ - Use org-default .github/FUNDING.yml
+ Committed via https://github.com/asottile/all-repos
+ - Rewrite docs examples with commented code to use diffs
+
+-------------------------------------------------------------------
+Tue Dec 28 16:15:14 UTC 2021 - Sebastian Wagner <[email protected]>
+
+- - update to version 2.30.0:
+ - rewrite abspath(__file__) to __file__ in py39+
+ - fix __path__ type annotation
+ - fix the diff output of `forced str("native") literals` section
+ - improve coverage pragmas with covdefaults 2.1
+ - Use org-default .github/FUNDING.yml
+ Committed via https://github.com/asottile/all-repos
+ - Rewrite docs examples with commented code to use diffs
+- update to version 2.29.1:
+ - prevent rewriting union types with forward annotations
+ - replace exit(main()) with raise SystemExit(main())
+ Committed via https://github.com/asottile/all-repos
+
+-------------------------------------------------------------------
Old:
----
python-pyupgrade-2.29.1.tar.gz
New:
----
python-pyupgrade-2.31.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-pyupgrade.spec ++++++
--- /var/tmp/diff_new_pack.knMMx4/_old 2022-01-06 15:52:04.476997326 +0100
+++ /var/tmp/diff_new_pack.knMMx4/_new 2022-01-06 15:52:04.484997330 +0100
@@ -1,7 +1,7 @@
#
# spec file for package python-pyupgrade
#
-# Copyright (c) 2021 SUSE LLC
+# Copyright (c) 2022 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -19,7 +19,7 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
%define skip_python2 1
Name: python-pyupgrade
-Version: 2.29.1
+Version: 2.31.0
Release: 0
Summary: A tool to automatically upgrade syntax for newer versions
License: MIT
++++++ python-pyupgrade-2.29.1.tar.gz -> python-pyupgrade-2.31.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyupgrade-2.29.1/.github/FUNDING.yml
new/pyupgrade-2.31.0/.github/FUNDING.yml
--- old/pyupgrade-2.29.1/.github/FUNDING.yml 2021-11-16 02:13:55.000000000
+0100
+++ new/pyupgrade-2.31.0/.github/FUNDING.yml 1970-01-01 01:00:00.000000000
+0100
@@ -1 +0,0 @@
-github: asottile
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyupgrade-2.29.1/.pre-commit-config.yaml
new/pyupgrade-2.31.0/.pre-commit-config.yaml
--- old/pyupgrade-2.29.1/.pre-commit-config.yaml 2021-11-16
02:13:55.000000000 +0100
+++ new/pyupgrade-2.31.0/.pre-commit-config.yaml 2022-01-01
01:43:09.000000000 +0100
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v4.0.1
+ rev: v4.1.0
hooks:
- id: check-docstring-first
- id: check-yaml
@@ -11,7 +11,7 @@
- id: requirements-txt-fixer
- id: trailing-whitespace
- repo: https://github.com/asottile/setup-cfg-fmt
- rev: v1.19.0
+ rev: v1.20.0
hooks:
- id: setup-cfg-fmt
- repo: https://github.com/PyCQA/flake8
@@ -29,16 +29,16 @@
- id: reorder-python-imports
args: [--py3-plus]
- repo: https://github.com/asottile/add-trailing-comma
- rev: v2.2.0
+ rev: v2.2.1
hooks:
- id: add-trailing-comma
args: [--py36-plus]
- repo: https://github.com/asottile/pyupgrade
- rev: v2.29.1
+ rev: v2.31.0
hooks:
- id: pyupgrade
args: [--py36-plus]
- repo: https://github.com/pre-commit/mirrors-mypy
- rev: v0.910-1
+ rev: v0.930
hooks:
- id: mypy
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyupgrade-2.29.1/README.md
new/pyupgrade-2.31.0/README.md
--- old/pyupgrade-2.29.1/README.md 2021-11-16 02:13:55.000000000 +0100
+++ new/pyupgrade-2.31.0/README.md 2022-01-01 01:43:09.000000000 +0100
@@ -20,7 +20,7 @@
```yaml
- repo: https://github.com/asottile/pyupgrade
- rev: v2.29.1
+ rev: v2.31.0
hooks:
- id: pyupgrade
```
@@ -29,38 +29,53 @@
### Set literals
-```python
-set(()) # set()
-set([]) # set()
-set((1,)) # {1}
-set((1, 2)) # {1, 2}
-set([1, 2]) # {1, 2}
-set(x for x in y) # {x for x in y}
-set([x for x in y]) # {x for x in y}
+```diff
+-set(())
++set()
+-set([])
++set()
+-set((1,))
++{1}
+-set((1, 2))
++{1, 2}
+-set([1, 2])
++{1, 2}
+-set(x for x in y)
++{x for x in y}
+-set([x for x in y])
++{x for x in y}
```
### Dictionary comprehensions
-```python
-dict((a, b) for a, b in y) # {a: b for a, b in y}
-dict([(a, b) for a, b in y]) # {a: b for a, b in y}
+```diff
+-dict((a, b) for a, b in y)
++{a: b for a, b in y}
+-dict([(a, b) for a, b in y])
++{a: b for a, b in y}
```
### Generator expressions for some built-in functions (pep 289)
-```python
-min([i for i in range(3)]) # min(i for i in range(3))
-max([i for i in range(3)]) # max(i for i in range(3))
-sum([i for i in range(3)]) # sum(i for i in range(3))
-''.join([str(i) for i in range(3)]) # ''.join(str(i) for i in range(3))
+```diff
+-min([i for i in range(3)])
++min(i for i in range(3))
+-max([i for i in range(3)])
++max(i for i in range(3))
+-sum([i for i in range(3)])
++sum(i for i in range(3))
+-''.join([str(i) for i in range(3)])
++''.join(str(i) for i in range(3))
```
### Python2.7+ Format Specifiers
-```python
-'{0} {1}'.format(1, 2) # '{} {}'.format(1, 2)
-'{0}' '{1}'.format(1, 2) # '{}' '{}'.format(1, 2)
+```diff
+-'{0} {1}'.format(1, 2)
++'{} {}'.format(1, 2)
+-'{0}' '{1}'.format(1, 2)
++'{}' '{}'.format(1, 2)
```
### printf-style string formatting
@@ -68,10 +83,13 @@
Availability:
- Unless `--keep-percent-format` is passed.
-```python
-'%s %s' % (a, b) # '{} {}'.format(a, b)
-'%r %2f' % (a, b) # '{!r} {:2f}'.format(a, b)
-'%(a)s %(b)s' % {'a': 1, 'b': 2} # '{a} {b}'.format(a=1, b=2)
+```diff
+-'%s %s' % (a, b)
++'{} {}'.format(a, b)
+-'%r %2f' % (a, b)
++'{!r} {:2f}'.format(a, b)
+-'%(a)s %(b)s' % {'a': 1, 'b': 2}
++'{a} {b}'.format(a=1, b=2)
```
### Unicode literals
@@ -80,24 +98,30 @@
- File imports `from __future__ import unicode_literals`
- `--py3-plus` is passed on the commandline.
-```python
-u'foo' # 'foo'
-u"foo" # 'foo'
-u'''foo''' # '''foo'''
+```diff
+-u'foo'
++'foo'
+-u"foo"
++'foo'
+-u'''foo'''
++'''foo'''
```
### Invalid escape sequences
-```python
-# strings with only invalid sequences become raw strings
-'\d' # r'\d'
-# strings with mixed valid / invalid sequences get escaped
-'\n\d' # '\n\\d'
-# `ur` is not a valid string prefix in python3
-u'\d' # u'\\d'
-
-# this fixes a syntax error in python3.3+
-'\N' # r'\N'
+```diff
+ # strings with only invalid sequences become raw strings
+-'\d'
++r'\d'
+ # strings with mixed valid / invalid sequences get escaped
+-'\n\d'
++'\n\\d'
+ # `ur` is not a valid string prefix in python3
+-u'\d'
++u'\\d'
+ # this fixes a syntax error in python3.3+
+-'\N'
++r'\N'
# note: pyupgrade is timid in one case (that's usually a mistake)
# in python2.x `'\u2603'` is the same as `'\\u2603'` without `unicode_literals`
@@ -109,58 +133,80 @@
In python3.8+, comparison to literals becomes a `SyntaxWarning` as the success
of those comparisons is implementation specific (due to common object caching).
-```python
-x is 5 # x == 5
-x is not 5 # x != 5
-x is 'foo' # x == 'foo'
+```diff
+-x is 5
++x == 5
+-x is not 5
++x != 5
+-x is 'foo'
++x == 'foo'
```
### `ur` string literals
`ur'...'` literals are not valid in python 3.x
-```python
-ur'foo' # u'foo'
-ur'\s' # u'\\s'
-# unicode escapes are left alone
-ur'\u2603' # u'\u2603'
-ur'\U0001f643' # u'\U0001f643'
+```diff
+-ur'foo'
++u'foo'
+-ur'\s'
++u'\\s'
+ # unicode escapes are left alone
+-ur'\u2603'
++u'\u2603'
+-ur'\U0001f643'
++u'\U0001f643'
```
### `.encode()` to bytes literals
-```python
-'foo'.encode() # b'foo'
-'foo'.encode('ascii') # b'foo'
-'foo'.encode('utf-8') # b'foo'
-u'foo'.encode() # b'foo'
-'\xa0'.encode('latin1') # b'\xa0'
+```diff
+-'foo'.encode()
++b'foo'
+-'foo'.encode('ascii')
++b'foo'
+-'foo'.encode('utf-8')
++b'foo'
+-u'foo'.encode()
++b'foo'
+-'\xa0'.encode('latin1')
++b'\xa0'
```
### Long literals
-```python
-5L # 5
-5l # 5
-123456789123456789123456789L # 123456789123456789123456789
+```diff
+-5L
++5
+-5l
++5
+-123456789123456789123456789L
++123456789123456789123456789
```
### Octal literals
-```
-0755 # 0o755
-05 # 5
+```diff
+-0755
++0o755
+-05
++5
```
### extraneous parens in `print(...)`
A fix for [python-modernize/python-modernize#178]
-```python
-print(()) # ok: printing an empty tuple
-print((1,)) # ok: printing a tuple
-sum((i for i in range(3)), []) # ok: parenthesized generator argument
-print(("foo")) # print("foo")
+```diff
+ # ok: printing an empty tuple
+ print(())
+ # ok: printing a tuple
+ print((1,))
+ # ok: parenthesized generator argument
+ sum((i for i in range(3)), [])
+ # fixed:
+-print(("foo"))
++print("foo")
```
[python-modernize/python-modernize#178]:
https://github.com/python-modernize/python-modernize/issues/178
@@ -189,10 +235,11 @@
Availability:
- `--py3-plus` is passed on the commandline.
-```python
-class C(Base):
- def f(self):
- super(C, self).f() # super().f()
+```diff
+ class C(Base):
+ def f(self):
+- super(C, self).f()
++ super().f()
```
### "new style" classes
@@ -202,15 +249,18 @@
#### rewrites class declaration
-```python
-class C(object): pass # class C: pass
-class C(B, object): pass # class C(B): pass
+```diff
+-class C(object): pass
++class C: pass
+-class C(B, object): pass
++class C(B): pass
```
#### removes `__metaclass__ = type` declaration
```diff
--__metaclass__ = type
+ class C:
+- __metaclass__ = type
```
### forced `str("native")` literals
@@ -218,9 +268,11 @@
Availability:
- `--py3-plus` is passed on the commandline.
-```python
-str() # "''"
-str("foo") # "foo"
+```diff
+-str()
++''
+-str("foo")
++"foo"
```
### `.encode("utf-8")`
@@ -228,8 +280,9 @@
Availability:
- `--py3-plus` is passed on the commandline.
-```python
-"foo".encode("utf-8") # "foo".encode()
+```diff
+-"foo".encode("utf-8")
++"foo".encode()
```
### `# coding: ...` comment
@@ -285,13 +338,14 @@
Availability:
- `--py3-plus` is passed on the commandline.
-```python
-def f():
- for x in y: # yield from y
- yield x
-
- for a, b in c: # yield from c
- yield (a, b)
+```diff
+ def f():
+- for x in y:
+- yield x
++ yield from y
+- for a, b in c:
+- yield (a, b)
++ yield from c
```
### Python2 and old Python3.x blocks
@@ -351,74 +405,127 @@
Availability:
- `--py3-plus` is passed on the commandline.
-```python
-six.text_type # str
-six.binary_type # bytes
-six.class_types # (type,)
-six.string_types # (str,)
-six.integer_types # (int,)
-six.unichr # chr
-six.iterbytes # iter
-six.print_(...) # print(...)
-six.exec_(c, g, l) # exec(c, g, l)
-six.advance_iterator(it) # next(it)
-six.next(it) # next(it)
-six.callable(x) # callable(x)
-six.moves.range(x) # range(x)
-six.moves.xrange(x) # range(x)
-
-from six import text_type
-text_type # str
-
[email protected]_2_unicode_compatible # decorator is removed
-class C:
- def __str__(self):
- return u'C()'
-
-class C(six.Iterator): pass # class C: pass
-
-class C(six.with_metaclass(M, B)): pass # class C(B, metaclass=M): pass
-
[email protected]_metaclass(M) # class C(B, metaclass=M): pass
-class C(B): pass
-
-isinstance(..., six.class_types) # isinstance(..., type)
-issubclass(..., six.integer_types) # issubclass(..., int)
-isinstance(..., six.string_types) # isinstance(..., str)
-
-six.b('...') # b'...'
-six.u('...') # '...'
-six.byte2int(bs) # bs[0]
-six.indexbytes(bs, i) # bs[i]
-six.int2byte(i) # bytes((i,))
-six.iteritems(dct) # dct.items()
-six.iterkeys(dct) # dct.keys()
-six.itervalues(dct) # dct.values()
-next(six.iteritems(dct)) # next(iter(dct.items()))
-next(six.iterkeys(dct)) # next(iter(dct.keys()))
-next(six.itervalues(dct)) # next(iter(dct.values()))
-six.viewitems(dct) # dct.items()
-six.viewkeys(dct) # dct.keys()
-six.viewvalues(dct) # dct.values()
-six.create_unbound_method(fn, cls) # fn
-six.get_unbound_function(meth) # meth
-six.get_method_function(meth) # meth.__func__
-six.get_method_self(meth) # meth.__self__
-six.get_function_closure(fn) # fn.__closure__
-six.get_function_code(fn) # fn.__code__
-six.get_function_defaults(fn) # fn.__defaults__
-six.get_function_globals(fn) # fn.__globals__
-six.raise_from(exc, exc_from) # raise exc from exc_from
-six.reraise(tp, exc, tb) # raise exc.with_traceback(tb)
-six.reraise(*sys.exc_info()) # raise
-six.assertCountEqual(self, a1, a2) # self.assertCountEqual(a1, a2)
-six.assertRaisesRegex(self, e, r, fn) # self.assertRaisesRegex(e, r, fn)
-six.assertRegex(self, s, r) # self.assertRegex(s, r)
-
-# note: only for *literals*
-six.ensure_binary('...') # b'...'
-six.ensure_str('...') # '...'
-six.ensure_text('...') # '...'
+```diff
+-six.text_type
++str
+-six.binary_type
++bytes
+-six.class_types
++(type,)
+-six.string_types
++(str,)
+-six.integer_types
++(int,)
+-six.unichr
++chr
+-six.iterbytes
++iter
+-six.print_(...)
++print(...)
+-six.exec_(c, g, l)
++exec(c, g, l)
+-six.advance_iterator(it)
++next(it)
+-six.next(it)
++next(it)
+-six.callable(x)
++callable(x)
+-six.moves.range(x)
++range(x)
+-six.moves.xrange(x)
++range(x)
+
+
+-from six import text_type
+-text_type
++str
+
[email protected]_2_unicode_compatible
+ class C:
+ def __str__(self):
+ return u'C()'
+
+-class C(six.Iterator): pass
++class C: pass
+
+-class C(six.with_metaclass(M, B)): pass
++class C(B, metaclass=M): pass
+
[email protected]_metaclass(M)
+-class C(B): pass
++class C(B, metaclass=M): pass
+
+-isinstance(..., six.class_types)
++isinstance(..., type)
+-issubclass(..., six.integer_types)
++issubclass(..., int)
+-isinstance(..., six.string_types)
++isinstance(..., str)
+
+-six.b('...')
++b'...'
+-six.u('...')
++'...'
+-six.byte2int(bs)
++bs[0]
+-six.indexbytes(bs, i)
++bs[i]
+-six.int2byte(i)
++bytes((i,))
+-six.iteritems(dct)
++dct.items()
+-six.iterkeys(dct)
++dct.keys()
+-six.itervalues(dct)
++dct.values()
+-next(six.iteritems(dct))
++next(iter(dct.items()))
+-next(six.iterkeys(dct))
++next(iter(dct.keys()))
+-next(six.itervalues(dct))
++next(iter(dct.values()))
+-six.viewitems(dct)
++dct.items()
+-six.viewkeys(dct)
++dct.keys()
+-six.viewvalues(dct)
++dct.values()
+-six.create_unbound_method(fn, cls)
++fn
+-six.get_unbound_function(meth)
++meth
+-six.get_method_function(meth)
++meth.__func__
+-six.get_method_self(meth)
++meth.__self__
+-six.get_function_closure(fn)
++fn.__closure__
+-six.get_function_code(fn)
++fn.__code__
+-six.get_function_defaults(fn)
++fn.__defaults__
+-six.get_function_globals(fn)
++fn.__globals__
+-six.raise_from(exc, exc_from)
++raise exc from exc_from
+-six.reraise(tp, exc, tb)
++raise exc.with_traceback(tb)
+-six.reraise(*sys.exc_info())
++raise
+-six.assertCountEqual(self, a1, a2)
++self.assertCountEqual(a1, a2)
+-six.assertRaisesRegex(self, e, r, fn)
++self.assertRaisesRegex(e, r, fn)
+-six.assertRegex(self, s, r)
++self.assertRegex(s, r)
+
+ # note: only for *literals*
+-six.ensure_binary('...')
++b'...'
+-six.ensure_str('...')
++'...'
+-six.ensure_text('...')
++'...'
```
### `open` alias
@@ -438,14 +545,21 @@
Availability:
- `--py3-plus` is passed on the commandline.
-```python
-open("foo", "U") # open("foo")
-open("foo", "Ur") # open("foo")
-open("foo", "Ub") # open("foo", "rb")
-open("foo", "rUb") # open("foo", "rb")
-open("foo", "r") # open("foo")
-open("foo", "rt") # open("foo")
-open("f", "r", encoding="UTF-8") # open("f", encoding="UTF-8")
+```diff
+-open("foo", "U")
++open("foo")
+-open("foo", "Ur")
++open("foo")
+-open("foo", "Ub")
++open("foo", "rb")
+-open("foo", "rUb")
++open("foo", "rb")
+-open("foo", "r")
++open("foo")
+-open("foo", "rt")
++open("foo")
+-open("f", "r", encoding="UTF-8")
++open("f", encoding="UTF-8")
```
@@ -560,11 +674,17 @@
Availability:
- `--py36-plus` is passed on the commandline.
-```python
-'{foo} {bar}'.format(foo=foo, bar=bar) # f'{foo} {bar}'
-'{} {}'.format(foo, bar) # f'{foo} {bar}'
-'{} {}'.format(foo.bar, baz.womp) # f'{foo.bar} {baz.womp}'
-'{} {}'.format(f(), g()) # f'{f()} {g()}'
+```diff
+-'{foo} {bar}'.format(foo=foo, bar=bar)
++f'{foo} {bar}'
+-'{} {}'.format(foo, bar)
++f'{foo} {bar}'
+-'{} {}'.format(foo.bar, baz.womp)
++f'{foo.bar} {baz.womp}'
+-'{} {}'.format(f(), g())
++f'{f()} {g()}'
+-'{x}'.format(**locals())
++f'{x}'
```
_note_: `pyupgrade` is intentionally timid and will not create an f-string
@@ -638,6 +758,19 @@
```
+### remove unnecessary abspath
+
+Availability:
+- `--py39-plus` is passed on the commandline.
+
+```diff
+ from os.path import abspath
+
+-abspath(__file__)
++__file__
+```
+
+
### pep 604 typing rewrites
Availability:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyupgrade-2.29.1/pyupgrade/_data.py
new/pyupgrade-2.31.0/pyupgrade/_data.py
--- old/pyupgrade-2.29.1/pyupgrade/_data.py 2021-11-16 02:13:55.000000000
+0100
+++ new/pyupgrade-2.31.0/pyupgrade/_data.py 2022-01-01 01:43:09.000000000
+0100
@@ -44,6 +44,7 @@
RECORD_FROM_IMPORTS = frozenset((
'__future__',
+ 'os.path',
'functools',
'mmap',
'select',
@@ -116,8 +117,7 @@
def _import_plugins() -> None:
- # https://github.com/python/mypy/issues/1422
- plugins_path: str = _plugins.__path__ # type: ignore
+ plugins_path = _plugins.__path__
mod_infos = pkgutil.walk_packages(plugins_path, f'{_plugins.__name__}.')
for _, name, _ in mod_infos:
__import__(name, fromlist=['_trash'])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyupgrade-2.29.1/pyupgrade/_main.py
new/pyupgrade-2.31.0/pyupgrade/_main.py
--- old/pyupgrade-2.29.1/pyupgrade/_main.py 2021-11-16 02:13:55.000000000
+0100
+++ new/pyupgrade-2.31.0/pyupgrade/_main.py 2022-01-01 01:43:09.000000000
+0100
@@ -694,9 +694,9 @@
elif isinstance(node, ast.Attribute):
return ''.join((_unparse(node.value), '.', node.attr))
elif isinstance(node, ast.Subscript):
- if sys.version_info >= (3, 9): # pragma: no cover (py39+)
+ if sys.version_info >= (3, 9): # pragma: >=3.9 cover
node_slice: ast.expr = node.slice
- elif isinstance(node.slice, ast.Index): # pragma: no cover (<py39)
+ elif isinstance(node.slice, ast.Index): # pragma: <3.9 cover
node_slice = node.slice.value
else:
raise AssertionError(f'expected Slice: {ast.dump(node)}')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyupgrade-2.29.1/pyupgrade/_plugins/abspath_file.py
new/pyupgrade-2.31.0/pyupgrade/_plugins/abspath_file.py
--- old/pyupgrade-2.29.1/pyupgrade/_plugins/abspath_file.py 1970-01-01
01:00:00.000000000 +0100
+++ new/pyupgrade-2.31.0/pyupgrade/_plugins/abspath_file.py 2022-01-01
01:43:09.000000000 +0100
@@ -0,0 +1,53 @@
+import ast
+from typing import Iterable
+from typing import List
+from typing import Tuple
+
+from tokenize_rt import Offset
+from tokenize_rt import Token
+
+from pyupgrade._ast_helpers import ast_to_offset
+from pyupgrade._data import register
+from pyupgrade._data import State
+from pyupgrade._data import TokenFunc
+from pyupgrade._token_helpers import find_closing_bracket
+from pyupgrade._token_helpers import find_open_paren
+
+
+def _remove_abspath(i: int, tokens: List[Token]) -> None:
+ paren_start = find_open_paren(tokens, i + 1)
+ paren_end = find_closing_bracket(tokens, paren_start)
+ while i <= paren_start:
+ tokens[i] = Token('PLACEHOLDER', '')
+ i += 1
+ tokens[paren_end] = Token('PLACEHOLDER', '')
+
+
+@register(ast.Call)
+def visit_Call(
+ state: State,
+ node: ast.Call,
+ parent: ast.AST,
+) -> Iterable[Tuple[Offset, TokenFunc]]:
+ if (
+ state.settings.min_version >= (3, 9) and
+ (
+ (
+ isinstance(node.func, ast.Name) and
+ node.func.id == 'abspath' and
+ node.func.id in state.from_imports['os.path']
+ ) or
+ (
+ isinstance(node.func, ast.Attribute) and
+ isinstance(node.func.value, ast.Attribute) and
+ isinstance(node.func.value.value, ast.Name) and
+ node.func.value.value.id == 'os' and
+ node.func.value.attr == 'path' and
+ node.func.attr == 'abspath'
+ )
+ ) and
+ len(node.args) == 1 and
+ isinstance(node.args[0], ast.Name) and
+ node.args[0].id == '__file__'
+ ):
+ yield ast_to_offset(node), _remove_abspath
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyupgrade-2.29.1/pyupgrade/_plugins/format_locals.py
new/pyupgrade-2.31.0/pyupgrade/_plugins/format_locals.py
--- old/pyupgrade-2.29.1/pyupgrade/_plugins/format_locals.py 1970-01-01
01:00:00.000000000 +0100
+++ new/pyupgrade-2.31.0/pyupgrade/_plugins/format_locals.py 2022-01-01
01:43:09.000000000 +0100
@@ -0,0 +1,49 @@
+import ast
+from typing import Iterable
+from typing import List
+from typing import Tuple
+
+from tokenize_rt import Offset
+from tokenize_rt import rfind_string_parts
+from tokenize_rt import Token
+
+from pyupgrade._ast_helpers import ast_to_offset
+from pyupgrade._data import register
+from pyupgrade._data import State
+from pyupgrade._data import TokenFunc
+from pyupgrade._token_helpers import find_closing_bracket
+from pyupgrade._token_helpers import find_open_paren
+from pyupgrade._token_helpers import find_token
+
+
+def _fix(i: int, tokens: List[Token]) -> None:
+ dot_pos = find_token(tokens, i, '.')
+ open_pos = find_open_paren(tokens, dot_pos)
+ close_pos = find_closing_bracket(tokens, open_pos)
+ for string_idx in rfind_string_parts(tokens, dot_pos - 1):
+ tok = tokens[string_idx]
+ tokens[string_idx] = tok._replace(src=f'f{tok.src}')
+ del tokens[dot_pos:close_pos + 1]
+
+
+@register(ast.Call)
+def visit_Call(
+ state: State,
+ node: ast.Call,
+ parent: ast.AST,
+) -> Iterable[Tuple[Offset, TokenFunc]]:
+ if (
+ state.settings.min_version >= (3, 6) and
+ isinstance(node.func, ast.Attribute) and
+ isinstance(node.func.value, ast.Str) and
+ node.func.attr == 'format' and
+ len(node.args) == 0 and
+ len(node.keywords) == 1 and
+ node.keywords[0].arg is None and
+ isinstance(node.keywords[0].value, ast.Call) and
+ isinstance(node.keywords[0].value.func, ast.Name) and
+ node.keywords[0].value.func.id == 'locals' and
+ len(node.keywords[0].value.args) == 0 and
+ len(node.keywords[0].value.keywords) == 0
+ ):
+ yield ast_to_offset(node), _fix
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyupgrade-2.29.1/pyupgrade/_plugins/six_calls.py
new/pyupgrade-2.31.0/pyupgrade/_plugins/six_calls.py
--- old/pyupgrade-2.29.1/pyupgrade/_plugins/six_calls.py 2021-11-16
02:13:55.000000000 +0100
+++ new/pyupgrade-2.31.0/pyupgrade/_plugins/six_calls.py 2022-01-01
01:43:09.000000000 +0100
@@ -25,7 +25,7 @@
ast.Await, ast.BinOp, ast.BoolOp, ast.Compare, ast.GeneratorExp, ast.IfExp,
ast.Lambda, ast.UnaryOp,
)
-if sys.version_info >= (3, 8): # pragma: no cover (py38+)
+if sys.version_info >= (3, 8): # pragma: >=3.8 cover
_EXPR_NEEDS_PARENS += (ast.NamedExpr,)
SIX_CALLS = {
@@ -172,13 +172,21 @@
('reraise',),
)
):
- if len(node.args) == 2 and not has_starargs(node):
+ if (
+ len(node.args) == 2 and
+ not node.keywords and
+ not has_starargs(node)
+ ):
func = functools.partial(
find_and_replace_call,
template=RERAISE_2_TMPL,
)
yield ast_to_offset(node), func
- elif len(node.args) == 3 and not has_starargs(node):
+ elif (
+ len(node.args) == 3 and
+ not node.keywords and
+ not has_starargs(node)
+ ):
func = functools.partial(
find_and_replace_call,
template=RERAISE_3_TMPL,
@@ -186,6 +194,7 @@
yield ast_to_offset(node), func
elif (
len(node.args) == 1 and
+ not node.keywords and
isinstance(node.args[0], ast.Starred) and
isinstance(node.args[0].value, ast.Call) and
is_name_attr(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyupgrade-2.29.1/pyupgrade/_plugins/typing_pep563.py
new/pyupgrade-2.31.0/pyupgrade/_plugins/typing_pep563.py
--- old/pyupgrade-2.29.1/pyupgrade/_plugins/typing_pep563.py 2021-11-16
02:13:55.000000000 +0100
+++ new/pyupgrade-2.31.0/pyupgrade/_plugins/typing_pep563.py 2022-01-01
01:43:09.000000000 +0100
@@ -94,18 +94,15 @@
def _process_subscript(node: ast.Subscript) -> Iterable[ast.AST]:
name = _get_name(node.value)
if name == 'Annotated':
- if sys.version_info >= (3, 9): # pragma: no cover (py39+)
- node_slice: ast.expr = node.slice
- elif isinstance(node.slice, ast.Index): # pragma: no cover (<py39)
- node_slice = node.slice.value
- else: # pragma: no cover (<py39)
- pass # unexpected slice type
+ if sys.version_info >= (3, 9): # pragma: >=3.9 cover
+ node_slice = node.slice
+ elif isinstance(node.slice, ast.Index): # pragma: <3.9 cover
+ node_slice: ast.AST = node.slice.value
+ else: # pragma: <3.9 cover
+ node_slice = node.slice
- if isinstance(node_slice, ast.Tuple):
- if node_slice.elts:
- yield node_slice.elts[0]
- else:
- raise AssertionError(f'expected ast.Tuple: {ast.dump(node_slice)}')
+ if isinstance(node_slice, ast.Tuple) and node_slice.elts:
+ yield node_slice.elts[0]
elif name != 'Literal':
yield node.slice
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyupgrade-2.29.1/pyupgrade/_plugins/typing_pep604.py
new/pyupgrade-2.31.0/pyupgrade/_plugins/typing_pep604.py
--- old/pyupgrade-2.29.1/pyupgrade/_plugins/typing_pep604.py 2021-11-16
02:13:55.000000000 +0100
+++ new/pyupgrade-2.31.0/pyupgrade/_plugins/typing_pep604.py 2022-01-01
01:43:09.000000000 +0100
@@ -158,12 +158,15 @@
if is_name_attr(node.value, state.from_imports, 'typing', ('Optional',)):
yield ast_to_offset(node), _fix_optional
elif is_name_attr(node.value, state.from_imports, 'typing', ('Union',)):
- if sys.version_info >= (3, 9): # pragma: no cover (py39+)
- node_slice: ast.expr = node.slice
- elif isinstance(node.slice, ast.Index): # pragma: no cover (<py39)
- node_slice = node.slice.value
- else: # pragma: no cover (<py39)
- return # unexpected slice type
+ if sys.version_info >= (3, 9): # pragma: >=3.9 cover
+ node_slice = node.slice
+ elif isinstance(node.slice, ast.Index): # pragma: <3.9 cover
+ node_slice: ast.AST = node.slice.value
+ else: # pragma: <3.9 cover
+ node_slice = node.slice # unexpected slice type
+
+ if isinstance(node_slice, ast.Slice): # not a valid annotation
+ return
if isinstance(node_slice, ast.Tuple):
if node_slice.elts:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyupgrade-2.29.1/pyupgrade/_string_helpers.py
new/pyupgrade-2.31.0/pyupgrade/_string_helpers.py
--- old/pyupgrade-2.29.1/pyupgrade/_string_helpers.py 2021-11-16
02:13:55.000000000 +0100
+++ new/pyupgrade-2.31.0/pyupgrade/_string_helpers.py 2022-01-01
01:43:09.000000000 +0100
@@ -3,9 +3,9 @@
import string
import sys
-if sys.version_info >= (3, 7): # pragma: no cover (py37+)
+if sys.version_info >= (3, 7): # pragma: >=3.7 cover
is_ascii = str.isascii
-else: # pragma: no cover (<py37)
+else: # pragma: <3.7 cover
def is_ascii(s: str) -> bool:
return all(c in string.printable for c in s)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyupgrade-2.29.1/pyupgrade/_token_helpers.py
new/pyupgrade-2.31.0/pyupgrade/_token_helpers.py
--- old/pyupgrade-2.29.1/pyupgrade/_token_helpers.py 2021-11-16
02:13:55.000000000 +0100
+++ new/pyupgrade-2.31.0/pyupgrade/_token_helpers.py 2022-01-01
01:43:09.000000000 +0100
@@ -65,14 +65,14 @@
return i
-if sys.version_info >= (3, 8): # pragma: no cover (py38+)
+if sys.version_info >= (3, 8): # pragma: >=3.8 cover
# python 3.8 fixed the offsets of generators / tuples
def _arg_token_index(tokens: List[Token], i: int, arg: ast.expr) -> int:
idx = _search_until(tokens, i, arg) + 1
while idx < len(tokens) and tokens[idx].name in NON_CODING_TOKENS:
idx += 1
return idx
-else: # pragma: no cover (<py38)
+else: # pragma: <3.8 cover
def _arg_token_index(tokens: List[Token], i: int, arg: ast.expr) -> int:
# lists containing non-tuples report the first element correctly
if isinstance(arg, ast.List):
@@ -502,12 +502,12 @@
def find_comprehension_opening_bracket(i: int, tokens: List[Token]) -> int:
"""Find opening bracket of comprehension given first argument."""
- if sys.version_info < (3, 8): # pragma: no cover (py38+)
+ if sys.version_info < (3, 8): # pragma: <3.8 cover
i -= 1
while not (tokens[i].name == 'OP' and tokens[i].src == '[') and i:
i -= 1
return i
- else: # pragma: no cover (<py38)
+ else: # pragma: >=3.8 cover
return i
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyupgrade-2.29.1/requirements-dev.txt
new/pyupgrade-2.31.0/requirements-dev.txt
--- old/pyupgrade-2.29.1/requirements-dev.txt 2021-11-16 02:13:55.000000000
+0100
+++ new/pyupgrade-2.31.0/requirements-dev.txt 2022-01-01 01:43:09.000000000
+0100
@@ -1,3 +1,3 @@
-covdefaults
+covdefaults>=2.1.0
coverage
pytest
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyupgrade-2.29.1/setup.cfg
new/pyupgrade-2.31.0/setup.cfg
--- old/pyupgrade-2.29.1/setup.cfg 2021-11-16 02:13:55.000000000 +0100
+++ new/pyupgrade-2.31.0/setup.cfg 2022-01-01 01:43:09.000000000 +0100
@@ -1,6 +1,6 @@
[metadata]
name = pyupgrade
-version = 2.29.1
+version = 2.31.0
description = A tool to automatically upgrade syntax for newer versions.
long_description = file: README.md
long_description_content_type = text/markdown
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyupgrade-2.29.1/tests/features/abspath_file_test.py
new/pyupgrade-2.31.0/tests/features/abspath_file_test.py
--- old/pyupgrade-2.29.1/tests/features/abspath_file_test.py 1970-01-01
01:00:00.000000000 +0100
+++ new/pyupgrade-2.31.0/tests/features/abspath_file_test.py 2022-01-01
01:43:09.000000000 +0100
@@ -0,0 +1,52 @@
+import pytest
+
+from pyupgrade._data import Settings
+from pyupgrade._main import _fix_plugins
+
+
[email protected](
+ ('s', 'expected'),
+ (
+ pytest.param(
+ 'from os.path import abspath\n'
+ 'abspath(__file__)',
+ 'from os.path import abspath\n'
+ '__file__',
+ id='abspath',
+ ),
+ pytest.param(
+ 'import os\n'
+ 'os.path.abspath(__file__)',
+ 'import os\n'
+ '__file__',
+ id='os.path.abspath',
+ ),
+ ),
+)
+def test_fix_abspath_file(s, expected):
+ ret = _fix_plugins(s, settings=Settings(min_version=(3, 9)))
+ assert ret == expected
+
+
[email protected](
+ 's, min_version',
+ (
+ pytest.param(
+ 'abspath(__file__)',
+ (3, 8),
+ id='Not Python3.9+',
+ ),
+ pytest.param(
+ 'os.path.abspath(file)',
+ (3, 9),
+ id='Abspath of not-__file__',
+ ),
+ pytest.param(
+ 'os.path.abspath(file, foo)',
+ (3, 9),
+ id='Garbage (don\'t rewrite)',
+ ),
+ ),
+)
+def test_fix_abspath_file_noop(s, min_version):
+ assert _fix_plugins(s, settings=Settings(min_version=min_version)) == s
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/pyupgrade-2.29.1/tests/features/format_locals_test.py
new/pyupgrade-2.31.0/tests/features/format_locals_test.py
--- old/pyupgrade-2.29.1/tests/features/format_locals_test.py 1970-01-01
01:00:00.000000000 +0100
+++ new/pyupgrade-2.31.0/tests/features/format_locals_test.py 2022-01-01
01:43:09.000000000 +0100
@@ -0,0 +1,53 @@
+import pytest
+
+from pyupgrade._data import Settings
+from pyupgrade._main import _fix_plugins
+
+
[email protected](
+ ('s', 'version'),
+ (
+ pytest.param(
+ '"{x}".format(**locals())',
+ (3,),
+ id='not 3.6+',
+ ),
+ pytest.param(
+ '"{x} {y}".format(x, **locals())',
+ (3, 6),
+ id='mixed locals() and params',
+ ),
+ ),
+)
+def test_fix_format_locals_noop(s, version):
+ assert _fix_plugins(s, settings=Settings(min_version=version)) == s
+
+
[email protected](
+ ('s', 'expected'),
+ (
+ pytest.param(
+ '"{x}".format(**locals())',
+ 'f"{x}"',
+ id='normal case',
+ ),
+ pytest.param(
+ '"{x}" "{y}".format(**locals())',
+ 'f"{x}" f"{y}"',
+ id='joined strings',
+ ),
+ pytest.param(
+ '(\n'
+ ' "{x}"\n'
+ ' "{y}"\n'
+ ').format(**locals())\n',
+ '(\n'
+ ' f"{x}"\n'
+ ' f"{y}"\n'
+ ')\n',
+ id='joined strings with parens',
+ ),
+ ),
+)
+def test_fix_format_locals(s, expected):
+ assert _fix_plugins(s, settings=Settings(min_version=(3, 6))) == expected
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyupgrade-2.29.1/tests/features/fstrings_test.py
new/pyupgrade-2.31.0/tests/features/fstrings_test.py
--- old/pyupgrade-2.29.1/tests/features/fstrings_test.py 2021-11-16
02:13:55.000000000 +0100
+++ new/pyupgrade-2.31.0/tests/features/fstrings_test.py 2022-01-01
01:43:09.000000000 +0100
@@ -61,8 +61,6 @@
r'f"\N{snowman} {a}"',
id='named escape sequences',
),
- # TODO: poor man's f-strings?
- # '"{foo}".format(**locals())'
),
)
def test_fix_fstrings(s, expected):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyupgrade-2.29.1/tests/features/six_test.py
new/pyupgrade-2.31.0/tests/features/six_test.py
--- old/pyupgrade-2.29.1/tests/features/six_test.py 2021-11-16
02:13:55.000000000 +0100
+++ new/pyupgrade-2.31.0/tests/features/six_test.py 2022-01-01
01:43:09.000000000 +0100
@@ -24,6 +24,7 @@
'class C(six.with_metaclass(Meta, B), D): pass',
# cannot determine args to rewrite them
'six.reraise(*err)', 'six.u(*a)',
+ 'six.reraise(a, b, tb=c)',
'class C(six.with_metaclass(*a)): pass',
'@six.add_metaclass(*a)\n'
'class C: pass\n',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/pyupgrade-2.29.1/tests/features/typing_pep563_test.py
new/pyupgrade-2.31.0/tests/features/typing_pep563_test.py
--- old/pyupgrade-2.29.1/tests/features/typing_pep563_test.py 2021-11-16
02:13:55.000000000 +0100
+++ new/pyupgrade-2.31.0/tests/features/typing_pep563_test.py 2022-01-01
01:43:09.000000000 +0100
@@ -57,6 +57,12 @@
(3,),
id='Kwonly, untyped',
),
+ pytest.param(
+ 'from __future__ import annotations\n'
+ 'x: Annotated[1:2] = ...\n',
+ (3,),
+ id='Annotated with invalid slice',
+ ),
),
)
def test_fix_typing_pep563_noop(s, version):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/pyupgrade-2.29.1/tests/features/typing_pep604_test.py
new/pyupgrade-2.31.0/tests/features/typing_pep604_test.py
--- old/pyupgrade-2.29.1/tests/features/typing_pep604_test.py 2021-11-16
02:13:55.000000000 +0100
+++ new/pyupgrade-2.31.0/tests/features/typing_pep604_test.py 2022-01-01
01:43:09.000000000 +0100
@@ -54,6 +54,12 @@
(3, 10),
id='3.10+ Union of forward reference',
),
+ pytest.param(
+ 'from typing import Union\n'
+ 'def f() -> Union[1:2]: ...\n',
+ (3, 10),
+ id='invalid Union slicing',
+ ),
),
)
def test_fix_pep604_types_noop(s, version):