[ty] Introduce UnionType::try_from_elements and UnionType::try_map#18911
[ty] Introduce UnionType::try_from_elements and UnionType::try_map#18911AlexWaygood merged 2 commits intomainfrom
UnionType::try_from_elements and UnionType::try_map#18911Conversation
UnionType::try_from_elements and UnionType::try_mapUnionType::try_from_elements and UnionType::try_map
|
| } | ||
|
|
||
| /// A fallible version of [`UnionType::map`]. | ||
| pub(crate) fn try_map( |
There was a problem hiding this comment.
Maybe: try_map and try_map_result or try_map and try_map_ok?
and try_from_elements and try_from_result_elements?
I also think it's important to document what "fallible" means because it wasn't clear to me if it bails if there's any None value or if it skip sover None values.
There was a problem hiding this comment.
Maybe:
try_mapandtry_map_resultortry_mapandtry_map_ok?and
try_from_elementsandtry_from_result_elements?
We could, but I don't think it's worth it right now considering that there's only one callsite that uses Results. We can add it later if that pattern becomes more common, I think.
I also think it's important to document what "fallible" means because it wasn't clear to me if it bails if there's any
Nonevalue or if it skip soverNonevalues.
👍 I'll push an update
MichaReiser
left a comment
There was a problem hiding this comment.
It's unfortunate that the Try trait isn't stabilized :(
* main: [ty] Fix false positives when subscripting an object inferred as having an `Intersection` type (#18920) [`flake8-use-pathlib`] Add autofix for `PTH202` (#18763) [ty] Add relative import completion tests [ty] Clarify what "cursor" means [ty] Add a cursor test builder [ty] Enforce sort order of completions (#18917) [formatter] Fix missing blank lines before decorated classes in .pyi files (#18888) Apply fix availability and applicability when adding to `DiagnosticGuard` and remove `NoqaCode::rule` (#18834) py-fuzzer: allow relative executable paths (#18915) [ty] Change `environment.root` to accept multiple paths (#18913) [ty] Rename `src.root` setting to `environment.root` (#18760) Use file path for detecting package root (#18914) Consider virtual path for various server actions (#18910) [ty] Introduce `UnionType::try_from_elements` and `UnionType::try_map` (#18911) [ty] Support narrowing on `isinstance()`/`issubclass()` if the second argument is a dynamic, intersection, union or typevar type (#18900) [ty] Add decorator check for implicit attribute assignments (#18587) [`ruff`] Trigger `RUF037` for empty string and byte strings (#18862) [ty] Avoid duplicate diagnostic in unpacking (#18897) [`pyupgrade`] Extend version detection to include `sys.version_info.major` (`UP036`) (#18633) [`ruff`] Frozen Dataclass default should be valid (`RUF009`) (#18735)
Summary
An increasingly common pattern in our codebase is to do something like this, where we iterate over a sequence of types and apply a fallible mapping operation to each element in turn:
While the mapping function continues to return
Some(Type<'db>)for each element, we build up a union; but as soon as the mapping operation returnsNonefor any element, we short-circuit and returnNone.This PR adds some helper functions to
UnionTypeto make this pattern less verbose:UnionType::try_from_elements()andUnionType::try_map.Unfortunately there are a couple of places where a mapping function returns a
Result:ruff/crates/ty_python_semantic/src/types/infer.rs
Lines 7465 to 7480 in 27eee5a
But I don't think this approach can be generalized to support mapping operations that return
Results as well as mapping operations that returnOptions until theTrytrait is stabilised in Rust.Test Plan
cargo test -p ty_python_semantic