Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
417 views
in Technique[技术] by (71.8m points)

pylint - Type checking tool for Python 3

I am trying to run a command that gives some aggregated information on type checking, static code analysis, etc. in some Python source code provided as a directory. If such thing exists, then I would like to add it to a Makefile invoked during some CI pipelines to validate a code base.

I've created this dummy source code file with a runtime issue

File foo_sample.py

def foo_func(my_num):
    return 1 + my_num


def bar_func():
    foo_func("foo")


if __name__ == "__main__":
    bar_func()

It throws this runtime error:

TypeError: unsupported operand type(s) for +: 'int' and 'str'.

Now I've tried to detect this type error with various tools, but they all fail to find these kind of problems. See the commands in the following list:

  • pyflakes foo_sample.py,
  • flake8 foo_sample.py,
  • pylint foo_sample.py,
  • mypy --check-untyped-defs foo_sample.py,
  • prospector --strictness veryhigh foo_sample.py

I know I could detect these issues with unittest, but the code base is quite large and untested to some degree. We frequently see runtime errors and address them with a unit test or an integration test. However, we would like to detect them during the execution of a CI pipeline.

Is there a way to run these kind of checks before running the code itself?

How can I avoid to discover these errors at runtime?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Undeclared types are considered to be of type Any, and are not type checked by mypy. A stricter configuration is necessary to make sure mypy forces you to set types. Specifically, you need disallow_untyped_defs, which should lead you to this result:

$ cat test.py 
def foo_func(my_num: int) -> int:
    return 1 + my_num


def bar_func() -> None:
    foo_func("foo")


if __name__ == "__main__":
    bar_func()
$ mypy test.py
test.py:6: error: Argument 1 to "foo_func" has incompatible type "str"; expected "int"
Found 1 error in 1 file (checked 1 source file)

You might also want disallow_any_generics and warn_return_any. Example configuration.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...