- This chapter is part of the series:
- Please consider reading the previous chapter (Chapter 2) before moving forward. This chapter builds upon the project structure discussed in the previous chapter (Chapter 2).
-
From the previous chapter (Chapter 2), we have the following project structure:
- src/ - something/ - __init__.py - app.py - tests/ - __init__.py - test_app.py - .gitignore - LICENSE - pyproject.toml - README.md - requirements.txt - setup.cfg - setup.py Here we are going to setup
pytest,mypyandflake8.-
TABLE OF CONTENTS
3.1 Adding new dependencies to requirements
- Now we need to install more libraries. Namely
pytest,mypyandflake8. -
So our
requirements.txtfile looks something like this. We have added dependencies forpytest:
flake==3.9.4 tox==3.24.3 pytest==6.2.5 pytest-cov==2.12.1 mypy==0.910 Instead of directly overwriting the
requirements.txtfile, we create a new file calledrequirements_dev.txt. Since testing is required indevenvironment.-
So we have two requirement files:
-
requirements.txtwhich we use while running our code:
requests==2.26.0 -
requirements_dev.txtwhich holds dev dependencies like our test, lint and type check libraries.
flake==3.9.4 tox==3.24.3 pytest==6.2.5 pytest-cov==2.12.1 mypy==0.910
-
While running tests we will use
requirements_dev.txtfile to install dependencies.
3.2 Adding to our metadata in setup.cfg
-
Our
setup.cfgfile looks something like this:
[metadata] name = something description = just some dummy codebase author = Coding with Zim license = MIT license_file = LICENSE platforms = unix, linux, osx, cygwin, win32 classifiers = Programming Language :: Python :: 3 Programming Language :: Python :: 3 :: Only Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 [options] packages = something install_requires = requests>=2 python_requires = >=3.6 package_dir = =src zip_safe = no [options.extras_require] testing= pytest>=6.0 pytest-cov>=2.0 mypy>=0.910 flake8>=3.9 tox>=3.24 [options.package_data] something = py.typed [flake8] max-line-length = 160 options.extras_requireare optional dependencies. We can read more about it here: https://setuptools.pypa.io/en/latest/userguide/dependency_management.htmloptions.package_datais a type ofData File Support, we can read more about it here: https://setuptools.pypa.io/en/latest/userguide/datafiles.html. We are basically using it to denote that our code istype-hinted, which means we are using types in the code.For this to work we need to create a
py.typedblank file in our something directory alongside__init__.py.flake8is the configuration for theflake8linter that we will be using. Here we are only saying that the maximum line length is 160.So our
flake8configuration is stored in thecfgfile and ourpythonconfiguration is stored in ourpyproject.tomlfile.
3.3 Adding python configurations to pyproject.toml
-
Our
pyproject.tomlfile looks something like this:
[build-system] requires = ["setuptools>=42.0", "wheel"] build-backend = "setuptools.build_meta" [tool.pytest.ini_options] addopts = "--cov=something" testpaths = [ "tests", ] [tool.mypy] mypy_path = "src" check_untyped_defs = true disallow_any_generics = true ignore_missing_imports = true no_implicit_optional = true show_error_codes = true strict_equality = true warn_redundant_casts = true warn_return_any = true warn_unreachable = true warn_unused_configs = true no_implicit_reexport = true We already discussed about the
build-system.tool.pytest.ini_optionsarepytesttool options during the execution of tests. In our case we have added the--cov=somethingoption inaddoptsso that we see the test coverage.testpathsbasically denotes all the directories containing tests.tool.mypyaremypytool options. To learn aboutmypy: https://realpython.com/lessons/type-checking-mypy/#:~:text=“Mypy is an optional static,background on the Mypy project.-
So, now we install the
devdependencies withpip:
(env)yourproject$ pip install -r requirements_dev.txt -
Finally we should be able to run our test with
pytest, check linting withflake8and type check withmypy.
$ pytest # this command will test our code with default test discovery mechanism. $ mypy # this command will run type checks on our code with mypy. $ flake8 # this command will check code linting.
Top comments (0)