python / mypy

Optional static typing for Python
https://www.mypy-lang.org/
Other
18.61k stars 2.85k forks source link

Support for pyproject.toml #5205

Closed pslacerda closed 3 years ago

pslacerda commented 6 years ago

PEP518 says that pyproject.toml is to support the minimum build requirements. I want to consider mypy as part of the minimum build on my package.

For example Pip uses a [tool.towncrier] section on pyproject.toml to generate a correctly updated NEWS.rst as part of its build. One can considers typing correctness as important to the distributed source pakcage as an well documented NEWS.rst. Other example is Black that also has it section on pyproject.toml.

Maybe you think that this is a silly feature request and that setup.cfg must be used instead, Pip or Flit or whatever can setup mypy after all. But an TOML module will be added to the standard library sooner or later, than could mypy accept this feature and antecipate TOML supporting pyproject.toml today?

ilevkivskyi commented 6 years ago

PEP 518 is accepted and specifies that pyproject.toml is preferred over setup.cfg, so I think we should support whatever the PEP specifies.

gvanrossum commented 6 years ago

Does adding pyproject.toml mean that we can remove other config files? Until that point I'm not excited.

pslacerda commented 6 years ago

I think that removing other config files would simplify config parsing even more. I would be very glad to change mypy.main.parse_config_file() accordingly.

If you agree that mypy==0.620 it is still in its early ages, would be exciting to remove the other config files. Otherwise I'm already coding the unexciting changes to support both legacy and pyproject.toml.

There is already lots of deprecated options:

--disallow-any
--strict-boolean
--dirty-stub
--use-python-pat
--silent-import
--almost-silen
--fast-parser
--no-fast-parser

So legacy config files (mypy.ini, setup.cfg and ~/.mypy.ini) could also be one of them.

gvanrossum commented 6 years ago

Note that mypy.ini serves a completely different purpose from setup.py, setup.cfg, and pyproject.toml. The mypy.ini file is read by mypy when it is about to type-check another program. The other files (IIUC) are used to build mypy itself. I don't think we can change mypy.ini much, though we can start removing deprecated flags (after they have been printing a warning for 1-2 release cycles). Please do that in a separate PR.

pslacerda commented 6 years ago

Even if setup.cfg was created originally for distutils or setuptools, everybody else seems to use it as an generic configuration file. PyTest for example don't care if is running from setup.py or whatever, it simply reads setup.cfg if it is found; many tools seems to do it (eg flake8, isort and even mypy).

If you are talking about to replace setup.py by pyproject.toml, yes it is indeed an legibility win.

