[ty] Add allowed-unresolved-imports setting#22800
Conversation
Typing conformance resultsNo changes detected ✅ |
|
allowed-unresolved-imports setting"allowed-unresolved-imports setting
|
There's one TODO, adding the same early-exit to ruff/crates/ty_python_semantic/src/types/infer/builder.rs Lines 8686 to 8695 in ceb876b but I haven't been able to come up with a test case, which is why I haven't done this yet. |
|
| Supports glob patterns: | ||
| - `*` matches zero or more characters except `.` (e.g., `foo.*` matches `foo.bar` but not `foo.bar.baz`) | ||
| - `**` matches any number of module components (e.g., `foo.**` matches `foo`, `foo.bar`, etc.) | ||
| - Prefix a pattern with `!` to exclude matching modules |
There was a problem hiding this comment.
This all looks reasonable to me. Is this also what mypy does?
There was a problem hiding this comment.
No, mypy doesn't distinguish between * and **.
A pattern of the form qualified_module_name matches only the named module, while dotted_module_name.* matches dotted_module_name and any submodules (so foo.bar.* would match all of foo.bar, foo.bar.baz, and foo.bar.baz.quux). source
I do think the distinction between ** and * is useful. I also don't think mypy supports test*, which seems useful to me as well.
There was a problem hiding this comment.
Yeah I agree. Distinguishing between "match one component" and "match many" is nice.
There was a problem hiding this comment.
Hmm, I'm not sure I agree with you two here! I can't see a use case for telling ty to ignore an unresolved foo.bar import but not to ignore an unresolved foo.bar.baz import. If foo.bar is unresolved, then foo.bar.baz will always be unresolved too -- that's just the nature of how imports work in Python! Distinguishing between "match one component" and "match many" might make sense in the abstract for glob patterns in general, but for this specific application it feels to me like it adds complexity for little purpose
There was a problem hiding this comment.
I also think there's value in matching what mypy does; it'll be what users migrating from mypy will expect
There was a problem hiding this comment.
Okay, I think I see the use case. You might want to use aws* to match, e.g., all modules that start with aws, but not necessarily their submodules.
I'll refine the docs here slightly to give some clearer examples of situations where it might be useful to use * instead of (or in combination with) **
| regex_set: RegexSet, | ||
| /// Parsed glob metadata. | ||
| globs: Box<[ModuleGlob]>, | ||
| } |
There was a problem hiding this comment.
I'm glad you resisted the urge to copy globset's optimizations. I was going to suggest not bringing them in initially if you did. :P
There was a problem hiding this comment.
Haha, I was counting on RegexSet doing a good job at optimizing the most trivial literal cases for me.
There was a problem hiding this comment.
It... probably will. The globset stuff was written before I overhauled the regex internals, so there are undoubtedly some things in globset that don't need to be there any more. But I'm not sure which! Hah.
| ModuleNameMatch::Exclude | ||
| } else { | ||
| ModuleNameMatch::Include | ||
| } |
| let settings = self.db().analysis_settings(self.file()); | ||
|
|
||
| if settings | ||
| .allowed_unresolved_imports | ||
| .matches(&full_submodule_name) | ||
| .is_include() | ||
| { | ||
| return; | ||
| } |
There was a problem hiding this comment.
I don't love that we have to repeat this three times, but I'm not immediately sure what a more DRY solution would be
AlexWaygood
left a comment
There was a problem hiding this comment.
Thank you, this is great!
Summary
This PR adds a new
analysis.allowed-unresolved-importssetting that allows users to suppressunresolved-importerrors for modules matching a glob in theallowed-unresolved-importslist.The new setting mimics
src.includeby supporting module-name globs and negated glob patterns. Negated globs are useful when using this setting withoverrideswhere an import should not be ignored for a specific subfolder.Fixes astral-sh/ty#1354
Adding support for astral-sh/ty#2082 should be straightforward after this change, as all the infrastructure is in place.
While the globbing is heavily inspired by
GlobSet, I didn't go as far as optimizing the implementation for literals etc. It also doesn't support all glob meta characters, but these are both things we can address in the future.CC: @ntBre because I think we wanted something similar in Ruff.
Review
It probalby makes sense for @BurntSushi to review the
ModuleGlobSet"stuff" and for someone familiar with our import system to review theTypeInferenceBuilderchangesTest plan
Added mdtests and glob tests