Types my way: Static Typing in Python

Joe Cabrera
Joe CabreraSoftware Engineer at Hearst
Types my way: Static typing in Python
Joe Cabrera
Dynamically typing
The Python interpreter checks types as your code runs and the type of variable
can change during it’s lifetime
>>> thing = "hello"
>>> type(thing)
<class 'str'>
>>> thing = 29.0
>>> type(thing)
<class 'float'>
Static Typing
Static typing checks run without even running the program, usually when the code
is compiled (C++ and Java)
String thing;
thing = "Hello";
Duck Typing
“If it walks like a duck and it quacks like a duck, this it must be a duck”
You do not check types at all, instead you check if an object has a method or
attribute
>>> class Malort:
... def __str__(self):
... return "Jeppson's Malört"
... def __format__(self, format):
... if(format == 'where'):
... return "only in chicago"
... return "None"
...
>>> print(format(Malort(), "where"))
only in chicago
def get_caching_header(args=None):
"""
Get cache header dictionary.
:param args: Query arguments for used to build surrogate key
:type args: dict
:return: Cache header dictionary
"""
def get_caching_header(args=None):
"""
Get cache header dictionary.
"""
assert type(args) is dict
Optional Type Checking
- Compile-time type checking
- Easier to find bugs
- Less debugging
- Easier maintenance
- Machine-checked documentation
- Easier to understand code
- Grow from dynamic to static typing
- You can add static typing existing codebases after your code has matured
- You can gradually add type hints with Any
Why should you start type checking now?
● Great for complex and confusing code
● Good for open-source code
● Before migrating or refactoring code
PEP 484: Type Hints
Python will remain a dynamically typed language, and the authors have no desire
to ever make type hints mandatory, even by convention.
Type hints have no runtime effect
>>> def shot(location: str) -> str:
... if location == "new york":
... return "hennessy"
... elif location == "chicago":
... return "evan williams"
... else:
... return "jack daniels"
Function annotations
Functions can have annotation arguments and return value
>>> def beer(location: str, with_shot: bool = True) -> str:
...
>>> beer.__annotations__
{'location': <class 'str'>, 'with_shot': <class 'bool'>}
Variable annotations
Available since Python 3.6
>>> speed_of_sound: float = 343.0
Type & Variable Comments
Annotations are great, but have not been backported to Python 2.x
Type comments can be used in any version of Python
>>> def beer(location, with_shot):
>>> # type: (str, bool) -> str
>>> ...
>>> speed_of_sound = 343.0 # type: float
Sequences & Mappings
Great we can do primitives but what about composite types. Also not an issue…
>>> beers: list = ["Coors Light", "Budweiser", "Corona"]
>>> shots: tuple = ("B-52", "Irish Car Bomb", "Lemon Drop")
>>> beer_shot: dict = {"Coors Light": "Jack Daniels", "Corona": "Tequila"}
Typing module
Composite types are great, but what about the individual values
>>> from typing import Dict, List, Tuple
>>> beers: List[str] = ["Coors Light", "Budweiser", "Corona"]
>>> shots: Tuple[str, str, str] = ("B-52", "Irish Car Bomb", "Lemon
Drop")
>>> beer_shot: Dict[str, str] = {"Coors Light": "Jack Daniels",
>>> ... "Corona": "Tequila"}
Sequences
Many times you expect some kind of sequence but do not care if it’s a list or a
tuple
>>> from typing import List, Sequence
>>>
>>> def take_shot(liquors: Sequence[str]) -> str:
>>> return random.choice(liquors)
Type Aliases
Instead of
Write this
>>> from typing import List, Tuple
>>>
>>> def take_shots(beer_shot: List[Tuple[str, str]]) -> Tuple[
>>> List[Tuple[str, str]],
>>> List[Tuple[str, str]],
>>> List[Tuple[str, str]],
>>> ]:
>>> return (beer_shot[0::3], beer_shot[1::3], beer_shot[2::3])
>>> from typing import List, Tuple
>>> Boilermaker = Tuple[str, str]
Functions without return values
>>> def shot(location: str) -> None:
... if location == "new york":
... print("hennessy")
... elif location == "chicago":
... print("evan williams")
... else:
... print("jack daniels")
>>> from typing import NoReturn
>>>
>>> def the_darkness() -> NoReturn:
raise Exception("It's too late")
The magically Any type
>>> from typing import Any, Sequence
>>>
>>> def take_shot(liquors: Sequence[Any]) -> Any:
>>> return random.choice(liquors)
The Optional Type
For functions that have a default value for an argument
>>> from typing import Sequence, Optional
>>>
>>> def beer_order(names: Sequence[str],
>>> ... start: Optional[str] = None) -> Sequence[str]:
The Union Type
When you need arguments of several types in a composite
>>> from typing import Union
>>>
>>> def beer_order(nashville_beer: Union[str, int]) -> Sequence[str]:
Annonating *args and **kwargs
>>> class Bar
>>> def __init__(self, beers: List[Beer],
>>> *customer: str,
>>> **drink_types: str) -> None:
>>> self.beers = beers
Callables
>>> from typing import Callable
>>>
>>> def take_shot(func: Callable[[str], str], argument: str) -> None:
>>> print(func(argument))
>>>
>>> def create_response(liquor: str) -> str:
>>> return f"A shot of {liquor}"
>>>
>>> take_shot(create_response, "Jack Daniels")
Protocols
>>> class Bar:
>>> def meth(self) -> int:
>>> return 0
>>>
>>> def func(x: Proto) -> int:
>>> return x.meth()
Classes as Types
>>> class Bar
>>> def __init__(self, beers: List[Beer]) -> None:
>>> self.beers = beers
>>>
>>> @classmethod
>>> def open(cls, restock: bool = False) -> "Bar":
return cls(beers)
Coming in Python 4.0
>>> from __future__ import annotations
>>>
>>> class Bar
>>>
>>> @classmethod
>>> def open(cls, restock: bool = False) -> Bar:
>>> return cls(beers)
Type-checkers
Static
● MyPy (Dropbox)
● PyType (Google)
● Pyre (Facebook)
● Pyright (Microsoft)
● PyCharm
Dynamic
● Enforce, Typeguard, Typo
Thanks!
@greedoshotlast
1 of 27

More Related Content

What's hot(20)

Developing iOS apps with SwiftDeveloping iOS apps with Swift
Developing iOS apps with Swift
New Generation Applications7K views
Concurrent Application Development using ScalaConcurrent Application Development using Scala
Concurrent Application Development using Scala
Siarhiej Siemianchuk272 views
Unit testUnit test
Unit test
David Xie501 views
Dependent Types with IdrisDependent Types with Idris
Dependent Types with Idris
Abdulsattar Mohammed296 views
Javascript Common MistakesJavascript Common Mistakes
Javascript Common Mistakes
동수 장908 views
How to Clone Flappy Bird in SwiftHow to Clone Flappy Bird in Swift
How to Clone Flappy Bird in Swift
Giordano Scalzo36.7K views
6 new ES6 features6 new ES6 features
6 new ES6 features
Kyle Dorman379 views
Selfish presentation - ruby internalsSelfish presentation - ruby internals
Selfish presentation - ruby internals
Wojciech Widenka79 views
NamespacesNamespaces
Namespaces
zindadili129 views
ES2015 (ES6) OverviewES2015 (ES6) Overview
ES2015 (ES6) Overview
hesher22.4K views
Whats New In C# 3.0Whats New In C# 3.0
Whats New In C# 3.0
Clint Edmonson764 views
Testing For UnicornsTesting For Unicorns
Testing For Unicorns
Alex Soto625 views
PyLecture1 -Python Basics-PyLecture1 -Python Basics-
PyLecture1 -Python Basics-
Yoshiki Satotani172 views
Cifrado cesarCifrado cesar
Cifrado cesar
EIYSC166 views
EcmaScript unchainedEcmaScript unchained
EcmaScript unchained
Eduard Tomàs1.1K views
Scroll pHAT HD に美咲フォントScroll pHAT HD に美咲フォント
Scroll pHAT HD に美咲フォント
Yuriko IKEDA1.9K views
AssignmentAssignment
Assignment
Ayesha Bhatti613 views
Exploring ES6Exploring ES6
Exploring ES6
Ximing Dai300 views

Similar to Types my way: Static Typing in Python(20)

Python coursePython course
Python course
Евгений Сазонов1.4K views
Python study materialPython study material
Python study material
Satish Nagabhushan2.9K views
Python 1Python 1
Python 1
Ramin Najjarbashi687 views
Welcome vibrant-technology-navimumbaiWelcome vibrant-technology-navimumbai
Welcome vibrant-technology-navimumbai
Vibrant Technologies & Computers134 views
Welcome vibrant-technology-navimumbaiWelcome vibrant-technology-navimumbai
Welcome vibrant-technology-navimumbai
Vibrant Technologies & Computers111 views
Python String Revisited.pptxPython String Revisited.pptx
Python String Revisited.pptx
Chandrapriya Jayabal93 views
An overview of Python 2.7An overview of Python 2.7
An overview of Python 2.7
decoupled248 views
A tour of PythonA tour of Python
A tour of Python
Aleksandar Veselinovic1.1K views
Beautiful python - PyLadiesBeautiful python - PyLadies
Beautiful python - PyLadies
Alicia Pérez389 views
Python materialPython material
Python material
Ruchika Sinha14 views
Introduction to PythonIntroduction to Python
Introduction to Python
UC San Diego566 views
Python crush coursePython crush course
Python crush course
Mohammed El Rafie Tarabay248 views
Python  Workshop Python  Workshop
Python Workshop
Assem CHELLI809 views
PythonPython
Python
Vishal Sancheti966 views
Investigating Python WatsInvestigating Python Wats
Investigating Python Wats
Amy Hanlon182 views
From android/java to swift (3)From android/java to swift (3)
From android/java to swift (3)
allanh052690 views

Recently uploaded(20)

CXL at OCPCXL at OCP
CXL at OCP
CXL Forum158 views
Green Leaf Consulting: Capabilities DeckGreen Leaf Consulting: Capabilities Deck
Green Leaf Consulting: Capabilities Deck
GreenLeafConsulting147 views
Java Platform Approach 1.0 - Picnic MeetupJava Platform Approach 1.0 - Picnic Meetup
Java Platform Approach 1.0 - Picnic Meetup
Rick Ossendrijver20 views
Web Dev - 1 PPT.pdfWeb Dev - 1 PPT.pdf
Web Dev - 1 PPT.pdf
gdsczhcet44 views
ChatGPT and AI for Web DevelopersChatGPT and AI for Web Developers
ChatGPT and AI for Web Developers
Maximiliano Firtman143 views
ThroughputThroughput
Throughput
Moisés Armani Ramírez25 views
METHOD AND SYSTEM FOR PREDICTING OPTIMAL LOAD FOR WHICH THE YIELD IS MAXIMUM ...METHOD AND SYSTEM FOR PREDICTING OPTIMAL LOAD FOR WHICH THE YIELD IS MAXIMUM ...
METHOD AND SYSTEM FOR PREDICTING OPTIMAL LOAD FOR WHICH THE YIELD IS MAXIMUM ...
Prity Khastgir IPR Strategic India Patent Attorney Amplify Innovation22 views

Types my way: Static Typing in Python

  • 1. Types my way: Static typing in Python Joe Cabrera
  • 2. Dynamically typing The Python interpreter checks types as your code runs and the type of variable can change during it’s lifetime >>> thing = "hello" >>> type(thing) <class 'str'> >>> thing = 29.0 >>> type(thing) <class 'float'>
  • 3. Static Typing Static typing checks run without even running the program, usually when the code is compiled (C++ and Java) String thing; thing = "Hello";
  • 4. Duck Typing “If it walks like a duck and it quacks like a duck, this it must be a duck” You do not check types at all, instead you check if an object has a method or attribute >>> class Malort: ... def __str__(self): ... return "Jeppson's Malört" ... def __format__(self, format): ... if(format == 'where'): ... return "only in chicago" ... return "None" ... >>> print(format(Malort(), "where")) only in chicago
  • 5. def get_caching_header(args=None): """ Get cache header dictionary. :param args: Query arguments for used to build surrogate key :type args: dict :return: Cache header dictionary """
  • 6. def get_caching_header(args=None): """ Get cache header dictionary. """ assert type(args) is dict
  • 7. Optional Type Checking - Compile-time type checking - Easier to find bugs - Less debugging - Easier maintenance - Machine-checked documentation - Easier to understand code - Grow from dynamic to static typing - You can add static typing existing codebases after your code has matured - You can gradually add type hints with Any
  • 8. Why should you start type checking now? ● Great for complex and confusing code ● Good for open-source code ● Before migrating or refactoring code
  • 9. PEP 484: Type Hints Python will remain a dynamically typed language, and the authors have no desire to ever make type hints mandatory, even by convention. Type hints have no runtime effect >>> def shot(location: str) -> str: ... if location == "new york": ... return "hennessy" ... elif location == "chicago": ... return "evan williams" ... else: ... return "jack daniels"
  • 10. Function annotations Functions can have annotation arguments and return value >>> def beer(location: str, with_shot: bool = True) -> str: ... >>> beer.__annotations__ {'location': <class 'str'>, 'with_shot': <class 'bool'>}
  • 11. Variable annotations Available since Python 3.6 >>> speed_of_sound: float = 343.0
  • 12. Type & Variable Comments Annotations are great, but have not been backported to Python 2.x Type comments can be used in any version of Python >>> def beer(location, with_shot): >>> # type: (str, bool) -> str >>> ... >>> speed_of_sound = 343.0 # type: float
  • 13. Sequences & Mappings Great we can do primitives but what about composite types. Also not an issue… >>> beers: list = ["Coors Light", "Budweiser", "Corona"] >>> shots: tuple = ("B-52", "Irish Car Bomb", "Lemon Drop") >>> beer_shot: dict = {"Coors Light": "Jack Daniels", "Corona": "Tequila"}
  • 14. Typing module Composite types are great, but what about the individual values >>> from typing import Dict, List, Tuple >>> beers: List[str] = ["Coors Light", "Budweiser", "Corona"] >>> shots: Tuple[str, str, str] = ("B-52", "Irish Car Bomb", "Lemon Drop") >>> beer_shot: Dict[str, str] = {"Coors Light": "Jack Daniels", >>> ... "Corona": "Tequila"}
  • 15. Sequences Many times you expect some kind of sequence but do not care if it’s a list or a tuple >>> from typing import List, Sequence >>> >>> def take_shot(liquors: Sequence[str]) -> str: >>> return random.choice(liquors)
  • 16. Type Aliases Instead of Write this >>> from typing import List, Tuple >>> >>> def take_shots(beer_shot: List[Tuple[str, str]]) -> Tuple[ >>> List[Tuple[str, str]], >>> List[Tuple[str, str]], >>> List[Tuple[str, str]], >>> ]: >>> return (beer_shot[0::3], beer_shot[1::3], beer_shot[2::3]) >>> from typing import List, Tuple >>> Boilermaker = Tuple[str, str]
  • 17. Functions without return values >>> def shot(location: str) -> None: ... if location == "new york": ... print("hennessy") ... elif location == "chicago": ... print("evan williams") ... else: ... print("jack daniels") >>> from typing import NoReturn >>> >>> def the_darkness() -> NoReturn: raise Exception("It's too late")
  • 18. The magically Any type >>> from typing import Any, Sequence >>> >>> def take_shot(liquors: Sequence[Any]) -> Any: >>> return random.choice(liquors)
  • 19. The Optional Type For functions that have a default value for an argument >>> from typing import Sequence, Optional >>> >>> def beer_order(names: Sequence[str], >>> ... start: Optional[str] = None) -> Sequence[str]:
  • 20. The Union Type When you need arguments of several types in a composite >>> from typing import Union >>> >>> def beer_order(nashville_beer: Union[str, int]) -> Sequence[str]:
  • 21. Annonating *args and **kwargs >>> class Bar >>> def __init__(self, beers: List[Beer], >>> *customer: str, >>> **drink_types: str) -> None: >>> self.beers = beers
  • 22. Callables >>> from typing import Callable >>> >>> def take_shot(func: Callable[[str], str], argument: str) -> None: >>> print(func(argument)) >>> >>> def create_response(liquor: str) -> str: >>> return f"A shot of {liquor}" >>> >>> take_shot(create_response, "Jack Daniels")
  • 23. Protocols >>> class Bar: >>> def meth(self) -> int: >>> return 0 >>> >>> def func(x: Proto) -> int: >>> return x.meth()
  • 24. Classes as Types >>> class Bar >>> def __init__(self, beers: List[Beer]) -> None: >>> self.beers = beers >>> >>> @classmethod >>> def open(cls, restock: bool = False) -> "Bar": return cls(beers)
  • 25. Coming in Python 4.0 >>> from __future__ import annotations >>> >>> class Bar >>> >>> @classmethod >>> def open(cls, restock: bool = False) -> Bar: >>> return cls(beers)
  • 26. Type-checkers Static ● MyPy (Dropbox) ● PyType (Google) ● Pyre (Facebook) ● Pyright (Microsoft) ● PyCharm Dynamic ● Enforce, Typeguard, Typo