Now taking about mypy config files when type-checking other programs, they are all equivalents and fallbacks of the next one (--config-file -> mypy.ini -> setup.cfg -> ~/.mypy.ini; http://mypy.readthedocs.io/en/latest/config_file.html. I'm talking to deprecate these ini-like config files and use toml, it is even more typed!

I will submit a PR to remove that flags later on.

pslacerda commented 6 years ago

To put it clear: enable sections like [tool.mypy] or [tool.mypy-somepackage] in pyproject.toml.

gvanrossum commented 6 years ago

Switching mypy.ini to a toml thing sounds like scope creep and we won't have the time and motivation to review PRs related to this, so please don't start on that. The rest is fine of course.

pslacerda commented 6 years ago

Seems that I misunderstood that to remove others would be necessary to the overral comunity need to target the same. Sorry.

Does adding pyproject.toml mean that we can remove other config files? Until that point I'm not excited.

JelleZijlstra commented 6 years ago

So what exactly is being proposed here?

There's a few things I can think of:

emmatyping commented 6 years ago

Pytest seems to be stalled until someone works on it https://github.com/pytest-dev/pytest/issues/1556

An issue for flake8 was opened yesterday https://gitlab.com/pycqa/flake8/issues/428

And the same for coverage https://bitbucket.org/ned/coveragepy/issues/664/allow-configuration-via-pyprojecttoml

I think we should add support for reading mypy's configuration from pyproject.toml, but it looks like we will need to wait to use it for our own config.

pslacerda commented 6 years ago

@JelleZijlstra

The first option. IMHO were some convergence towards each_project.ini then setup.cfg and now towards pyproject.toml. The messy that was tooling configuration seems to be finally ending. Indeed I have some sort of working code, a TOML library was required but pretty much can be packed together instead.

https://github.com/python/mypy/compare/master...pslacerda:feature/pep518

But also the second option.

@ethanhs, seems that as more and more projects adopt it, more sense has to put all that config files centralized. There is divergent opinions for projects with very large pytest.ini, flake8.ini and so on. So maybe individual config files should continue where they are.

pslacerda commented 6 years ago

Maybe that branch isn't so rudimentary and maybe you allow I submmit this PR.

EDIT: there is a bug that nested tables dont flatten correctly here. I need to work more on it.

gvanrossum commented 6 years ago

If you do want to continue this discussion please do submit the PR. Please understand that doesn't mean it will be accepted.

gvanrossum commented 6 years ago

Thanks -- I finally understand that TOML is meant as an alternative to mypy.ini. My apologies for not understanding this earlier. There is no particular urgency for this, is there? The PR is nice to have but we'll need to find time to review it carefully. Also, did you add tests?

pslacerda commented 6 years ago

Take your time to review, there is no urgency. I adapted some tests and also put my opinions on the PR.

gvanrossum commented 6 years ago

I've rejected the PR, and I'm going to close this issue. I don't think this solves a real problem for mypy. Sorry!

pslacerda commented 6 years ago

I'm saying that mypy is a build/test time requirement in my projects.

gvanrossum commented 6 years ago

PEP 518 doesn't say that all build/test requirements must use pyproject.toml for their own configuration. It only says that the list of packages to be installed must be specified there (as opposed to in a parameter to the setup() call in setup.py).

and-semakin commented 5 years ago

Hey, it would be nice to remove setup.cfg and completely switch to using fresh modern pyproject.toml but we can't do this because of mypy :disappointed:

JelleZijlstra commented 5 years ago

There's actually some risk in doing that. http://github.com/python/black only supports pyproject.toml as its configuration file, but this has caused grief for various users because the mere presence of pyproject.toml causes some versions of pip to process packages differently, even if pyproject.toml contained only Black configuration files.

chancecarey commented 5 years ago

There's actually some risk in doing that. http://github.com/python/black only supports pyproject.toml as its configuration file, but this has caused grief for various users because the mere presence of pyproject.toml causes some versions of pip to process packages differently, even if pyproject.toml contained only Black configuration files.

I don't think that's a reasonable concern. PEP 518 indicates that pyproject.toml is "the way forward". That some tools fail to parse it correctly is on them, it shouldn't be used as evidence that implementing support for pyproject.toml is a bad thing.

chancecarey commented 5 years ago

@gvanrossum

I've rejected the PR, and I'm going to close this issue. I don't think this solves a real problem for mypy. Sorry!

Perhaps not for mypy, but I think having a good standard format and place to store config for tools that are used during development is a boon. PEP 518 does specify a [tool] section, and comments on it:

The [tool] table is where any tool related to your Python project, not just build tools, can have users specify configuration data as long as they use a sub-table within [tool], e.g. the flit tool would store its configuration in [tool.flit]

prokher commented 5 years ago

@gvanrossum

I've rejected the PR, and I'm going to close this issue. I don't think this solves a real problem for mypy. Sorry!

Indeed, MyPy's support of pyproject.toml does not solve a real problem now. But taking into account the inter-language competition we have (Python vs JS vs Go vs TypeScript vs ...) everything matters. Especially if we recall that the population of software engineers grow at a high rate and languages basically fight for newcomers. I think that today the beauty of the ecosystem is as important as the beauty of the language itself. Python is a beautiful and expressive language, but why should I have all this configuration-management-related files in the root of every Python project I work on (.pylintrc, .mypyrc, setup.py, setup.cfg, isort.cfg, ...)? It just looks ugly IMHO. I agree, it is not a serious problem to fight against, but pyproject.toml is already here and it is seems not to be a big deal to support it in MyPy. Moreover this could be a good example for other Python tools to follow. So one day we can end with a single configuration file for every Python project, it would be nice.

Just sharing.

chancecarey commented 5 years ago

@prokher

but pyproject.toml is already here and it is seems not to be a big deal to support it in MyPy

Indeed, and someone already has a working PR ...

pslacerda commented 5 years ago

Don't really belong here, but just remembering the situation right now.

image

PgLoLo commented 5 years ago

Please, add pyproject.toml support

NargiT commented 5 years ago

PEP 518 doesn't say that all build/test requirements must use pyproject.toml for their own configuration. It only says that the list of packages to be installed must be specified there (as opposed to in a parameter to the setup() call in setup.py).

Allow me to disagree. source: https://www.python.org/dev/peps/pep-0518/#tool-table

The [tool] table is where any tool related to your Python project, not just build tools, can have users specify configuration data as long as they use a sub-table within [tool], e.g. the flit tool would store its configuration in [tool.flit].

We need some mechanism to allocate names within the tool.* namespace, to make sure that different projects don't attempt to use the same sub-table and collide. Our rule is that a project can use the subtable tool.$NAME if, and only if, they own the entry for $NAME in the Cheeseshop/PyPI.

As an example, tox plan to also support fully pyproject.toml "https://tox.readthedocs.io/en/latest/example/basic.html#pyproject-toml-tox-legacy-ini".

JukkaL commented 5 years ago

There seems to be quite a bit of interest in adding pyproject.toml support. We can reconsider accepting a PR, but I'd like to understand this a bit better first. Hopefully somebody can help with these questions:

  1. Which notable developer tools currently (Aug 2019) support storing their configuration in pyproject.toml files in [tool.foo] sections?
  2. Which notable open source Python projects use the [tool.foo] sections in their pyproject.toml files?

I'm basically trying to understand how mature and widespread the use of the [tool] section is at the moment.

We would still continue to support mypy.ini files, as requiring every user to migrate to pyproject.toml would be too disruptive.

impredicative commented 5 years ago

@JukkaL black is the only notable tool I am aware of in static analysis (and/or autoformatting) circles that meets # 1. Many more including mypy support setup.cfg and that is good and important. I don't think anyone should have to migrate to pyproject.toml in the short to medium term, but all of these tools do need to come together and use a single file. It's atrocious the number of such files I have to have in a project.

In general I see no harm in adding support, but right now it won't help me until other setup.cfg supporting tools like pycodestyle, pydocstyle, and pytest also do the same. Thanks.

chancecarey commented 5 years ago

@JukkaL

Tox currently has a naive implementation but plans to implement full support soon - https://tox.readthedocs.io/en/latest/example/basic.html#pyproject-toml-tox-legacy-ini

Black uses pyproject.toml for config exclusively - https://black.readthedocs.io/en/stable/pyproject_toml.html

Flit uses pyproject.toml (soon exclusively) - https://flit.readthedocs.io/en/latest/pyproject_toml.html

isort uses pyproject.toml.

Those are some of the most known tools I can find that use it. Flake8 has a well supported issue open about supporting pyproject.toml. The community is, imo, largely moving in this direction.

pslacerda commented 5 years ago

Many projects uses pyproject.toml, some exclusively (which is too much for most of us). Both are required for most projects keep going. A deprecation warning could stimulate the adoption of pyproject.toml.

EDIT: there is nothing stopping programs like 2to3 to convert projects into pyproject.toml. Also github bots could make pull requests almost trivially given that the program was done. The program itself is mostly a bunch of fields to be unserialized from legacy and serialized into pyproject.toml. Seems very cool.

prokher commented 5 years ago

I would also mention Poetry: https://poetry.eustace.io

chancecarey commented 5 years ago

@JukkaL any chance we could get this issue re-opened?

JukkaL commented 5 years ago

I'm reopening the issue for discussion, but we are not committing to any timeline yet.

emmatyping commented 5 years ago

By the way, if we do go ahead with this, I'm happy to help review/maintain the code, if that helps.

DaniGuardiola commented 5 years ago

Managed to remove a bunch of python configuration files thanks to pyproject.toml. The only remaining file is setup.cfg because of mypy. I can live with it, but it is pretty annoying. Just my two cents. Would really appreciate support for pyproject.toml.

pslacerda commented 5 years ago

@DaniGuardiola Some years ago I thought that require pyproject.toml was too much. Only one project I was trying out (Black) required it, all other tools accepted setup.cfg. It was too much ahead and I had a similar annoying felling but in the reverse. Now the situation changed and more projects started to adopt pyproject.toml, Tox for instance. I miss pytest.

TOML has a so better syntax and typing that could alleviate user configuration bugs if adopted I guess. Its syntax is easy but more complex than ini files and because of this not everybody can support it into their own programs (myself for instance) without a library. However it isn't that much of a problem because there is a library for that.

I'd love to have my PR accepted. It worked well for me last year but if @ethanhs deem it unsuitable wouldn't be that hard for someone to do another PR.

The conversion of user files from setup.cfg to pyproject.toml is so trivial (at least in all files I saw) that a Github bot can scan projects that use Mypy, Tox, isort and so on do the PRs itself.

I hope that this issue get resolved soon and some pull request get merged (hopefully mine) because not only is a demanded that will reduce annoy but also because maybe it will reduce bugs.

flying-sheep commented 5 years ago

PEP 518 was accepted and its “Rejected ideas” section contains “sticking with setup.cfg”, which together means that setup.cfg is deprecated as a place to put project-wide static tool configuration.

Therefore I think reopening #5208 and eventually deprecating and then removing setup.cfg support everywhere would make sense.

emmatyping commented 5 years ago

Hi, I have no objections to the PR at face value, but the team would like to have more discussion on this.

I personally would like to see this happen but I cannot speak for the team as a whole.

Adding another config format would make maintenance harder, which we want to avoid.

That being said, if @flying-sheep's interpretation of the PEP is correct, then we can probably kill setup.cfg support and support pyproject.toml. However based on my understanding, it is not correct. I will ask on discuss.python.org for suggestions from the packaging folks.

flying-sheep commented 5 years ago

I understand your concerns. As a maintainer myself, I know the pains of slowly transitioning to “the new way” in terms of maintenance. However (not that I imply you proposed this): I don’t think it’s fair to have the stance “we’ll switch last, if adoption gets high”. That’s a self-fulfilling prophecy if many think this way.

I think the only way to be a good open source citizen is to switch early, support both ways until many projects support the new standard, and then remove the old way. At first it looks like the only way that’s more painful is supporting both indefinitely, but you can soft-deprecate the old way: Just stop maintaining it but leave it in. If any bug surfaces with setup.cfg parsing, tell people to switch to pyproject.toml. This is essentially as high a maintenancy burden as only supporting pyproject.toml.

/edit: Just realized I wrote “maintenancy”. That sounds like a very practical discipline/branch of magic :laughing:

danieljanes commented 5 years ago

@JukkaL as of Dec 2019, amongst the major tools we use, 3/5 have support for pyproject.toml:

Support:

No support:

JukkaL commented 5 years ago

It looks like pyproject.toml is gaining enough traction that we can accept a PR that adds support for it.

chancecarey commented 5 years ago

@JukkaL There was a PR for this previously - https://github.com/python/mypy/pull/5208

But Guido closed it.

JukkaL commented 5 years ago

Maybe the original PR can be resurrected?

JukkaL commented 5 years ago

I've reopened #5208.

pslacerda commented 4 years ago

How to handle options specific to package/module?

[mypy]
some_opt = 1

# is it acceptable?
[mypy."specific.*.module"]
some_opt = 2
flying-sheep commented 4 years ago

As @layday said, I’d think

[mypy.overrides."specific.*.module"]
some_opt = 2
# or
[mypy.overrides.specific."*".module]
some_opt = 2
layday commented 4 years ago

Note that the latter example expands into

{'mypy': {'overrides': {'specific': {'*': {'module': {'some_opt': 2}}}}}}

which is almost certainly not what we want.

pslacerda commented 4 years ago

I'm now aware. Handy in case someone needs to parse the file by themselves (like a GitHub bot that converts setup.cfg into pyproject.toml).

[mypy.overrides."specific.*.module"]
some_opt = 2
# or
[mypy.overrides."other.*.package"]
some_opt = 2
chadgh commented 4 years ago

Here is the awesome-pyproject list. It would be helpful if and when mypy supports pyproject.toml to notify the list maintainer or submitting a PR to update the list indicating that mypy supports the file now. Just FYI. :)