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

Typedict key and value suggestion inside dict literal syntax. #654

Closed
Gryhyphen opened this issue Nov 27, 2020 · 13 comments
Closed

Typedict key and value suggestion inside dict literal syntax. #654

Gryhyphen opened this issue Nov 27, 2020 · 13 comments
Labels
enhancement New feature or request

Comments

@Gryhyphen
Copy link

The problem

I'm using python for configuration files. I want to use typeddicts to provide hinting for the keys and values as the user is writing configuration.

i.e. (Category is a typeddict, name and fiction are required, potato is optional)

from category import Category

categories : "list[Category]" = [
    {"name": "Fishing", "fiction" : False},
    {"name": "Music", "fiction" : True, "potato" : 5 }
]

Dataclasses/named tuples/classes are an alternative I could use, which would provide the desired code-completion hints, but then I need to depend on the actual implementations, and wrap everything in constructors.

from category import Category

categories : "list[Category]" = [
    Category(name="Fishing", fiction=False),
    Category(name="Music", fiction=True, potato = 5)
]

The solution I'd like:

Basically I'm looking for a way to do this with python dicts:
https://code.visualstudio.com/docs/languages/json
https://json-schema.org/

I could switch over to json config files and write up schemas but I want to use python. Because it works, it's just not a very friendly experience without the auto-completion.

Additional context

Pylance will give the red swiggly line if the typeddict doesn't match up with the proper syntax, but it doesn't say exactly which key(s) is wrong or missing. I'm not looking for the red swiggly line, I'm looking for autocompletion and a popup which reads the docstring.

It's not this issue as I've checked and this access to the dict is supported and works on my computer:
microsoft/pyright#308
But I want it in the dict literal, not the accessor.

Your readme page mentions you have code completion support: https://github.com/microsoft/pylance-release , but it doesn't go into details on what exactly will and will not work. I thought the purpose of typeddicts were mainly to make autocompletion and hinting possible, and since it isn't I'm confused.

Maybe I'm misunderstanding what the purpose of typed dictionaries are, but it would help if you added more information somewhere on the page.

May be loosely related to: #374
In that I think there would be similar code needed to be written to support both cases, just in reverse and mapped to the 'constructor' of the typeddict.

@jakebailey
Copy link
Member

I'm a bit confused as to what you are looking for specifically; can you provide an example of where you are expecting completion in a code snippet and what you expect to appear, perhaps in a screenshot with what you get instead?

We should be giving completion anywhere we know there are members.

@jakebailey jakebailey added the waiting for user response Requires more information from user label Nov 30, 2020
@github-actions github-actions bot removed the triage label Nov 30, 2020
@heejaechang
Copy link
Contributor

looks like he wants this to work (https://github.com/microsoft/pyright/blob/master/packages/pyright-internal/src/languageService/completionProvider.ts#L1096) in dict initializer construction on top of dict["..."] construct.

@Gryhyphen
Copy link
Author

@jakebailey
@heejaechang

Exactly! dict["..."] will work as I mentioned, and that's great and all but it's not what I'm looking for. I want the {} to provide autocompletion:

image

You obviously can tell there is an issue with the dict init constructor, hence the red wavy lines, but as I'm adding fields to the instance you don't get any popups for members.

Ideally these popups would come with more information read from the docstring, to say what the configuration option does.

@tiangolo
Copy link

I want to second this, I might be misunderstanding it, but I'm pretty sure my feature request is this same one.

I plan on using TypedDict for several function parameters in FastAPI and other tools I'll build, and having this would improve the developer experience for users a lot.

Here are more details of what I mean:

Take this Python snippet:

from typing import TypedDict


class FormatOptions(TypedDict, total=False):
    capitalize: bool
    prefix: str


class Options(TypedDict):
    name: str
    seconds: float
    format_options: FormatOptions


def some_func(
    options: Options,
):
    return options


some_func(options={})

If I put the cursor inside the {} in the options argument, and then I trigger autocompletion, I would like to receive completion for the keys "name": , "seconds": , and "format_options": in the dropdown list.

Then if I call it, for example with:

some_func(options={
    "name": "foo",
    "seconds": 3,
    "format_options": {}}
)

And then, if I put the cursor inside the {} of the format_options, and trigger autocompletion, I would like to see completion for the keys "capitalize": and "prefix": .


This would be very similar to how it works in TypeScript with interfaces:

interface FormatOptions {
  capitalize?: boolean;
  prefix?: string;
}

interface Options {
  name: string;
  seconds: number;
  format_options: FormatOptions;
}

function some_func(options: Options) {
  return options;
}

some_func({
  name: "foo",
  seconds: 3,
  format_options: { capitalize: true, prefix: "pre" },
});

all the autocompletion described above for the Python example already works when editing this equivalent TypeScript file.

@NixBiks
Copy link

NixBiks commented Jun 14, 2021

We also need this feature to allow for autocomplete support for XState in Python, where the API is a typed dict.

Is it possible to see a list of issues that are prioritized? It is my understanding that it depends on the number of upvotes but I can't seem to find how many upvotes are currently needed.

@RobertCraigie
Copy link

+1 This would be very helpful for prisma-client-py

@sethmlarson
Copy link

sethmlarson commented Oct 8, 2021

Putting my vote on this issue as well, I'd like to lean on TypedDict for the Elasticsearch client and having a better UX when writing these literals would be much appreciated.

@RobertCraigie
Copy link

@sethmlarson Support for this feature has actually been added in https://github.com/microsoft/pylance-release/releases/tag/2021.9.4

@sethmlarson
Copy link

@RobertCraigie Excellent! Thank you for pointing me to that.

@jakebailey
Copy link
Member

Interesting; we weren't sure that the code @RobertCraigie submitted (microsoft/pyright#2334) would handle this particular issue, but it looks as thought it does (yay!), probably thanks to the getExpectedType getting info in some conditions.

image

image

Even deeply:

image

Though, it would be nice to suggest {} in our completions when a typeddict (or maybe just generally, any dict/list/etc) are expected:

image

Note that with the way that completions operate, you have to manually trigger the completions with Ctrl+Space. This is probably something to investigate in another issue (it's not specific to TypedDict or even dicts at all).

@cdce8p
Copy link

cdce8p commented Oct 8, 2021

@jakebailey Unfortunately, it only works for the first key. After that pylance reports an error (missing key) and no suggestions are offered.

from typing import TypedDict

class PointTD(TypedDict):
    x: int
    y: int

p1: PointTD = {'x': 1, }

Screen Shot 2021-10-08 at 21 12 07

@jakebailey
Copy link
Member

That's probably a bug; add the quotes and we will suggest the other keys:

image

I'll create a new issue to track that.

@stereobutter
Copy link

Currently there are only autocomplete suggestions for a TypedDicts keys. Is it possible to also provide a hint what the type of the value should be ?

class Example(TypedDict):
    a: int

example: Example {'a': }
#                     ^cursor here: helpful suggestion would be something like 'a': int

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

10 participants