Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I read project dependencies from pyproject.toml from my setup.py, to avoid duplicating the information in both files?

We're upgrading to use BeeWare's Briefcase 0.3.1 for packaging, which uses pyproject.toml instead of setup.py to specify how to package, including which dependencies to include in a package.

Here's a minimal example of a pyproject.toml for briefcase:

[tool.briefcase.app.exampleapp]
formal_name = "exampleapp"
description = "something"
requires = ['PyQt5', 'qtconsole']
sources = ['exampleapp']

We'd like to access the list of requires from setup.py, so we wouldn't have to replicate it in both files, and keep them in sync. We're not ready to switch away from setuptools, this is only for packaging. The alternative is of course to let setup.py auto-generate the pyproject.toml file, but that seems a little backwards to the intention with PEP 518.

like image 336
Dybber Avatar asked Jun 13 '20 16:06

Dybber


People also ask

What is Pyproject toml used for?

What is pyproject. toml? 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.

Does pip support Pyproject toml?

Yes, pyproject. toml is the specified file format of PEP 518 which contains the build system requirements of Python projects. This solves the build-tool dependency chicken and egg problem, i.e. pip can read pyproject.

How do I use toml files in Python?

You specify them with a <key> = <value> syntax, where the key is separated from the value with an equal sign. The following is a valid TOML document with one key-value pair: greeting = "Hello, TOML!" In this example, greeting is the key, while "Hello, TOML!" is the value.

Is setup py deprecated?

You may still find advice all over the place that involves invoking setup.py directly, but unfortunately this is no longer good advice because as of the last few years all direct invocations of setup.py are effectively deprecated in favor of invocations via purpose-built and/or standards-based CLI tools like pip, build ...

What is pyproject TOML?

What is pyproject.toml? 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.

How should dependencies be laid out in a project's metadata?

There is a standard called PEP 621 that specifies how a project's metadata, including dependencies, should be laid out in the pyproject.toml file. Here is a list of build back-ends I know of that have support for PEP 621: For all PEP 621 compatible build back-ends, the dependencies should be written in pyproject.toml file like in the following:

How do I create a project with dependencies in Python?

To interactively create a pyproject.toml file in directory pre-existing-project: If you want to add dependencies to your project, you can specify them in the tool.poetry.dependencies section. As you can see, it takes a mapping of package names and version constraints.

What is the difference between setup config and TOML in pyproject?

It is worth noting that setup.cfg is an ini format file, and pyproject.toml is a slightly more formal ini-like format. What is pyproject.toml?


1 Answers

As far as I can tell, briefcase isn't actually PEP 517 compatible (at least not by default). It uses a pyproject.toml file, but doesn't fill up the [build-system] section, so it should be possible to set an actual PEP 517 build backend in that file without causing conflict.

pyproject.toml

[build-system]
build-backend = 'setuptools.build_meta'
requires = [
    'setuptools',
    'toml',
]

[tool.briefcase.app.exampleapp]
formal_name = 'exampleapp'
description = 'something'
requires = ['PyQt5', 'qtconsole']
sources = ['exampleapp']

setup.py

#!/usr/bin/env python3

import pathlib

import pkg_resources
import setuptools
import toml

def _parse_briefcase_toml(pyproject_path, app_name):
    pyproject_text = pyproject_path.read_text()
    pyproject_data = toml.loads(pyproject_text)
    briefcase_data = pyproject_data['tool']['briefcase']
    app_data = briefcase_data['app'][app_name]
    setup_data = {
        'name': pkg_resources.safe_name(app_data['formal_name']),
        'version': briefcase_data['version'],
        'install_requires': app_data['requires'],
        # ...
    }
    return setup_data

def _setup():
    app_name = 'exampleapp'
    pyproject_path = pathlib.Path('pyproject.toml')
    setup_data = _parse_briefcase_toml(pyproject_path, app_name)
    setuptools.setup(**setup_data)

if __name__ == '__main__':
    _setup()

Then pip and other PEP 517-compatible frontends should be able to build and install the project by delegating to setuptools while taking care to correctly setup a build environment containing both setuptools and toml.

I guess it would be also possible to let briefcase handle the parsing of the pyproject.toml file (maybe with briefcase.config.parse_config(...)) but it's not documented so I don't know how stable these APIs are.

like image 68
sinoroc Avatar answered Oct 19 '22 23:10

sinoroc