自动升级新版本语法的工具。
pyupgrade的Python项目详细描述
pyupgrade
自动升级新语法的工具(和预提交挂钩) 语言的版本。
安装
pip install pyupgrade
作为预提交挂钩
有关说明,请参见pre-commit。
样本.pre-commit-config.yaml
:
-repo:https://github.com/asottile/pyupgraderev:v1.23.0hooks:-id:pyupgrade
实现的功能
设置文字
set(())# set()set([])# set()set((1,))# {1}set((1,2))# {1, 2}set([1,2])# {1, 2}set(xforxiny)# {x for x in y}set([xforxiny])# {x for x in y}
字典理解
dict((a,b)fora,biny)# {a: b for a, b in y}dict([(a,b)fora,biny])# {a: b for a, b in y}
python2.7+格式说明符
'{0}{1}'.format(1,2)# '{} {}'.format(1, 2)'{0}''{1}'.format(1,2)# '{}' '{}'.format(1, 2)
打印样式字符串格式
可用性:
- 除非通过
--keep-percent-format
。
'%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文本
可用性:
- 文件导入
from __future__ import unicode_literals
--py3-plus
在命令行上传递。
u'foo'# 'foo'u"foo"# 'foo'u'''foo'''# '''foo'''
无效转义序列
# 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 python3u'\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`# but in python3.x, that's our friend ☃
is
/is not
与常量文本的比较
在python3.8+中,与文本的比较成为一个成功的SyntaxWarning
其中的比较是特定于实现的(由于公共对象缓存)。
xis5# x == 5xisnot5# x != 5xis'foo'# x == foo
ur
字符串文本
ur'...'
文本在python 3.x中无效
ur'foo'# u'foo'ur'\s'# u'\\s'# unicode escapes are left aloneur'\u2603'# u'\u2603'ur'\U0001f643'# u'\U0001f643'
.encode()
到字节文本
'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'
长文字
5L# 55l# 5123456789123456789123456789L# 123456789123456789123456789
八进制文字
0755 # 0o755
05 # 5
在print(...)
对python-modernize/python-modernize#178
的修复print(())# ok: printing an empty tupleprint((1,))# ok: printing a tuplesum((iforiinrange(3)),[])# ok: parenthesized generator argumentprint(("foo"))# print("foo")
super()
调用
可用性:
--py3-plus
在命令行上传递。
classC(Base):deff(self):super(C,self).f()# super().f()
“新风格”课程
可用性:
--py3-plus
在命令行上传递。
classC(object):pass# class C: passclassC(B,object):pass# class C(B): pass
强制str("native")
文本
可用性:
--py3-plus
在命令行上传递。
str()# "''"str("foo")# "foo"
.encode("utf-8")
可用性:
--py3-plus
在命令行上传递。
"foo".encode("utf-8")# "foo".encode()
# coding: ...
注释
可用性:
--py3-plus
在命令行上传递。
从PEP 3120开始,python源代码的默认编码是utf-8
-# coding: utf-8
x = 1
yield
=>;yield from
可用性:
--py3-plus
在命令行上传递。
deff():forxiny:# yield from yyieldxfora,binc:# yield from cyield(a,b)
if PY2
块
可用性:
--py3-plus
在命令行上传递。
# inputifsix.PY2:# also understands `six.PY3` and `not` and `sys.version_info`print('py2')else:print('py3')# outputprint('py3')
删除six
兼容代码
可用性:
--py3-plus
在命令行上传递。
six.text_type# strsix.binary_type# bytessix.class_types# (type,)six.string_types# (str,)six.integer_types# (int,)six.unichr# chrsix.iterbytes# itersix.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)fromsiximporttext_typetext_type# str@six.python_2_unicode_compatible# decorator is removedclassC:def__str__(self):returnu'C()'classC(six.Iterator):pass# class C: passclassC(six.with_metaclass(M,B)):pass# class C(B, metaclass=M): pass@six.add_metaclass(M)# class C(B, metaclass=M): passclassC(B):passisinstance(...,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.iteritems(dct)# dct.items()six.iterkeys(dct)# dct.keys()six.itervalues(dct)# dct.values()six.viewitems(dct)# dct.items()six.viewkeys(dct)# dct.keys()six.viewvalues(dct)# dct.values()six.create_unbound_method(fn,cls)# fnsix.get_unbound_method(meth)# methsix.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.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)
open
别名
可用性:
--py3-plus
在命令行上传递。
# inputwithio.open('f.txt')asf:pass# outputwithopen('f.txt')asf:pass
OSError
别名
可用性:
--py3-plus
在命令行上传递。
# input# also understands:# - IOError# - WindowsError# - mmap.error and uses of `from mmap import error`# - select.error and uses of `from select import error`# - socket.error and uses of `from socket import error`try:raiseEnvironmentError('boom')exceptEnvironmentError:raise# outputtry:raiseOSError('boom')exceptOSError:raise
F字符串
可用性:
--py36-plus
在命令行上传递。
'{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}'
note:pyupgrade
是故意的timid,不会创建f字符串
如果它会使表达式更长,或者替换参数是
任何东西,除了简单的名字或虚线名称(因为这会降低可读性)。