Skip to content
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

No keys hints for TypedDict when it is in union #2860

Closed
pukhov opened this issue May 26, 2022 · 14 comments
Closed

No keys hints for TypedDict when it is in union #2860

pukhov opened this issue May 26, 2022 · 14 comments
Labels
enhancement New feature or request fixed in next version (main) A fix has been implemented and will appear in an upcoming version

Comments

@pukhov
Copy link

pukhov commented May 26, 2022

Environment data

  • Language Server version: Pylance language server 2022.5.3 (pyright 73c82fab)
  • OS and version: Windows 10 / tested on Linux, too.
  • Python version (& distribution if applicable, e.g. Anaconda): 3.10.4 (anaconda)

Code Snippet

from __future__ import annotations
from typing import TypedDict

class MyDict(TypedDict):
    a: str

def foo() -> MyDict | int:
    ...

x = foo()
# x. # OK: shows hints for int, e.g. bit_length and for dict, e.g. keys
# x[] # BUG: does not show 'a' here
# x[''] # and even here

# but this works, though, so it understands it is TypedDict, only hints do not work.
#y = x['a'] # inferred type of y is str | Any

Expected behavior

Show keys hints, 'a' in this case

Actual behavior

Does not show key hints.

@bschnurr
Copy link
Member

I think you need to check that the type is MyDict first

if isinstance(x, MyDict):
    x['a'] = 'hi'
else:
    x = 1

@erictraut
Copy link
Contributor

For type correctness, you'd need to add that check. For completions, we should offer suggestions for all subtypes in the union. We do this for unions in other cases, like in this example.

Screen Shot 2022-05-26 at 2 41 20 PM

The completion logic for TypedDict is special-cased, and it doesn't currently handle unions properly.

@pukhov
Copy link
Author

pukhov commented May 26, 2022

@bschnurr

I don't think one should check with isinstance to get autocomplete hints, finally, it's just a nice feature, the inference of types works correctly (I said so in the issue, that y = x['a'] has correct type -- str | Any).

@pukhov
Copy link
Author

pukhov commented May 26, 2022

@erictraut

So it is currently not supported but maybe it will be fixed later?

@erictraut
Copy link
Contributor

It's a trivial fix. Working on it now.

@erictraut erictraut added enhancement New feature or request fixed in next version (main) A fix has been implemented and will appear in an upcoming version and removed triage labels May 26, 2022
@erictraut
Copy link
Contributor

erictraut commented May 26, 2022

This will be addressed in the next release.

The change also supports unions that include multiple TypedDict types.

Screen Shot 2022-05-26 at 2 54 11 PM

@pukhov
Copy link
Author

pukhov commented May 26, 2022

Thanks!

In fact, what I want to achieve with this is to say that some class has these and these keys. Are there any other ways to tell this to pylance?

As I understand, now only TypedDict has supported hints. There are 2 "pythonic" solutions, both are prohibited by TypedDict pep though :)

  1. class should inherit from TypedDict
  2. add methods to TypedDict

So what I am doing is a hack, I say "this is both class and it has these keys" by passing the union of my class and created TypedDict.

Motivation / common use-case: pandas.DataFrame / numpy.ndarray (with fields) with known in advance columns / dtype.

I might create a separate issue for this, though not sure, if it's pylance or current Python typing state. (I think the latter)

@erictraut
Copy link
Contributor

This would be a topic better discussed in the python/typing discussions forum.

@pukhov
Copy link
Author

pukhov commented May 26, 2022

Ok, thanks!

@erictraut
Copy link
Contributor

We'll leave this open until next week's release.

@erictraut erictraut reopened this May 26, 2022
@pukhov
Copy link
Author

pukhov commented May 29, 2022

@erictraut

BTW, is the problem below also fixed by your change or should I open another issue?

Normal classes have hints in notebooks, but TypedDicts don't.

foo.py

from typing import TypedDict

class A:
    a: int

class B(TypedDict):
    a: int

def get_A() -> A:
    ...

def get_B() -> B:
    ...

in notebook:
(on double brackets see #2384 )

import foo

a = foo.get_A()
b = foo.get_B()

a. # gives hints
b[] # no hints
b[[]] # and even this

@erictraut
Copy link
Contributor

erictraut commented May 29, 2022

That should have worked prior to my change because b doesn't involve a union.

Here are the completions I receive with the latest code (which includes my recent change). I think this is what one would expect.

Screen Shot 2022-05-29 at 10 07 36 AM

Screen Shot 2022-05-29 at 10 07 48 AM

Edit: It looks like there's another issue that may be specific to Jupyter notebooks. There's already another bug tracking that issue.

@pukhov
Copy link
Author

pukhov commented May 29, 2022

Yes, it works perfectly in normal py files, however for notebooks:

  • if dict is already created and has keys then there is a known issue, when double brackets work and single brackets do not.
  • if it is not created (but of a known type TypedDict), then neither single nor double brackets work, so I thought it's a different issue.

We can wait for that issue to be resolved first and if it still does not work, I ll open a new issue.

@bschnurr
Copy link
Member

bschnurr commented Jun 1, 2022

This issue has been fixed in version 2022.6.0, which we've just released. You can find the changelog here: CHANGELOG.md

@bschnurr bschnurr closed this as completed Jun 1, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request fixed in next version (main) A fix has been implemented and will appear in an upcoming version
Projects
None yet
Development

No branches or pull requests

3 participants