black icon indicating copy to clipboard operation
black copied to clipboard

Use PEP 621's [project.requires-python] field to automatically set --target-version

Open GamePad64 opened this issue 3 years ago • 12 comments

PEP 621 provides project.requires-python field in pyproject.toml. I expect, that most of the tools will support this field eventually. Each code-related linter and formatter has a setting for supported python version.

Using this field would be good for tool interoperability in the future.

Related: https://github.com/psf/black/issues/751#issuecomment-778441893

GamePad64 avatar Jun 17 '22 10:06 GamePad64

I'm in favour.

ichard26 avatar Jun 28 '22 15:06 ichard26

When it makes sense, I'm in favor of moving everything we can to pyproject.toml long as it does not break mypyc etc. etc.

cooperlees avatar Jun 28 '22 16:06 cooperlees

I looked into this. It should be easy enough to augment the parse_pyproject_toml function to also read the project.requires-python field.

However, parsing that field is another matter. We would probably have to rely on a third party library if we really want to do this properly. And I'm not sure it's worth introducing a dependency in order to be able to automatically infer the target version.

Input is appreciated!

stinodego avatar Jul 31 '22 05:07 stinodego

FWIW, I hacked something similiar in my GitHub workflow to feed pyupgrade with the appropriate --py3-plus / --py36-plus / (...) / --py311-plus option flags.

kdeldycke avatar Jul 31 '22 05:07 kdeldycke

@kdeldycke If a new version of python is out you will need to modify the file no ? Can we erase the check <= 11

SamirPS avatar Jul 31 '22 06:07 SamirPS

I indeed looked at poetry-core for the version parsing. But if you wanted to use their version parser (it's quite extensive), you'd have to add it as a dependency, which feels quite bad.

stinodego avatar Jul 31 '22 09:07 stinodego

I hope to see this feature being added and maybe in a way that it would make it easy to reuse in other tools as updating min-python in so many tools is a PITA and almost a guarantee that you will forget to update one of them.

ssbarnea avatar Aug 02 '22 08:08 ssbarnea

We could also probably use packaging.specifiers.SpecifierSet to parse [project].python-requires. Not sure whether to hard depend on packaging or add it as an extra since it's not core Black functionality.

ichard26 avatar Aug 11 '22 00:08 ichard26

We could also probably use packaging.specifiers.SpecifierSet to parse [project].python-requires. Not sure whether to hard depend on packaging or add it as an extra since it's not core Black functionality.

packaging was a great suggestion - it does exactly what we need. I have a working implementation now; will open a PR when I have added tests.

I'll first add it as a hard dependency - we can adjust in code review if required.

stinodego avatar Aug 12 '22 19:08 stinodego

That's great, thank you for looking into this! I look forward to the PR :)

ichard26 avatar Aug 12 '22 19:08 ichard26

The Requires-Python metadata can be in pyproject.toml, setup.cfg or setup.py.

Would Black only support reading from pyproject.toml?

I usually put it in setup.cfg, but am fine if Black only wants to read pyproject.toml, because it's already doing so for other config. (And it may also drive further pyproject.toml adoption.)

hugovk avatar Aug 13 '22 10:08 hugovk

I wouldn't want Black to read other config files than pyproject.toml; that's asking for a lot of additional complexity.

JelleZijlstra avatar Aug 13 '22 13:08 JelleZijlstra

@kdeldycke If a new version of python is out you will need to modify the file no ? Can we erase the check <= 11

Hey @SamirPS, just noticed your comment. Since then I indeed removed the hard-coded check on Python <= 3.11. My code to produce Black's --target-version parameters is now future-proof.

Since #3219 has been released upstream in v23.1.0, we still need my custom code for Poetry-based projects. Black only looks for the PEP-621's requires-python marker in the pyproject.toml file. Not Poetry's [tool.poetry.dependencies] > python = "^3.7" specifiers.

kdeldycke avatar Feb 02 '23 07:02 kdeldycke

I hope to see this feature being added and maybe in a way that it would make it easy to reuse in other tools as updating min-python in so many tools is a PITA and almost a guarantee that you will forget to update one of them.

Agreed @ssbarnea. I had to write some code to produce consistent Python target parameters for Black, Mypy and Pyupgrade.

For more details, see my metadata.py script in my reuseable workflows that I try to use everywhere in my Python projects.

kdeldycke avatar Feb 02 '23 07:02 kdeldycke