mypy icon indicating copy to clipboard operation
mypy copied to clipboard

Complete bi-directional linking between cli-flags/configs and error codes

Open wyattscarpenter opened this issue 5 months ago • 6 comments

Could there also be links (both ways) between those and the documentation of the different error codes that are affected by the configuration options (eg. between --disallow-any-generics, disallow_any_generics and type-arg). In this example, there is also the "Generics" section of the documentation.

Some of those links are already there, some are not there yet.

Originally posted by @Zeckie in #12347

I agree with Zeckie, having just spent some time looking at --warn-unreachable and thinking "hmm, wasn't this some kind of code as well?" and then remembering [unreachable]

Possibly, flags which could be replaced with a simple --enable-error-code whatever should be deprecated in some way. (Although, it probably doesn't make sense to remove them, since they're so cheap to maintain.) But that would be a different issue, anyway.

This bi-directional linking could probably be achieved for free an automatically if more of the docs were automatically generated, a perennial thought of mine.

If the other issue merging config and cli guides is fixed, then this issue would naturally become easier, or perhaps get fixed along the way.

wyattscarpenter avatar Aug 07 '25 08:08 wyattscarpenter

I'll work on it !

Sabine22-alt avatar Nov 18 '25 09:11 Sabine22-alt

@wyattscarpenter I have a few questions regarding this issue. To start exploring a solution, I created a new module, flag_error_mapping.py, which defines a centralized mapping between a couple of existing flags (warn_unreachable, warn_redundant_casts) and their corresponding error codes, along with an automatically generated reverse mapping. I also added a small utility method in options.py to make this mapping accessible within the codebase.

I initially tried writing a pytest test for this, but none were collected, which led me to believe that mypy disables standard pytest discovery and relies on its internal testing system instead.

Could you confirm whether this approach is in the right direction for solving the issue, and whether my understanding of why pytest tests are not executed in this project is correct? Thank you in advance !

Sabine22-alt avatar Dec 04 '25 10:12 Sabine22-alt

@Sabine22-alt good questions; let me try to answer all of them. It's worth noting that I am not a maintainer on mypy and have no particular authority; I'm just another user & occasional-contributor who thought this issue's suggestion would be a good idea. I have no ability to approve or deny pull requests, for example, and there are large parts of mypy I am completely ignorant of.

I don't really know anything about how pytest is supposed to work, because I don't use pytest except for this project. https://github.com/python/mypy/blob/mypy-ignore/CONTRIBUTING.md#running-tests seems to indicate that the pytest-structure of the tests is something like, eg, mypy/test/testcheck.py::TypeCheckSuite::check-dataclasses.test, where the middle thing is probably some sort of class that runs the .test files and the first part is a file path. Maybe that's a clue.

If pytest isn't working try runtests.py (which just calls pytest, but perhaps in a different way that you're currently trying). Conversely, if runtests.py isn't working try running pytest directly.

Regarding the question of the general direction of the approach:

Taken in the simplest way, this issue is really a documentation issue. For instance, --warn-unreachable should have a link to [unreachable], and vice-versa.

This could be done manually, by reviewing each error code section in the documentation, making sure it has a link to the flag to enable it, and then making sure that flag has a link to the error code.

Realistically, it's probably best to edit this documentation manually, for now, since changes like that will be very easy for maintainers to review.

But maybe you want to write code, specifically. (In fact, you seem to be involved in some kind of school assignment(?), which may or may not mandate that you program as part of your contribution.) In that case, there may be some code that is useful to write.

The cross-linking of the documentation could also be done automatically, by having the program generate or alter the documentation somehow, or verify that there are such cross-links. There are various ways one could go about doing that and your approach sounds fine so far.

Come to think of it, if the idea so far is just to have a mapping between error codes and flags, a convenient way to do that might just be an additional optional parameter on ErrorCode in errorcodes.py, so that data would already live with the rest of the information about error codes. For instance, the newly revised constructor could hypothetically be called like this:

UNREACHABLE: Final = ErrorCode(
    "unreachable", "Warn about unreachable statements or expressions", "General", associated_flag="warn_unreachable"
)

Something like this. It's easy for me to start architecting this, perhaps unwisely. For instance, maybe it should actually be two optional parameters, positive_flag_aliases and negative_flag_aliases, both list of str, to capture the fact that sometimes flags turn the code on and sometimes off. (But how to take note of flags that do that but also have other side effects? hmm...)

Anyway, I hope this helps! Feel free to ask me other things, if you want, although I might not have any answers.

wyattscarpenter avatar Dec 05 '25 08:12 wyattscarpenter

@wyattscarpenter Thanks for your detailed reply. Yes, it’s for a school project. I chose the coded version because it’s the preferred one, and I thought the manual version would take much more time. I’ll go ahead and make the modification manually.

In the documentation, I see three important files:

  • error_code.rst: overview of the error codes

  • error_code_list.rst: list of error codes enabled by default, with descriptions

  • error_code_list.rst2: optional error codes

I should proceed as follows: I look for the specific error code in error_code_list.rst and add the section documenting the mapping with the corresponding flag (probably in options.py) in that file, using a section like:

"This error code can be enabled/disabled using the flag --warn-unreachable or through the configuration option warn_unreachable."

Thanks in advance for your response ;)

Sabine22-alt avatar Dec 08 '25 10:12 Sabine22-alt

Here's what I think is important:

  • command_line.rst
  • error_code_list2.rst

(error_code.rst: doesn't really document specific error codes, so it won't need to be changed. config_file.html is basically vestigial and will be merged into command_line.rst when someone gets around to the issue this issue spun off from)

There are a number of flags in command_line.rst that enable an error code in error_code_list2.rst. The idea is that for each of these, the entry for the code in error_code_list2.rst will mention and link to the dedicated flag in command_line.rst (this already seems to be true for most of them) and the entry for the flag in command_line.rst will mention and link to the corresponding code in error_code_list2.rst. And then you should be good!

(In particular, I don't think you need to include anything mentioning the version of the option with underscores that goes in the configuration file (e.g. warn_unreachable), because that's basically just redundant and the user will be able to figure that out without being told every time.)

error_code_list.rst doesn't list any enabling flags, since they're all enabled by default. I guess if there were dedicated disabling flags for these, it would make sense to bi-directionally link those as well, but I don't know of any.

wyattscarpenter avatar Dec 08 '25 13:12 wyattscarpenter

Oh, another thought: we currently have some code that checks if every error code is documented in the error codes list documents. In the future, we could extend that code to check that every error code is bi-directionally linked to every flag that enables an error code. (You don't have to implement that.) So, try to add the cross-links in a consistent format that will be machine-parsable — instead of, say, a winding prose description at a random part of the cli flag's documentation, a consistent format like a sentence at the top of the cli flag's descriptioin saying "this flag enables the error code whatever" or something like that. That's probably more-or-less how you were going to do it anyhow, but, just thought I'd mention in case it came up.

wyattscarpenter avatar Dec 09 '25 13:12 wyattscarpenter