Setup.cfg File

0 views
Skip to first unread message

Dinah Lianes

unread,
Aug 4, 2024, 4:11:39 PM8/4/24
to gantcharsappto
Ifcompatibility with legacy builds (i.e. those not using the PEP 517build API) is desired, a setup.py file containing a setup() functioncall is still required even if your configuration resides in setup.cfg.

In this example, the value for the package_dirconfiguration (i.e. =src) is parsed as "": "src".The "" key has a special meaning in this context, and indicates that all thepackages are contained inside the given directory.Also note that the value for [options.packages.find] where matches thevalue associated with "" in the package_dir dictionary.


It is advisable to use literal values together with attr: (e.g. str,tuple[str], see ast.literal_eval()). This is recommendin order to support the common case of a literal value assigned to a variablein a module containing (directly or indirectly) third-party imports.


If you are using an old version of setuptools, you might need to ensurethat all files referenced by the file: directive are included in the sdist(you can do that via MANIFEST.in or using plugins such as setuptools-scm,please have a look on Controlling files in the distribution for more information).


The find: and find_namespace: directive can be further configuredin a dedicated subsection options.packages.find. This subsection accepts thesame keys as the setuptools.find_packages and thesetuptools.find_namespace_packages function:where, include, and exclude.


This blog post is designed to clarify my thinking around installing Python packages and the use of setup.py, setup.cfg and pyproject.toml files. Hopefully it will be a useful reference for other people, and future me.


It is stimulated by my starting work on a new project where we have been discussing best practices in Python programming, and how to layout a git repository containing Python code. More broadly it is relevant to me as someone who programmes a lot in Python, mainly for my own local use, but increasingly for other people to consume my code. Prior to writing this the layout of my Python repositories was by a system of random inheritance dating back a number of years.


The minimal setup.py file simply contains an invocation of the setuptools setup function, if you do not intend to publish your project then no setup.py file is required at all, pip install -e . will work without it:


It is common and recommended practice to use virtual environments for work in Python. I use the Anaconda distribution of Python in which we setup and activate a virtual environment using the following, to be run before the pip install statement


The setup.py and setup.cfg files are artefacts of the setuptools module which is designed to help with the packaging process. It is used by pip whose purpose is to install a package either locally or remotely. If we do not configure setup.py/setup.cfg correctly then pip will not work. In the past we would have written a setup.py file which contained a bunch of configuration information but now we should put that configuration information into setup.cfg which is effectively an ini format file (i.e. does not need to be executed to be read). This is why we now have the minimal setup.py file.


The pyproject.toml file was introduced in PEP-518 (2016) as a way of separating configuration of the build system from a specific, optional library (setuptools) and also enabling setuptools to install itself without already being installed. Subsequently PEP-621 (2020) introduces the idea that the pyproject.toml file be used for wider project configuration and PEP-660 (2021) proposes finally doing away with the need for setup.py for editable installation using pip.


Tests go in a tests directory at the top-level of the project with an __init__.py file so they are discoverable by applications like pytest. The alternative of placing them inside the src/mypackage directory means they will get deployed into production which may not be desirable.


I've worked as a scientist for the last 30 years, at various universities, a large home and personal care company, a startup in Liverpool called The Sensible Code Company (formerly ScraperWiki Ltd), GBG and now as a consultant in data science.


The Python Packaging Tutorial recommends that "Static metadata (setup.cfg) should be preferred. Dynamic metadata (setup.py) should be used only as an escape hatch when absolutely necessary. setup.py used to be required, but can be omitted with newer versions of setuptools and pip."


The guide to packaging and distributing projects explains that "setup.cfg is an ini file that contains option defaults for setup.py commands. For an example, see the setup.cfg in the PyPA sample project."


That example is entirely useless, and there doesn't appear to be a lot of other helpful information. The examples in the tutorial suggest that some, or perhaps all, valid arguments to setuptools.setup() can be listed in setup.cfg, but there is no real explanation to this effect. In particular, it's not clear how to translate a list argument, like that for the very common and important install_requires parameter, into lines in setup.cfg.


