| -- Test cases for keyword arguments. |
| |
| |
| [case testTypeErrorInKeywordArgument] |
| import typing |
| def f(o: object) -> None: pass |
| f(o=None()) # E: None not callable |
| |
| [case testSimpleKeywordArgument] |
| import typing |
| def f(a: 'A') -> None: pass |
| f(a=A()) |
| f(a=object()) # E: Argument 1 to "f" has incompatible type "object"; expected "A" |
| class A: pass |
| |
| [case testTwoKeywordArgumentsNotInOrder] |
| import typing |
| def f(a: 'A', b: 'B') -> None: pass |
| f(b=A(), a=A()) # E: Argument 1 to "f" has incompatible type "A"; expected "B" |
| f(b=B(), a=B()) # E: Argument 2 to "f" has incompatible type "B"; expected "A" |
| f(a=A(), b=B()) |
| f(b=B(), a=A()) |
| class A: pass |
| class B: pass |
| |
| [case testOneOfSeveralOptionalKeywordArguments] |
| import typing |
| def f(a: 'A' = None, b: 'B' = None, c: 'C' = None) -> None: pass |
| f(a=A()) |
| f(b=B()) |
| f(c=C()) |
| f(b=B(), c=C()) |
| f(a=B()) # E: Argument 1 to "f" has incompatible type "B"; expected "A" |
| f(b=A()) # E: Argument 1 to "f" has incompatible type "A"; expected "B" |
| f(c=B()) # E: Argument 1 to "f" has incompatible type "B"; expected "C" |
| f(b=B(), c=A()) # E: Argument 2 to "f" has incompatible type "A"; expected "C" |
| class A: pass |
| class B: pass |
| class C: pass |
| |
| [case testBothPositionalAndKeywordArguments] |
| import typing |
| def f(a: 'A', b: 'B') -> None: pass |
| f(A(), b=A()) # E: Argument 2 to "f" has incompatible type "A"; expected "B" |
| f(A(), b=B()) |
| class A: pass |
| class B: pass |
| |
| [case testContextSensitiveTypeInferenceForKeywordArg] |
| from typing import List |
| def f(a: 'A', b: 'List[A]') -> None: pass |
| f(b=[], a=A()) |
| class A: pass |
| [builtins fixtures/list.pyi] |
| |
| [case testGivingSameKeywordArgumentTwice] |
| import typing |
| def f(a: 'A', b: 'B') -> None: pass |
| f(a=A(), b=B(), a=A()) # E: keyword argument repeated |
| class A: pass |
| class B: pass |
| |
| [case testGivingArgumentAsPositionalAndKeywordArg] |
| import typing |
| def f(a: 'A', b: 'B' = None) -> None: pass |
| f(A(), a=A()) # E: "f" gets multiple values for keyword argument "a" |
| class A: pass |
| class B: pass |
| |
| [case testGivingArgumentAsPositionalAndKeywordArg2] |
| import typing |
| def f(a: 'A' = None, b: 'B' = None) -> None: pass |
| f(A(), a=A()) # E: "f" gets multiple values for keyword argument "a" |
| class A: pass |
| class B: pass |
| |
| [case testPositionalAndKeywordForSameArg] |
| # This used to crash in check_argument_count(). See #1095. |
| def f(a: int): pass |
| def g(): f(0, a=1) |
| [out] |
| |
| [case testInvalidKeywordArgument] |
| import typing |
| def f(a: 'A') -> None: pass # N: "f" defined here |
| f(b=object()) # E: Unexpected keyword argument "b" for "f" |
| class A: pass |
| |
| [case testKeywordArgumentsWithDynamicallyTypedCallable] |
| from typing import Any |
| f = None # type: Any |
| f(x=f(), z=None()) # E: None not callable |
| f(f, zz=None()) # E: None not callable |
| f(x=None) |
| |
| [case testKeywordArgumentWithFunctionObject] |
| from typing import Callable |
| f = None # type: Callable[[A, B], None] |
| f(a=A(), b=B()) |
| f(A(), b=B()) |
| class A: pass |
| class B: pass |
| [out] |
| main:3: error: Unexpected keyword argument "a" |
| main:3: error: Unexpected keyword argument "b" |
| main:4: error: Unexpected keyword argument "b" |
| |
| [case testKeywordOnlyArguments] |
| import typing |
| def f(a: 'A', *, b: 'B' = None) -> None: pass |
| def g(a: 'A', *, b: 'B') -> None: pass |
| def h(a: 'A', *, b: 'B', aa: 'A') -> None: pass |
| def i(a: 'A', *, b: 'B', aa: 'A' = None) -> None: pass |
| f(A(), b=B()) |
| f(b=B(), a=A()) |
| f(A()) |
| f(A(), B()) # E: Too many positional arguments for "f" |
| g(A(), b=B()) |
| g(b=B(), a=A()) |
| g(A()) # E: Missing named argument "b" for function "g" |
| g(A(), B()) # E: Too many positional arguments for "g" |
| h(A()) # E: Missing named argument "b" for function "h" # E: Missing named argument "aa" for function "h" |
| h(A(), b=B()) # E: Missing named argument "aa" for function "h" |
| h(A(), aa=A()) # E: Missing named argument "b" for function "h" |
| h(A(), b=B(), aa=A()) |
| h(A(), aa=A(), b=B()) |
| i(A()) # E: Missing named argument "b" for function "i" |
| i(A(), b=B()) |
| i(A(), aa=A()) # E: Missing named argument "b" for function "i" |
| i(A(), b=B(), aa=A()) |
| i(A(), aa=A(), b=B()) |
| |
| class A: pass |
| class B: pass |
| |
| [case testKeywordOnlyArgumentsFastparse] |
| # flags: --fast-parser |
| import typing |
| def f(a: 'A', *, b: 'B' = None) -> None: pass |
| def g(a: 'A', *, b: 'B') -> None: pass |
| def h(a: 'A', *, b: 'B', aa: 'A') -> None: pass |
| def i(a: 'A', *, b: 'B', aa: 'A' = None) -> None: pass |
| f(A(), b=B()) |
| f(b=B(), a=A()) |
| f(A()) |
| f(A(), B()) # E: Too many positional arguments for "f" |
| g(A(), b=B()) |
| g(b=B(), a=A()) |
| g(A()) # E: Missing named argument "b" for function "g" |
| g(A(), B()) # E: Too many positional arguments for "g" |
| h(A()) # E: Missing named argument "b" for function "h" # E: Missing named argument "aa" for function "h" |
| h(A(), b=B()) # E: Missing named argument "aa" for function "h" |
| h(A(), aa=A()) # E: Missing named argument "b" for function "h" |
| h(A(), b=B(), aa=A()) |
| h(A(), aa=A(), b=B()) |
| i(A()) # E: Missing named argument "b" for function "i" |
| i(A(), b=B()) |
| i(A(), aa=A()) # E: Missing named argument "b" for function "i" |
| i(A(), b=B(), aa=A()) |
| i(A(), aa=A(), b=B()) |
| |
| class A: pass |
| class B: pass |
| |
| [case testKwargsAfterBareArgs] |
| from typing import Tuple, Any |
| def f(a, *, b=None) -> None: pass |
| a = None # type: Any |
| b = None # type: Any |
| f(a, **b) |
| |
| [builtins fixtures/dict.pyi] |
| |
| [case testKeywordArgAfterVarArgs] |
| import typing |
| def f(*a: 'A', b: 'B' = None) -> None: pass |
| f() |
| f(A()) |
| f(A(), A()) |
| f(b=B()) |
| f(A(), b=B()) |
| f(A(), A(), b=B()) |
| f(B()) # E: Argument 1 to "f" has incompatible type "B"; expected "A" |
| f(A(), B()) # E: Argument 2 to "f" has incompatible type "B"; expected "A" |
| f(b=A()) # E: Argument 1 to "f" has incompatible type "A"; expected "B" |
| class A: pass |
| class B: pass |
| [builtins fixtures/list.pyi] |
| |
| [case testKeywordArgAfterVarArgsWithBothCallerAndCalleeVarArgs] |
| from typing import List |
| def f(*a: 'A', b: 'B' = None) -> None: pass |
| a = None # type: List[A] |
| f(*a) |
| f(A(), *a) |
| f(b=B()) |
| f(*a, b=B()) |
| f(A(), *a, b=B()) |
| f(A(), B()) # E: Argument 2 to "f" has incompatible type "B"; expected "A" |
| f(A(), b=A()) # E: Argument 2 to "f" has incompatible type "A"; expected "B" |
| f(*a, b=A()) # E: Argument 2 to "f" has incompatible type "A"; expected "B" |
| class A: pass |
| class B: pass |
| [builtins fixtures/list.pyi] |
| |
| [case testCallingDynamicallyTypedFunctionWithKeywordArgs] |
| import typing |
| def f(x, y=A()): pass |
| f(x=A(), y=A()) |
| f(y=A(), x=A()) |
| f(y=A()) # E: Missing positional argument "x" in call to "f" |
| f(A(), z=A()) # E: Unexpected keyword argument "z" for "f" |
| class A: pass |
| |
| [case testKwargsArgumentInFunctionBody] |
| from typing import Dict, Any |
| def f( **kwargs: 'A') -> None: |
| d1 = kwargs # type: Dict[str, A] |
| d2 = kwargs # type: Dict[A, Any] # E: Incompatible types in assignment (expression has type Dict[str, A], variable has type Dict[A, Any]) |
| d3 = kwargs # type: Dict[Any, str] # E: Incompatible types in assignment (expression has type Dict[str, A], variable has type Dict[Any, str]) |
| class A: pass |
| [builtins fixtures/dict.pyi] |
| [out] |
| |
| [case testKwargsArgumentInFunctionBodyWithImplicitAny] |
| from typing import Dict, Any |
| def f(**kwargs) -> None: |
| d1 = kwargs # type: Dict[str, A] |
| d2 = kwargs # type: Dict[str, str] |
| d3 = kwargs # type: Dict[A, Any] # E: Incompatible types in assignment (expression has type Dict[str, Any], variable has type Dict[A, Any]) |
| class A: pass |
| [builtins fixtures/dict.pyi] |
| [out] |
| |
| [case testCallingFunctionThatAcceptsVarKwargs] |
| import typing |
| def f( **kwargs: 'A') -> None: pass |
| f() |
| f(x=A()) |
| f(y=A(), z=A()) |
| f(x=B()) # E: Argument 1 to "f" has incompatible type "B"; expected "A" |
| f(A()) # E: Too many arguments for "f" |
| # Perhaps a better message would be "Too many *positional* arguments..." |
| class A: pass |
| class B: pass |
| [builtins fixtures/dict.pyi] |
| |
| [case testCallingFunctionWithKeywordVarArgs] |
| from typing import Dict |
| def f( **kwargs: 'A') -> None: pass |
| d = None # type: Dict[str, A] |
| f(**d) |
| f(x=A(), **d) |
| d2 = None # type: Dict[str, B] |
| f(**d2) # E: Argument 1 to "f" has incompatible type **Dict[str, B]; expected "A" |
| f(x=A(), **d2) # E: Argument 2 to "f" has incompatible type **Dict[str, B]; expected "A" |
| class A: pass |
| class B: pass |
| [builtins fixtures/dict.pyi] |
| |
| [case testInvalidTypeForKeywordVarArg] |
| from typing import Dict |
| def f( **kwargs: 'A') -> None: pass |
| d = None # type: Dict[A, A] |
| f(**d) # E: Keywords must be strings |
| f(**A()) # E: Argument after ** must be a dictionary |
| class A: pass |
| [builtins fixtures/dict.pyi] |
| |
| [case testPassingKeywordVarArgsToNonVarArgsFunction] |
| from typing import Any, Dict |
| def f(a: 'A', b: 'B') -> None: pass |
| d = None # type: Dict[str, Any] |
| f(**d) |
| d2 = None # type: Dict[str, A] |
| f(**d2) # E: Argument 1 to "f" has incompatible type **Dict[str, A]; expected "B" |
| class A: pass |
| class B: pass |
| [builtins fixtures/dict.pyi] |
| |
| [case testBothKindsOfVarArgs] |
| from typing import Any, List, Dict |
| def f(a: 'A', b: 'A') -> None: pass |
| l = None # type: List[Any] |
| d = None # type: Dict[Any, Any] |
| f(*l, **d) |
| class A: pass |
| [builtins fixtures/dict.pyi] |
| |
| [case testKeywordArgumentAndCommentSignature] |
| import typing |
| def f(x): # type: (int) -> str # N: "f" defined here |
| pass |
| f(x='') # E: Argument 1 to "f" has incompatible type "str"; expected "int" |
| f(x=0) |
| f(y=0) # E: Unexpected keyword argument "y" for "f" |
| |
| [case testKeywordArgumentAndCommentSignature2] |
| import typing |
| class A: |
| def f(self, x): # type: (int) -> str |
| pass |
| A().f(x='') # E: Argument 1 to "f" of "A" has incompatible type "str"; expected "int" |
| A().f(x=0) |
| A().f(y=0) # E: Unexpected keyword argument "y" for "f" of "A" |
| |
| [case testKeywordVarArgsAndCommentSignature] |
| import typing |
| def f(**kwargs): # type: (**int) -> None |
| pass |
| f(z=1) |
| f(x=1, y=1) |
| f(x='', y=1) # E: Argument 1 to "f" has incompatible type "str"; expected "int" |
| f(x=1, y='') # E: Argument 2 to "f" has incompatible type "str"; expected "int" |
| [builtins fixtures/dict.pyi] |
| |
| [case testCallsWithStars] |
| def f(a: int) -> None: |
| pass |
| |
| s = ('',) |
| f(*s) # E: Argument 1 to "f" has incompatible type *"Tuple[str]"; expected "int" |
| |
| a = {'': 0} |
| f(a) # E: Argument 1 to "f" has incompatible type Dict[str, int]; expected "int" |
| f(**a) # okay |
| |
| b = {'': ''} |
| f(b) # E: Argument 1 to "f" has incompatible type Dict[str, str]; expected "int" |
| f(**b) # E: Argument 1 to "f" has incompatible type **Dict[str, str]; expected "int" |
| |
| c = {0: 0} |
| f(**c) # E: Keywords must be strings |
| [builtins fixtures/dict.pyi] |
| |
| [case testCallStar2WithStar] |
| def f(**k): pass |
| f(*(1, 2)) # E: Too many arguments for "f" |
| [builtins fixtures/dict.pyi] |