-
Notifications
You must be signed in to change notification settings - Fork 276
Looping through list of aliased union causes potentially-missing members to be available #3161
Copy link
Copy link
Closed
astral-sh/ruff
#24263Description
Summary
https://play.ty.dev/e386b6ff-128c-45d7-bc1a-89108e3a1ad3
class A:
pass
class B:
def do_b_thing(self) -> None:
pass
type U = A | B
class Cls:
def __init__(self,
not_aliased: list[A | B], # list of `A | B`
aliased: list[U], # effectively the same as above, but with an intermediate alias
) -> None:
# All of this is as expected: we can't access B-only methods from `A | B`...
self.not_aliased = not_aliased
reveal_type(self.not_aliased[0]) # A | B
self.not_aliased[0].do_b_thing() # not defined on `A` in union `A | B`
for item in self.not_aliased:
reveal_type(item) # A | B
item.do_b_thing() # not defined on `A` in union `A | B`
# ...even if it's through an alias. Why would an alias change anything anyway?
self.aliased = aliased
reveal_type(self.aliased[0]) # A | B
self.aliased[0].do_b_thing() # not defined on `A` in union `A | B`
for item in self.aliased:
reveal_type(item) # A | B
item.do_b_thing() # not defined on `A` in union `U`
def do_thing(self) -> None:
# If we do all the same stuff from a method, then it's all still as expected, right?
reveal_type(self.not_aliased[0]) # Unknown | A | B
self.not_aliased[0].do_b_thing() # ERROR: not defined on `A` in union `Unknown | A | B`
for item in self.not_aliased:
reveal_type(item) # Unknown | A | B
item.do_b_thing() # not defined on `A` in union `Unknown | A | B`
# But when we access the list of aliases...
reveal_type(self.aliased[0]) # Unknown | A | B
self.aliased[0].do_b_thing() # ERROR: not defined on `A` in union `Unknown | A | B`
for item in self.aliased:
reveal_type(item) # Unknown | A | B
item.do_b_thing() # SOMEHOW NOT AN ERROR?????Version
6e76b4cd8 (from playground)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels