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

Type checking for unpacked TypedDicts as function arguments #374

Closed
juanpablos opened this issue Sep 16, 2020 · 2 comments
Closed

Type checking for unpacked TypedDicts as function arguments #374

juanpablos opened this issue Sep 16, 2020 · 2 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

@juanpablos
Copy link

Issue Type: Feature request.

Summary: when using a TypedDict and keyword unpacking it (**dict), check that the types in the TypedDict match with the arguments in the function.

In functions where arguments are meant to be passed as arguments to other functions the number of arguments can get too large. I find that using dicts to store keyword arguments for the inner functions is really useful, and with the introduction of TypedDicts we know the values that are present and could use them to check if it is compatible with the arguments of the function.

For example we could do something like:

class MyDict(TypedDict):
	var1: int
	var2: str
	var3: List[int]

def my_function(var1: int, var2: str, var3: List[int]):
	...

def my_other_function(var1: str, var2: str, var3: List[int]):
	...

mydict: MyDict = {...}

my_function(**mydict) # should pass
my_other_function(**mydict) # should not pass

Currently Pylance does not type check the unpacking and treats mydict as a normal dict. I think we could take advantage that we know the types of each value in the TypedDict to type check if all arguments are given and if given the correct type.
In this example my_other_function has an argument var1: str instead of int, so the type checker would show a type error.

More cases
  • When TypedDict have some optional values.
class BasicMyDict(TypedDict):
	var1: int
	var2: str
class MyDict(BasicMyDict, total=False):
	var3: bool

mydict: MyDict = {...}

def my_function(var1: int, var2: str, var3: bool):
	...
def my_other_function(var1: int, var2: str, var3: bool=True):
	...

my_function(**mydict) # should not pass
my_other_function(**mydict) # should pass

In this case for a function to allow unpacking of MyDict it should have arguments var1, var2 and var3 of the types indicated in the TypedDicts, but var3 must have a default value.

  • If we have a MyDict with 3 values and total=True, then when unpacking the function should have 3 arguments (if less then error raised) or define a **kwargs to match remaining.
def my_function(var1: int):
	...
def my_other_function(var1: int, **kwargs):
	...

my_function(**mydict) # should not pass
my_other_function(**mydict) # should pass
  • If MyDict do not complete the function arguments then they must be completed manually:
class MyDict(TypedDict):
	var1: int
	var2: int

mydict: MyDict = {...}

def my_function(var1: int, var2: int, var3: int, var4: bool):
	...

# this should give type error
my_function(**mydict)

# this should pass
my_function(**mydict, var3=1, var4=False)
@erictraut
Copy link
Contributor

Thanks for the feature request. This will be included in the next release.

@jakebailey
Copy link
Member

This issue has been fixed in version 2021.5.4, which we've just released. You can find the changelog here: https://github.com/microsoft/pylance-release/blob/main/CHANGELOG.md#202154-26-may-2021

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

4 participants