Verified Commit 1e270474 authored by Renato Alves's avatar Renato Alves 🌱
Browse files

Add example code and type check against Python 3.9

parent 1b90e6e7
......@@ -2,6 +2,8 @@
# Needed for Python >=3.7 <3.10
from __future__ import annotations
import sys
# Types to explore:
# int, str
# list, dict, tuple, set
......@@ -12,12 +14,124 @@ from __future__ import annotations
# typing.NewType (aka alias)
# collections.abc.*
# def multiply(var: annot = default) -> returnval:
from typing import Optional, NewType, TypeVar
IntOrStr = TypeVar("IntOrStr", int, str)
# Annotation syntax
# variable: type_annotation
# or
# variable: type_annotation = initial_value
# and a function
# def function(var: type_annotation = default_value) -> return_type:
# pass
# Accepts either int or str for x and returns the same type
def multiply(x: IntOrStr, y: int) -> IntOrStr:
return x * y
# When you need a list type but want to avoid func(arg = [])
# which creates a list in the global namespace.
# You'd need arg = (None or list)
def times_two(values: Optional[list[int]] = None) -> list[int]:
if values is None:
values = []
return [x * 2 for x in values]
def add_to_dict() -> dict[str, int]:
# dict[key, value]
mydict: dict[str, int] = {"key": 10}
return mydict
def tuples_work_too() -> None:
two_tuple: tuple[int, int]
three_tuple: tuple[int, str, int]
# arbitrary tuple length using an ellipsis
n_tuple: tuple[int, ...]
# an alias - seems to only be valid if defined in the global scope
String = str
def aliasing_vs_creating_a_new_type() -> None:
# an alias - seems to only be valid if defined in the global scope
# String = str # if done here this won't work
def transform_str(txt: String) -> String:
return txt
transform_str(String("hello")) # Is valid
transform_str(str("hello")) # Is valid
# NewType allows creating a representation of the same type that is
# considered different by the type checker
Text = NewType("Text", str)
def transform_text(txt: Text) -> str:
return txt
transform_text(Text("hello")) # Is valid
transform_text(str("hello")) # Fails: Incompatible type "str" expected "Text@76"
# NOTE, the type of "Text" is "Text@76" because the new type was defined
# inside a function
# A name is necessary to tell IDEs and static analyzers referring to your custom type
# unless you are using Python 3.9+ you need to use typing.<types> here
from typing import List, Dict
# In Python 3.7-3.8
Point = NewType("Point", List[Dict[str, List[int]]])
# In Python 3.9+
Point = NewType("Point", list[dict[str, list[int]]])
# You can then use Point as
def point_math(x: Point) -> Point:
return x
point_math(Point([{"key": [1, 2]}]))
return None
def using_classes_in_signatures() -> None:
class MyClass:
pass
class MyOtherClass(MyClass):
pass
def func(x: MyClass) -> MyClass:
return x
myclass: MyClass = MyOtherClass()
myotherclass: MyOtherClass = MyOtherClass()
func(myclass) # OK
func(myotherclass) # OK
def main() -> int:
result_int: int = multiply(10, 10)
result_str: str = multiply("Hello ", 10)
if not result_int or not result_str:
return 2
print(times_two())
print(add_to_dict())
tuples_work_too()
aliasing_vs_creating_a_new_type()
using_classes_in_signatures()
def main():
pass
return 0
if __name__ == "__main__":
main()
sys.exit(main())
......@@ -8,4 +8,4 @@ fi
source helpers/venv/bin/activate
mypy sample.py
mypy --python-version 3.9 sample.py
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment