Keywords
Some external links to resources about organising, building, deploying, and distributing Python projects and Python environment management.
Some things to note:
- Whilst it is not officially deprecated, direct use of
setup.py
is no longer recommended (although asetup.py
can optionally be generated). The modern approach is to usepyproject.toml
as defined in PEP 518. - In Python there are often many (sometimes too many) ways of doing things, especially when it comes to environment management, version management, and package management. Some forum postings may zealously introduce someone's pet approach as the way of doing something, and sometimes without even alerting you to the existence of alternatives.
"The Zen of Python" states:
"There should be one—and preferably only one—obvious way to do it."
What a shame that this is less applicable to actually working with Python in practice on real projects than to just about any other language.
For MacOS, Webel IT Australia recommends the Homebrew version of pyenv for managing more than one Python version on your system (visit also this guide). But whatever Python version management tool works for you on your own system will be enormously helpful, as it's often necessary to work with different Python versions between projects.
If you are working with a good IDE such as JetBrains IntelliJ IDEA (or PyCharm) you can associate each project with a different Python version, classpath(s), a set of installed modules, and a (typically project specific) virtual environment venv
, which in JetBrains terminology is denoted a Python SDK. You can also create a virtual environment SDK that may be shared by multiple projects, which then share a virtual environment folder – which may have any name - and the modules installed into it.
venv-3.8.13
that indicates the associated Python version. If one of the client project evolves and is then not compatible with the indicated Python version it's a good hint that it should instead have its own venv.
You can also manage each venv
and activate the one that is current as seen from a shell command line; details depend on your operating system. Module installs with pip
will then install under the active venv
folder. Visit also this primer, which also has a nice Cheat Sheet PDF download. Using a per-project venv
is nearly always a good idea, and well worth learning about early on.
If you are just working on a self-contained Python project as a sole developer you may be completely content with the setup provided by your IDE (and may even not be aware of all of the possible project deployment metadata settings), but if you wish to distribute your project you'll need to learn some of the standardised project organisation mechanisms. There's a comprehensive Python Packaging User Guide, which includes a glossary with some Python-specific terminology.
The package installer usually included with the main Python distributions is pip. You need to at least know how to pip install
as it's used in many online examples and tutorials, but there are also alternatives such as Poetry and Pipenv, which also serve as virtual environment managers. There are many other (too many) other alternatives amongst package installers and package managers, including Hatch, PDM, Rye, uv, and Ruff. Too many:
That package manager [insert whichever you don't use] sucks! You should use [insert whichever one you happen to use]!!
Dude, you only use Pip? You clearly aren't a real Python developer!
Anaconda (primarily used for data science and machine learning projects) has its own Conda package and environment manager.
The official upload tool for Python Package Index (PyPi) - which is not the only package index – is twine.
If you are new to Python, you may find the terminology module and package a little unusual. A module is a single file (usually with the .py
suffix) containing Python definitions and statements (the code). The term 'package' is used a little more loosely (it sometimes describes what is otherwise called a "library"), but when referring to namespaces defined by a folder/directory, there are two types of packages, a regular package (must have an __init__.py
even if it is empty) and a namespace packages (without an __init__.py
); the difference is explained well here.
A non-empty __init__.py
file can additionally be used to define the visibility of the contents of its parent package, to define package level variables, and to create convenience names. It can contain just about anything (but is also easily misused).
Originally defined as the PEP 427 – The Wheel Binary Package Format, a wheel is a ZIP-format archive with a single distribution. Sometimes you may also need to deal with sdists (source distributions). And you may still also encounter “Eggs”, which is an old package format that has been replaced with the wheel format. Visit also this guide on Package Formats.