Argument-Clinic / cpython

The Python programming language
https://www.python.org/
Other
1 stars 0 forks source link

Getting rid of the globals #29

Closed erlend-aasland closed 7 months ago

erlend-aasland commented 10 months ago

There are various types of globals in clinic:

We should start with the low-hanging frui: stateless helpers and plain constants. Some constants can be baked into their respective class (for example version). Others can be stuffed away in a "libclinic.py" or "util.py" file. Ditto for the helpers: some helpers clearly belong in a specific class, so we can stash them there. Other helpers are completely stateless, and can thus live in a "util.py" file.

erlend-aasland commented 10 months ago

Low-hanging fruit:

AlexWaygood commented 10 months ago

We should maybe distinguish between different types of globals.

Global variables that are never mutated, have a constant type, and are annotated with typing.Final — these are fine, in my opinion. They're easy to reason about, easy to move into submodules, I have no issues.

Globals that are mutated from inside apparently unrelated functions, and/or have different types at various stages of the code — these are evil, and must be eviscerated! Anything that requires the global keyword is a code smell.

Personally, I only really care about category (2). Moving global variables from category (2) to category (1) can be just as good as getting rid of the global variable altogether

erlend-aasland commented 10 months ago

Yep, and making sure globals are not mutated (category 2 => category 1) can easily be done in parallel with taking care of other low-hanging fruit (separating out stateless helpers and "final" constants).

erlend-aasland commented 10 months ago

The following can easily be dealt with:

The resulting files can be put in a libclinic package.

erlend-aasland commented 10 months ago

I did some experimenting in #30. Helpers that call fail(...) must of course wait for now, so linear_format is out of the question for now. Anyways, this looks promising. We should be able to follow up with some of the support classes (FormatCounterFormatter, CRenderData, Include, BufferSeries, FunctionKind, ...).

erlend-aasland commented 10 months ago

Regarding the two fails in linear_format():

https://github.com/python/cpython/blob/1ff02385944924db7e683a607da2882462594764/Tools/clinic/clinic.py#L313-L318

It seems to me only the latter can be triggered by user input[^1]; the former is an assert that the internal templates are correctly formatted. Perhaps the former can be made an assert?

[^1]: It lacks a test, but that is pretty easy to fix: add a docstring with a {parameters} placeholder, and put a non-whitespace character right in front of the placeholder: a{parameters}.

erlend-aasland commented 10 months ago

Regarding the global parsers and converters, one can argue that they're part of the configuration of the application, so they could end up living with the app.

erlend-aasland commented 10 months ago

Also: I've been trying to move the option group helpers, but they need forward declarations for a lot of stuff (Parameter, Function, etc.). We could relax their typing rules, though; they are type agnostic (we use just tuples of ints for the tests, IIRC).

vstinner commented 7 months ago

This issue has been fixed.