| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
Sorry, something went wrong.
|
@hauntsaninja I still need to actually respect @final but am I on the right track? BTW, does it strictly require @final? This can be deemed as truthy even without @final class D(TypedDict):
foo: str
d: D
if 'foo' in d:
assert_type(d, D)
else:
assert_never()It doesn't make a good case for ruling out unions, though: class D1(TypedDict):
foo: str
class D2(TypedDict):
bar: str
d: D1 | D2
if 'foo' in d:
assert_type(d, Union[D1, D2])
else:
assert_type(d, D2)Might seem a bit complex, but we already have to deal with it for totality. |
Sorry, something went wrong.
|
Update: Also discerning on final-ity now In the case of https://github.com/Rapptz/discord.py/blob/3bca40352ecfa5b219bae0527252ee5d296113e7/discord/client.py#L1755: |
Sorry, something went wrong.
|
@sobolevn can this be merged as is? |
Sorry, something went wrong.
There was a problem hiding this comment.
Took a look at the tests and left some comments. I'll review the actual code too, but might take me a little bit to get to it. Will make sure to review before 1.0 though
Sorry, something went wrong.
| [builtins fixtures/dict.pyi] | ||
| [typing fixtures/typing-typeddict.pyi] | ||
|
|
||
| [case testOperatorContainsNarrowsTypedDicts_unionWithList] |
There was a problem hiding this comment.
this test case seems completely duplicated in testOperatorContainsNarrowsTypedDicts_total, let's remove this?
Sorry, something went wrong.
There was a problem hiding this comment.
I'll remove the relevant part from testOperatorContainsNarrowsTypedDicts_total, as to keep test names descriptive.
Sorry, something went wrong.
There was a problem hiding this comment.
Sorry, something went wrong.
| else: | ||
| assert_type(d_or_list, list[str]) |
There was a problem hiding this comment.
| else: | |
| assert_type(d_or_list, list[str]) | |
| elif 'bar' in d_or_list: | |
| assert_type(d_or_list, list[str]) | |
| else: | |
| assert_type(d_or_list, list[str]) |
Sorry, something went wrong.
There was a problem hiding this comment.
Sorry, something went wrong.
|
|
||
| foo_or_invalid: Literal['foo', 'invalid'] | ||
| if foo_or_invalid in d: | ||
| assert_type(d, D1) |
There was a problem hiding this comment.
in theory this could narrow foo_or_invalid as well, want to add an assert_type for that behaviour too?
Sorry, something went wrong.
There was a problem hiding this comment.
That'd have to be implemented. And I think it could be pretty neat, but would require a rework: I'd have to pass in the left expression, and return type maps (not "if_type" and "else_type"). Maybe in a follow-up?
Sorry, something went wrong.
There was a problem hiding this comment.
My current implementation is to make a form of "tagged TypeDicts" work, but I suspect a more generalized form of type narrowing should be possible. However, before we tackle the more contrived x in y case, we should probably do it for x == y, so that this example would see narrowing applied.
(I might be naive, though, and this might've been tried before and proven impossible.)
P.S. PyRight is similarly limited in this
Sorry, something went wrong.
There was a problem hiding this comment.
Oh sorry, to be clear my suggestion wasn't to implement this / I don't think it's a terribly important feature. I was just saying it's worth adding an assert_type in this test to make this (lack of) behaviour clear to the reader.
Sorry, something went wrong.
There was a problem hiding this comment.
Gotcha, done: fb564eb
Sorry, something went wrong.
| value: int | ||
| if 'foo' in arg: | ||
| assert_type(d, Union[D1, D2]) # strangely enough it's seen as a union | ||
| value = arg['foo'] # but acts here as D1 |
There was a problem hiding this comment.
I think this is because mypy processes these twice. Want to change the test to just do reveal_type(arg['foo'])?
Sorry, something went wrong.
There was a problem hiding this comment.
Sorry, something went wrong.
…nst/mypy into typed-dict-in-type-narrowing
|
Diff from mypy_primer, showing the effect of this PR on open source code: discord.py (https://github.com/Rapptz/discord.py)
- discord/client.py:1755: error: Value of "rpc_origins" has incompatible type "None"; expected "List[str]" [typeddict-item]
|
Sorry, something went wrong.
|
Could the PR description be modified to reflect the change made in f799344 ? Perhaps to class A(TypedDict)
foo: int
@final
class B(TypedDict):
bar: int
union: Union[A, B] = ...
value: int
if 'foo' in union:
# Cannot be a B as it is final and has no "foo" field, so must be an A
value = union['foo']
else:
# Cannot be an A as those went to the if branch
value = union['bar'](Super excited to see this PR, thank you so much!) |
Sorry, something went wrong.
|
@alicederyn thanks for spotting this — updated with your proposed sample code |
Sorry, something went wrong.
There was a problem hiding this comment.
Thanks for improving this! This is a nice feature
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
in could narrow unions of TypeDicts, e.g.