Last active
February 25, 2022 05:30
-
-
Save chadrik/0b8585589b85aa4fba9f4ef2a952b633 to your computer and use it in GitHub Desktop.
Practical Guide to Python Static Typing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from functools import lru_cache | |
@lru_cache(None) | |
def getvalue() -> List[Set[int]]: | |
return [{1, 2}, {3}] | |
x = getvalue() | |
x.append({4}) | |
y = getvalue() | |
x == y # True! bad! | |
x is y # True! bad! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from functools import lru_cache | |
@lru_cache(None) | |
def getvalue() -> Sequence[AbstractSet[int]]: | |
return [{1, 2}, {3}] | |
x = getvalue() | |
x.append({4}) # mypy errors: no append method | |
x[0].add(4) # mypy errors: no add method |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def get_unique(input: List[str], invalid: List[str]) -> List[str]: | |
return [x for x in input if x not in invalid] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def get_unique(input: Iterable[str], invalid: Container[str]) -> List[str]: | |
return [x for x in input if x not in invalid] | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if None not in (x, y, z): | |
result = x + y + z |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if x is not None and y is not None and z is not None: | |
result = x + y + z |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
inputs = (x, y, z) | |
valid = [v for v in inputs if v is not None] | |
if len(valid) == len(inputs): | |
result = sum(valid) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if inspect.isclass(x) and issubclass(x, Asset): | |
... |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if isinstance(x, type) and issubclass(x, Asset): | |
... |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
isAsset = isinstance(x, Asset) | |
if isAsset: | |
... | |
else: | |
... |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if isinstance(x, Asset): | |
isAsset = True | |
... | |
else: | |
isAsset = False | |
... |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import subprocess | |
from typing import * | |
def ls(env: Optional[Dict[str, str]] = None) -> None: | |
args = "ls -la" | |
kwargs = {"shell": True} # <-- inferred type is Dict[str, bool] !!! | |
if env: | |
kwargs["env"] = env # error! env is not a bool | |
subprocess.call(args, **kwargs) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import subprocess | |
from typing import * | |
def ls(env: Optional[Dict[str, str]] = None) -> None: | |
args = "ls -la" | |
kwargs: Dict[str, Any] = {"shell": True} | |
if env: | |
kwargs["env"] = env | |
subprocess.call(args, **kwargs) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if whatever: | |
foo = 2 | |
else: | |
foo = 'some string' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if whatever: | |
foo: Union[int, str] = 2 | |
else: | |
foo = 'some string' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
l1 = [v for k, v in d.items() if k.startswith('foo')] | |
kwargs = {k: v for k, v in kw.items() if k in _keys} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
for i, path in enumerate(paths): | |
... | |
for i, item in enumerate(items): # ok! i is still an int | |
... |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import subprocess | |
from typing import * | |
def run(args: Union[str, List[str]], env: Optional[Dict[str, str]] = None) -> None: | |
kwargs: Dict[str, Any] = { | |
"shell": False, | |
} | |
if isinstance(args, str): | |
# in this scope, args is understood to be a str | |
args = args.split() # convert from str to List[str]. the str case of Union[str, List[str]] is now removed | |
# at this point args can now only be List[str] | |
if env: | |
kwargs["env"] = env | |
subprocess.call(args, **kwargs) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import subprocess | |
from typing import * | |
def run(args: str, env: Optional[Dict[str, str]] = None) -> None: | |
kwargs: Dict[str, Any] = { | |
"shell": False, | |
} | |
args = args.split() # can't reassign the type of args! | |
args.insert(0, 'xdg-open') | |
if env: | |
kwargs["env"] = env | |
subprocess.call(args, **kwargs) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import subprocess | |
from typing import * | |
def run(command: str, env: Optional[Dict[str, str]] = None) -> None: | |
kwargs: Dict[str, Any] = { | |
"shell": False, | |
} | |
args = command.split() | |
args.insert(0, 'xdg-open') | |
if env: | |
kwargs["env"] = env | |
subprocess.call(args, **kwargs) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def letter_list(s: str, strip_last: bool = False) -> Optional[str]: | |
if s: | |
result = list(s) | |
if strip_last: | |
result = result[:-1] | |
else: | |
result = None # <--- error: incompatible type | |
return result |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def letter_list(s: str, strip_last: bool = False) -> Optional[str]: | |
if s: | |
result: Optional[str] = list(s) | |
if strip_last: | |
result = result[:-1] # <--- error: None does not support indexing | |
else: | |
result = None | |
return result |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def letter_list(s: str, strip_last: bool = False) -> Optional[str]: | |
if s: | |
result = list(s) | |
if strip_last: | |
result = result[:-1] | |
return result | |
else: | |
return None |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Base: | |
validThings = ('thing1',) | |
class A(Base): | |
validThings = ('thing1', 'thing2') |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Base: | |
validThings: Tuple[str, ...] = ('thing1',) | |
class A(Base): | |
validThings: Tuple[str, ...] = ('thing1', 'thing2') |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Base: | |
validThings = FrozenSet(['thing1']) | |
class A(Base): | |
validThings = FrozenSet(['thing1', 'thing2']) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Base: | |
validThings: Final[List[str]] = ['thing1'] | |
class A(Base): | |
validThings: Final[List[str]] = ['thing1', 'thing2'] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment