重现我遇到的问题:
poetry new pysnmp-and-mypy
cd ./pysnmp-and-mypy
poetry add mypy
poetry add pysnmp-lextudio
touch ./pysnmp_and_mypy/test.py
将以下代码放入
./pysnmp_and_mypy/test.py
:
from pysnmp.hlapi import * # type: ignore
from typing import Any
def convert_snmp_type_to_python_type(
snmp_value: Integer32 | Integer | Unsigned32 | Gauge32 | OctetString | Any,
) -> int | str:
match snmp_value:
case Integer32():
return int(snmp_value)
case Integer():
return int(snmp_value)
case Unsigned32():
return int(snmp_value)
case Gauge32():
return int(snmp_value)
case OctetString():
return str(snmp_value)
case _:
raise TypeError(
"Only SNMP types of type integer and string are supported. Received type of {}".format(
str(type(snmp_value))
)
)
def get_data(ip_address: str, object_identity: str) -> int | str:
iterator = getCmd(
SnmpEngine(),
CommunityData("public", mpModel=0),
UdpTransportTarget((ip_address, 161)),
ContextData(),
ObjectType(ObjectIdentity(object_identity)),
)
error_indication, error_status, error_index, variable_bindings = next(iterator)
if error_indication:
raise RuntimeError(error_indication.prettyPrint())
elif error_status:
raise RuntimeError(error_status.prettyPrint())
else:
[variable_binding] = variable_bindings
[_oid, value] = variable_binding
return convert_snmp_type_to_python_type(value)
运行:
poetry install
poetry run mypy ./pysnmp_and_mypy
现在观察返回以下错误:
pysnmp_and_mypy\test.py:6: error: Name "Integer32" is not defined [name-defined]
pysnmp_and_mypy\test.py:6: error: Name "Integer" is not defined [name-defined]
pysnmp_and_mypy\test.py:6: error: Name "Unsigned32" is not defined [name-defined]
pysnmp_and_mypy\test.py:6: error: Name "Gauge32" is not defined [name-defined]
pysnmp_and_mypy\test.py:6: error: Name "OctetString" is not defined [name-defined]
pysnmp_and_mypy\test.py:9: error: Name "Integer32" is not defined [name-defined]
pysnmp_and_mypy\test.py:11: error: Name "Integer" is not defined [name-defined]
pysnmp_and_mypy\test.py:13: error: Name "Unsigned32" is not defined [name-defined]
pysnmp_and_mypy\test.py:15: error: Name "Gauge32" is not defined [name-defined]
pysnmp_and_mypy\test.py:17: error: Name "OctetString" is not defined [name-defined]
pysnmp_and_mypy\test.py:28: error: Name "getCmd" is not defined [name-defined]
pysnmp_and_mypy\test.py:29: error: Name "SnmpEngine" is not defined [name-defined]
pysnmp_and_mypy\test.py:30: error: Name "CommunityData" is not defined [name-defined]
pysnmp_and_mypy\test.py:31: error: Name "UdpTransportTarget" is not defined [name-defined]
pysnmp_and_mypy\test.py:32: error: Name "ContextData" is not defined [name-defined]
pysnmp_and_mypy\test.py:33: error: Name "ObjectType" is not defined [name-defined]
pysnmp_and_mypy\test.py:33: error: Name "ObjectIdentity" is not defined [name-defined]
如何以适当的方式消除这些错误?为什么 MyPy 找不到定义?它们肯定在那里,因为代码运行得很好,而且 Pylance 找到它们也没有问题。如果没有好的方法,最好的解决方法是什么?
请注意,我必须这样做
from pysnmp.hlapi import * # type: ignore
,否则我会收到错误 error: Skipping analyzing "pysnmp.hlapi": module is installed, but missing library stubs or py.typed marker [import-untyped]
。
从原始问题中的有用评论中获得的一种可能的解决方案是显式导入所有使用的类型和函数。在这种情况下,以下内容允许 MyPy 通过。
from pysnmp.hlapi import ( # type: ignore
Integer32,
Integer,
Unsigned32,
Gauge32,
OctetString,
Integer32,
Integer,
Unsigned32,
Gauge32,
OctetString,
SnmpEngine,
ObjectType,
ObjectIdentity,
SnmpEngine,
ObjectType,
ObjectIdentity,
Integer,
getCmd,
setCmd,
CommunityData,
UdpTransportTarget,
ContextData,
)
请注意,我仍然需要为第一行提供忽略注释以消除错误:
error: Skipping analyzing "pysnmp.hlapi": module is installed, but missing library stubs or py.typed marker [import-untyped]
note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
看来这个忽略注释是明确包含它的行,因为将其放置在导入“块”之后(在带有右括号的行上不起作用,并且还会产生
error: Unused "type: ignore" comment [unused-ignore]"
。