I would like to add some datafiles to my PyPi package. This documentation for setup.cfg is aimed at someone more expert than me. It states the following without any explanation of what the elements are:


Static metadata ( setup.cfg ) should be preferred. Dynamic metadata ( setup.py ) should be used only as an escape hatch when absolutely necessary. setup.py used to be required, but can be omitted with newer versions of setuptools and pip.


The asterisk matches any package in your source tree that happens to contain a myapp.dat or myapp.html. Where are these files located in your repository? Package data only works if the files are actually located inside your Python package (the folder with the actual *.py files) to begin with.


So you decided you want to make a python package thats awesome! But after reading through the documentation and numerous blog posts you might be feeling utterly confused as to what exactly you need to make a pypi package. I'm here to explain the connections between pyproject.toml, setup.cfg andsetup.py .I'll show you how you can make sure your project will be future proof.


pyproject.toml tells pip what build tools it needs to build sdist and wheels. Before pyproject.toml was introduced pip had no way of knowing what build tools (tools like peotry, setuptools, etc.) it needed to use to build the wheel for your project. With pyproject.toml you can specify exactly what version of the build tool you need to correctly build your pip package in your virtual environment. For example, the following pyproject.toml tells pip the build tool it needs to build your package with setuptools, specifically a version greater than or equal to 61.0.




You need it because it tells pip what build tools pip needs to use build your package in your virtual environment. Not to mention setup.py is (deprecated)[ ] so you should declare you package's metadata in your pyproject.toml file too. Of course you can also specify the project's metadata in your setup.cfg if you'd like too, but I prefer to keep it all in pyproject.toml.

Additionally, certain tools like poetry and flit use this file to specify how to build you package, its dependencies, etc. This article explains more in detail how poetry uses the pyproject.toml. If you want to know how to structure your pyproject.toml file check out the guide I wrote.


setup.py is a script that can executed on the command line that is used to build a source distribution and wheel for your package with the command setup.py sdist setup.py bdist_wheel . You can also declare metadata and package options in your setup.py. However, I do not recommend you use setup.py as it is being deprecated. Instead you should use pyproject.toml to declare your package's metadata and build dependencies.


You shouldn't use setup.py because its deprecated instead you should use pyproject.toml to declare the build tools and metadata for your package. You shouldn't invoke setup.py directly to perform tasks like uploading to pypi or building you package. The following table shows what commands to use instead of the deprecated setup.py commands:


This table I got from Why you should not invoke setup.py directly. It explains why setup.py shouldn't be used as well as why there is so much confusion around why setup.py shouldn't be used. I highly recommend reading it if you are wondering why setup.py is being deprecated.


A setup.cfg is a configuration file used to declare the metadata for your package. Metadata is information that describes your package such as package's name, version, description, etc. All this information can be included in your setup.cfg or your pyproject.toml. If you want more details on how to use setup.cfg check out setuptools page.


Hi,

I am facing a problem trying to install my plugin with pip install -e .

I have a torch package to install from an url with pip which is normally done using pip install torch -f /the/link.

Apparently setup.cfg can read an argument called dependency_links, but when i do that it is ignored and it does not work:


The reason is that the pytest team intends to fully utilize the rich TOML data formatfor configuration in the future, reserving the [tool.pytest] table for that.The ini_options table is being used, for now, as a bridge between the existing.ini configuration system and the future configuration format.


Usage of setup.cfg is not recommended unless for very simple use cases. .cfgfiles use a different parser than pytest.ini and tox.ini which might cause hard to trackdown problems.When possible, it is recommended to use the latter files, or pyproject.toml, to hold yourpytest configuration.


pytest determines a rootdir for each test run which depends onthe command line arguments (specified test files, paths) and onthe existence of configuration files. The determined rootdir and configfile areprinted as part of the pytest header during startup.


Is used by plugins as a stable location to store project/test run specific information;for example, the internal cache plugin creates a .pytest_cache subdirectoryin rootdir to store its cross-test run state.

3a8082e126
Reply all
Reply to author
Forward
0 new messages