Pip包:从依赖关系中公开类成员类型提示



我写了一个python模块:

b.py

class B:
pass

a.py

from b import B
class A:
def __init__(self):
self.member: B = B()

__init__.py

from ab_package.a import A
from ab_package.b import B

我使用极简主义的setup.py文件将其打包并安装在pip中


setup(
name='ab_package',
version='0.0.1',
description='My AB package',
url='https://github.com/somewhere',
author='Me',
author_email='me@somedomain.com',
license='Private',
packages=['ab'],
install_requires=['numpy>=1.19.5',
'pandas>=1.3.3',
'pylint==2.11.1',
'pyparsing~=2.4.7',
'requests~=2.26.0',
'wget~=3.2',
],
classifiers=[
],
)

然后在另一个项目中,我使用它:

from ab_package import A, B
a = A()
myvar = a.member

问题是在PyCharm中,myvar被推断为Any

我可以修复显式类型提示myvar,但这不够简洁(尤其是当我的类型比B长得多时(。

我怎样才能使推理按预期进行?

在您显示的示例代码中,推断b的类型为Any是一个更严重问题的症状,即当您尝试在赋值语句中查找a.b时,将得到一个AttributeError。类型检查器mypy正确地将其标识为错误,正如您在这里看到的那样。我不确定PyCharm的内置类型检查在这里会有什么不同,尽管我希望它也能识别错误。

如果您更改了代码,使您在A.__init__中创建的B实例成为一个属性,那么代码就会起作用,并且可以推断类型,至少可以通过mypy:推断

class B:
pass
class A:
def __init__(self):
self.b: B = B()   # change member to self.b here
a = A()
b = a.b
reveal_type(b) # type checker reports __main__.B for me, should be ab_package.b.B for you

正如@Blckknht所说,问题来自于在包中Python文件之间的相对导入。

如果我只是在b的导入中添加一个点,使其成为a.py中的from .b import B,那么a.member具有正确的推断类型(以及myvar(。

a.py

from .b import B
class A:
def __init__(self):
self.member: B = B()

最新更新