跳转至

Python 类型检查工具 beartype

Python 代码中的类型提示并不是需要强制满足的。如果我们希望代码使用者严格遵循类型提示,在类型不符时抛出错误,可以使用 beartype 进行类型检查。

安装

Bash
pip install beartype

使用

仅针对自己编写的代码

若我们正在开发一个 Python 包,并需要对这个包内的所有代码添加类型检查,可以在包的 __init__.py 文件中添加:

Python
from beartype.claw import beartype_this_package

beartype_this_package()

针对依赖的外部代码

若我们需要对依赖的外部代码进行类型提示,但不需要抛出错误,而是警告用户,可以用:

Python
# ....................{ BIG BEAR                        }....................
# Warn about type hint violations in *OTHER* packages outside your control;
# only raise exceptions from violations in your package under your control.
# Again, at the very top of your "{your_package}.__init__" submodule:
from beartype import BeartypeConf  # <-- this isn't your fault
from beartype.claw import (
    beartype_all,
    beartype_this_package,
)  # <-- you didn't sign up for this

beartype_this_package()  # <-- raise exceptions in your code
beartype_all(
    conf=BeartypeConf(violation_type=UserWarning)
)  # <-- emit warnings from other code

针对单个函数

若我们只需要对某个函数进行类型检查,可以使用装饰器:

Python
from beartype import beartype


# Annotate @beartype-decorated classes and callables with type hints.
@beartype  # <-- you too will believe in magic
def quote_wiggum(lines: list[str]) -> None:
    print("“{}\n\t— Police Chief Wiggum".format("\n ".join(lines)))

更多使用方法可以参考官方文档

不对某些内容进行类型检查

参考:How do I NOT type-check something?

方法 1:

Python
# Import the requisite machinery.
from beartype import beartype, BeartypeConf, BeartypeStrategy

# Dynamically create a new @nobeartype decorator disabling type-checking.
nobeartype = beartype(conf=BeartypeConf(strategy=BeartypeStrategy.O0))

# Avoid type-checking *ANY* methods or attributes of this class.
@nobeartype
class UncheckedDangerClassIsDangerous(object):
    # This method raises *NO* type-checking violation despite returning a
    # non-"None" value.
    def unchecked_danger_method_is_dangerous(self) -> None:
        return 'This string is not "None". Sadly, nobody cares anymore.'

方法 2:

Python
# Import more requisite machinery. It is requisite.
from beartype import beartype
from typing import no_type_check

# Avoid type-checking *ANY* methods or attributes of this class.
@no_type_check
class UncheckedRiskyClassRisksOurEntireHistoricalTimeline(object):
    # This method raises *NO* type-checking violation despite returning a
    # non-"None" value.
    def unchecked_risky_method_which_i_am_squinting_at(self) -> None:
        return 'This string is not "None". Why does nobody care? Why?'

评论