Skip to content

New setting "user_builtins_name": Ignore specific "name-defined" errors #18932

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

Open
un-pogaz opened this issue Apr 17, 2025 · 5 comments · May be fixed by #18936
Open

New setting "user_builtins_name": Ignore specific "name-defined" errors #18932

un-pogaz opened this issue Apr 17, 2025 · 5 comments · May be fixed by #18936
Labels

Comments

@un-pogaz
Copy link

Feature

Adding a setting "user_builtins_name", or "builtins", that is a array of strings for which the error [name-defined] is ignored.

Pitch

It is possible to extend the list of builtins function, which can be very useful in some projects as we no longer need to import this function if it's used extensively in the rest of the project.

Example:

builtins.__dict__['prints'] = prints = PrefixedPrint()

builtins.__dict__['_'] = localization.gettext

Sadly, mypy don't support such exotic things. There is two solution:

  1. Analyzer all the code to add dynamically the "user builtins name"
  2. Add a user-controlled setting to globally ignore specific "name-defined" errors

The first would be the best, but also the harder to implement. The second would be easier to implement, but some ignored 'name-defined' error could be legitimate depending on the import and call stack. But since the very exotic and niche feature, the risks are low and we can assume that the user know what he do when he use this settings.

The use of a setting name that contain the word 'builtins' allows to explicitly specify the user case of such setting (when a generic "ignore_name_defined" could be misinterpreted and so misused)

Related Issues
#7931

@brianschubert
Copy link
Collaborator

Linking #16078, #12860 for related discussion

@A5rocks
Copy link
Collaborator

A5rocks commented Apr 19, 2025

I assume using custom_typeshed_dir with a typeshed where you modify builtins.pyi is too cumbersome?

Maybe better than a list of names to ignore would be custom_typing_module for builtins -- I imagine you want types for the commonly used functions too!

@un-pogaz
Copy link
Author

un-pogaz commented Apr 19, 2025

Cumbersome is a word to use, but Hacky and Over-exagered seems to me a better descriptors.

At first, I thought that the solution you suggested was that I import the more than 2000 line builtins.pyi to add the only 10 that describe custom builtins functions and then that mypy will dynamicly add/overide the corresponding module into their default typeshed. I'd have objections to that, but okay. It's a hacky way that could work fine, but that not very solve propely the issue.

But no, that worst than that since your suggestion need to import the +700 files of the native CPython/mypy??? For 2 functions??? Why do that for a such small change ??? O_o

So, I'm sure there are projects that are able and determined to do this kind of thing, but it's certainly because they have a very good reason to do it, like probably using custom versions of CPython/mypy. But that's not the case for everyone, especially given the disproportionate size ratio between the files added and the modifications specific to this project. Not to mention the maintenance that would have to be done in the event of a python version change.

No, you idea completly miss the use case for small and medium-sized projects, and probably the almost totality of any projects of any size, with a absurdly over-exagered way to solve a simple and small problem.


So Yes, checking the types for the custom builtins functions would be a must-have, and that's why the support of __builtins__.pyi (#16078) would be absolutely perfect, but I'm afraid I'm not good enough to make such edit. So a simple list of excluded name is not a perfect solution, but that one that work now (see PR #18936).

(and I don't understand why you propose to use "custom_typing_module", their is no type change implie in my proposal)

@sterliakov
Copy link
Collaborator

sterliakov commented Apr 22, 2025

A trivial implementation of __builtins__.pyi patching exists in the standard unix toolbelt:

cat __builtins__.pyi >>.venv/lib/python*/site-packages/mypy/typeshed/stdlib/builtins.pyi

If you run an automated CI pipeline, such monkey-patching will likely be much easier than using typeshed as a git submodule and saving your modifications. (yes, I'm mostly joking, but for closed-source codebase with a small team... may work just fine)

That will only support really simple cases (like variables annotated with builtin types) because builtins are special-cased, but may be good enough to not warrant user_builtins_name mypy setting that is essentially equivalent to a bunch of some_var: Any declarations appended to builtins.pyi.

I'm, however, +1 on supporting some variant of __builtins__.pyi. I hate TS declare global with every fiber of my being, it can produce completely unmaintainable mess after just a couple such "patches", but it's a nice escape hatch.

I can suggest to add a --custom-builtins-file FILE flag that works exactly like --custom-typing-module. If given, mypy should parse FILE instead of builtins.pyi everywhere. FILE should contain a valid (probably modified) copy of builtins.pyi from typeshed. That's what @A5rocks proposed above.

Alternatively, it may be --append-builtins-file FILE that instructs mypy to continue as if you ran cat builtins.pyi FILE > new_builtins.pyi && mv new_builtins.pyi builtins.pyi.

Either option will be intended for advanced users and subject to breaking changes. Supplying something bad there may cause any sorts of mypy crashes down the road.

@un-pogaz
Copy link
Author

Append your custom builtins data to the stub in mypy packages? Clever. Still a stopgap solution, patching builtins.pyi so that mypy don't complain, but I can see how it can be used with a correct workflow.

For the radicality of user_builtins_name: I'm into the philosophy "we're all consenting adults here". Is a user setting, if you use it, your problem.

Else, I finaly manage to implement the support of __builtins__.pyi on my fork, I just need to add the tests and the doc before make the PR. But I note and will see how I could add your idea for --append-builtins-file, it will be very complementary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants