Status of "`pyproject.toml` presence triggers different pip behavior"

I was about to recommend someone add a pyproject.toml file to their project to declare build-time dependencies following PEP 518, but then I remembered these old threads about the presence of the file triggering potentially problematic behavior for old projects:

These threads are old though, and I understand that lots of things have changed ever since. What is the current status of the issue? Should users still be wary of the presence of pyproject.toml files on their projects? Or with the standardization of editable installs etc are all the shortcomings basically solved?

pip still uses the presence of pyproject.toml as a signal that it can use isolated builds for editable installs.

In my experience, this doesn’t cause too many problems, so I think after various bugs were fixed most people just moved on from complaining about it. To me it seems checking for the [build-system] table in pyproject.toml would probably have been better, but that ship has probably sailed. So don’t get your hopes up for flake8 supporting pyproject.toml!

In particular, for pure Python packages the only problem I’ve had is that isolated builds cause editable installs via pip to be 2-3x slower.

For extension modules, isolated builds matter more since you tend to actually have build requirements. For the most part when it’s come up for me, it’s the kind of breakage that’s good and leaves you with more reproducible builds going forward. It can be annoying if you need a specific build of some package installed in your build environment though.


There’s no major missing bits of functionality with pyproject.toml-based builds but there’s still a difference in behaviours. As noted in Build System Interface - pip documentation v22.2.2, we’re working toward removing non-isolated builds via direct invocations within pip entirely, at some point in the future.

For that to happen though, there’s a few missing pieces: using proper virtual environments for the isolation, killing install and speeding up the build times via caching/reusing build environments (eg: setuptools + wheel is a common base environment setup).

This is the tracking issue:


OT: I truly don’t understand their intransigence on this point. The folks who want to use flake8 with pyproject.toml have already accepted the differences implied by having a pyproject.toml. But I digress. There is some hope they will add a configuration hook that plugins can use, at least. :crossed_fingers:

This is unfortunate, as flake8 really is the last hold out for fully embracing pyproject.toml, at least for the tools I use in OSS and in my work environment. In the interest of minimizing config files, I’m at least glad you can configure flake8 in tox.ini and that’s what I use. I’ve been able to completely ditch and setup.cfg and am not looking back.

I’m mixed on whether tox should also fully support pyproject.toml. I know they have the legacy config, but putting a string in pyproject.toml isn’t compelling enough. I’m also not totally sure I want pyproject.toml to replace tox.ini in my code. I kind of like separating local development and project metadata/installation requirements, but OTOH maybe one ring to rule them all would be better in the long run.

1 Like

This tweet (and those around it) have some relevant context on the flake8/pyproject.toml situation.

A part of the problem for flake8 is that the configuration system is closely coupled with the ini file format and exposed to plugins; causing a mix of compatibiility, implementation and migration concerns.

1 Like

pre-commit (notably, by the same author as flake8) is also a holdout, though admittedly with a better rationale in that case (at least until toml widely supports more hierarchical data better).

A part of the problem for flake8 is that the configuration system is closely coupled with the ini file format and exposed to plugins; causing a mix of compatibiility, implementation and migration concerns.

I actually made an issue regarding a new plugin hook that would allow overriding config collection, so that at least there could be a supported path self-service here. I even offered to submit a PR for it, but was asked not to. However, things did, in fact, look rather simple to me, with one function that returns a dict[str, Any] that gets merged with cmdline args then used by subsequent codepaths. So TBH I don’t understand those comments, but :man_shrugging: guess I must have missed some details somewhere.

Love the snark abut “8 config files instead of 9” though—currently we have three config files instead of one, and two of them are for his tools. :rofl:

1 Like

In general, I think no. Now is a great time to fully embrace pyproject.toml and get rid of the legacy setuptools stuff. It’s not completely seamless though. One thing that would help my projects is some additional standardization in the config_settings that are passed to the backends. For example, I reported a problem to pdm-pep517 where its default use of a build/ directory clobbered a similarly named directory used by my work’s build system. If I could define the build directory in a standard way in pyproject.toml and ensure that that was passed in a consistent way to any build backend through the config_settings dictionary, it would help us out a lot.


The concept of a temporary build directory in the project directory is backend-specific; Hatchling does not do that and never will.

As far as config_settings goes, I find it generally useless/unintuitive, so Hatchling uses environment variables.

1 Like

pre-commit is not specific to Python projects; it’s a development tool which happens to be written in Python. If we’re gonna draw the line somewhere, I think that’s a pretty good place.


Thanks all for your answers. To be clear, I was not asking this to debate the flake8 situation - I couldn’t care less about having one more config file.

I’ll keep an eye on Default to isolated, pyproject.toml-based builds · Issue #9175 · pypa/pip · GitHub (I was already subscribed apparently).

1 Like