-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for additional predefined config file paths #2761
Conversation
Hi! Thanks for submitting this PR. If I recall correctly, when implementing config files initially, we considered using |
I prefer not to do this. To explain my reasoning (then and now): as a consumer of projects created by others I've often been confused by the rules for finding configuration data in seemingly randomly-named files like tox.ini (I've never heard of anyone who uses it) and setup.cfg, combined with directory searches. E.g. if there's a tox.ini in a subdirectory but a setup.cfg in the root directory of a project, which one wins, or are they combined somehow? |
I understand and this is something I've expected. I think my reasoning can be explained when we look at hypothetical open-source Python project, which decides to incorporate quite a few modern tools:
This project may also use other tools, which require configuration, but we'll ignore them (for instance it may use something like isort, probably have Now let's say some new developer decides to fork the repo and hack some things on it. Sooner or later, he will want to test/lint/typecheck/something his code. The project probably has some kind of What will be read?
One file per tool or shared configs. It's possible to stick everything into Mypy devs themselves have decided that flake8 and coverage.py can have their configs in Personally, I see (at least) two types of tools:
In the former, I believe they should have only dedicated files (and they do), because these are required to turn source code into a program. The latter should not, since they are only to help and it should be up to developers how to configure them. Since there is visible trend in the community to use Why I don't want that many files? Try to write a modern (defined as using FOTM frameworks and build tools) JS app and you'll see. Even django, despite being mostly Python codebase, has four JS-related configs in project root. A lot of people say JS ecosystem has some flaws in it, and, IMO, configs scattered all over the place contribute to it. Again, in my opinion, if an user wants to have mypy configured out of the box in his codebase, we shouldn't force him to create yet another file. If developers want to keep all configs in single place, noone will stop them and they will work around that in either way, e.g. telling contributors to run some tools with Lastly, regarding subdirectories and merging configs. AFAIK none of these tools do this and neither would mypy after merging this PR. It would look for
If mypy manages to read some file, it stops reading next. This why there won't be any file merging; I think noone does it and it'd be a hell of a nightmare to manage. Additionally - for already configured projects - if you have EDIT: |
I am still not convinced. The desire for fewer files in the project root is
honest, but naive. There are going to be tons of files there, like it or
not. It's just how the world works. And the rules for precedence when
multiple of these files exist are very murky (I know for a fact that a
setup.cfg in a subdirectory overrides one in a parent directory if you
point pytest to files in that subdirectory).
|
Given a chance to try to reverse this trend, why not take it? |
See my earlier reply. The multiple files are confusing. |
@gvanrossum, please consider reopening. The actual discussion has just begun to appear. I've brought up a topic on Python tools about using I'd be cautious when saying there will be tons of files anyway. I am using pytest, flake8, and mypy in my project and with this PR I can halve config files amount - to one. The rules for precedence are easy:
Subdirectory behavior is clear as well - mypy doesn't traverse directory tree looking for By the way, would you close PR with support for PEP 512? Like it or not, the community (at least some part of it) has agreed on And please don't say that Additionally, after @nedbat suggestion, I've dropped EDIT: |
I'll reopen, but I will continue to argue against. Look at https://github.com/python/mypy, the toplevel has already 18 different files, a majority of which are configuration of some sort or other. Maybe @ambv has an opinion? He's got more experience with a variety of tools like this than I have. (And I notice that he added a |
docs/source/command_line.rst
Outdated
and command line flags can override settings. See :ref:`config-file` | ||
for the syntax of configuration files. | ||
read from the given file. By default settings are read from ``mypy.ini``, | ||
``setup.cfg``, or ``tox.ini`` in the current directory. Settings override |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You still mention tox.ini here (and several other places). Also you should clarify that it stops at the first file it finds (here and in the next chapter).
I see flake8 and converage config are in the setup.cfg file now at https://github.com/python/mypy Note that pytest can also use setup.cfg (and tox.ini). See how they do it here: http://doc.pytest.org/en/latest/customize.html Some packages are really drowning in config file soup, with 20-30 config files! Hopefully at least all the python tools can agree on a common file for config. |
Sorry, didn't notice the @ until now. I added a That being said, I don't think additional support for
With those explicitly stated in the docs, I think there's little space for surprise on the user's end. Oh, and I agree that |
OK, you've convinced me. Is that the state of the PR currently? Then I will
merge it.
|
It is exactly as @ambv described. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bunch of style nits. We're almost there!
docs/source/command_line.rst
Outdated
@@ -344,10 +344,10 @@ Here are some more useful flags: | |||
.. _config-file-flag: | |||
|
|||
- ``--config-file CONFIG_FILE`` causes configuration settings to be | |||
read from the given file. By default settings are read from ``mypy.ini`` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please put the double spaces after periods back. They don't affect how the HTML is rendered, but they improve the quality of paragraph reflowing in Emacs.
docs/source/command_line.rst
Outdated
and command line flags can override settings. See :ref:`config-file` | ||
for the syntax of configuration files. | ||
read from the given file. By default settings are read from ``mypy.ini`` | ||
and ``setup.cfg`` in the current directory. Settings override mypy's |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe "and" -> "or" ?
docs/source/config_file.rst
Outdated
read a different file instead (see :ref:`--config-file <config-file-flag>`). | ||
|
||
It is important to understand that there is no merging of configuration | ||
files, as it would lead to disambiguity. The ``--config-file`` flag |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
drop "dis"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if I understood this correctly. You meant first sentence only, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually just meant to change "disambiguity" to "ambiguity". What you wrote was backwards. :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, you're absolutely right. Restored the sentence.
mypy/main.py
Outdated
"""Parse a config file into an Options object. | ||
|
||
Errors are written to stderr but are not fatal. | ||
|
||
If filename isn't provided, fall back to default config file and then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"isn't provided" -> "is None"
mypy/main.py
Outdated
"""Parse a config file into an Options object. | ||
|
||
Errors are written to stderr but are not fatal. | ||
|
||
If filename isn't provided, fall back to default config file and then | ||
to common shared files (currently setup.cfg). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would just say "to setup.cfg". If and when we change it we can update the comment.
mypy/main.py
Outdated
if filename is not None: | ||
config_files = (filename, ) | ||
else: | ||
config_files = (defaults.CONFIG_FILE, ) + SHARED_CONFIG_FILES |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No space between "," and ")". (Also two lines up.)
mypy/main.py
Outdated
@@ -540,31 +537,52 @@ def get_init_file(dir: str) -> Optional[str]: | |||
'almost_silent': bool, | |||
} | |||
|
|||
SHARED_CONFIG_FILES = ('setup.cfg', ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No space between "," and ")".
Fixed. Please forgive my English - I'm trying to do my best despite it's not my native language. And I'm more of a Vim guy. :) |
When --config-file option isn't passed to mypy and mypy can't load mypy.ini (default config filename), it will try to load settings from setup.cfg.
Thanks! PS. Next time can you not squash your commits? It's easier to go through review cycles if every push is a separate commit. e squash and rewrite the commit message when we merge PRs anyways. |
When
--config-file
option isn't passed to mypy and mypy can't load mypy.ini (default config filename), it will try to load settings from common shared config files -- currentlysetup.cfg
andtox.ini
. However, with these files, mypy will become less verbose; specifically it won't requiremypy
section.My main incentive is that I don't wan't to "bloat" my project structure with loads of config files; OTOH I expect them to work just by typing well-known command (with options loaded from configuration files). Two common development tools I use are pytest and flake8 and both support loading
setup.cfg
files. Another popular one is tox, which unfortunately doesn't load that file, but the former two loadtox.ini
in addition tosetup.cfg
. Moreover, tox is often used to run all these tools with mypy included and I believe some people consider keeping all configuration in one place as a nice thing to have.I do understand that this is kind of an anti-pattern, but with small codebases it is quite annoying to have as many config files as source code. This is why it is implemented as a completely optional feature, with
--config-file
option andmypy.ini
taking precedence over shared configs. Anyway, this PR is rather small - I hope the code won't need any maintenance - and some people will benefit from it, while others will never use it.