我正在尝试转换此py2类:
class Example(object):
def __unicode__(self):
return unicode(42) # unicode(self.id)
def __str__(self):
return unicode(self).encode('u8')
__repr__ = __str__
到具有以下类型的组合2/3版本:
import sys
from typing import Text
from builtins import str as text
class Example(object):
def _as_unicode(self): # type: () -> Text
return text(42)
__unicode__ = _as_unicode
def _as_bytes(self): # type: () -> bytes
return self._as_unicode().encode('utf-8')
def __str__(self): # type: () -> str
if sys.version_info.major == 2:
return self._as_bytes() # line 17
else:
return self._as_unicode() # line 19
__repr__ = __str__
这将产生以下错误:
c:\tmp> py -3 -m mypy example.py
example.py:17: error: Incompatible return value type (got "bytes", expected "str")
c:\tmp> py -3 -m mypy example.py -2
example.py:19: error: Incompatible return value type (got "unicode", expected "str")
有没有办法使mypy相信
__str__
的类型是copacetic的?(还有一种更好的方法以2 + 3兼容的方式编写此代码吗?)
最佳答案
正确的方法实际上是不要试图找到可以桥接两个Python版本的类型,而要让mypy理解您的分支将仅在特定版本的Python上运行。
为此,将sys.version_info.major == 2
更改为类似于sys.version_info[0] == 2
的检查,例如:
import sys
from typing import Text
from builtins import str as text
class Example(object):
def _as_unicode(self): # type: () -> Text
return text(42)
def _as_bytes(self): # type: () -> bytes
return self._as_unicode().encode('utf-8')
def __str__(self): # type: () -> str
if sys.version_info[0] == 2:
return self._as_bytes()
else:
return self._as_unicode()
__unicode__ = _as_unicode
__repr__ = __str__
最终完全避开了您的问题。例如。由于在Python 2.7模式下进行类型检查时,“ else”分支被标记为不可访问,因此mypy不会尝试分析该分支,因此不会报告错误。
如果需要,可以更进一步,对
__str__
的整个定义进行if-else运算:import sys
from typing import Text
from builtins import str as text
class Example(object):
def _as_unicode(self): # type: () -> Text
return text(42)
def _as_bytes(self): # type: () -> bytes
return self._as_unicode().encode('utf-8')
if sys.version_info[0] == 2:
__str__ = _as_bytes
else:
__str__ = _as_unicode
__unicode__ = _as_unicode
__repr__ = __str__
这是一些more info on the version and platform checks mypy支持。
mypy无法具体理解
sys.version_info.major
格式的事实很可能是一个疏忽。您可以尝试在mypy's issue tracker上提交有关此问题的问题(尽管idk会优先考虑此问题的优先级,因为有简单的解决方法),或者您可以尝试自己修改consider_sys_version_info
函数in mypy/reachability.py
来为此添加支持。关于python - 2和3组合代码库中的__str__类型是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57483303/