Mypy Examples

Here are some mypy example programs. Each example has dynamically typed Python/mypy code and equivalent statically typed mypy code side by side. Every program is still valid Python 3.x. All differences between the variants are highlighted.

Word frequencies with a dictionary

Mypy with dynamic typing
# Display the frequencies of wordsina file.

importsys
importre


ifnotsys.argv[1:]:
raiseRuntimeError('Usage: wordfreq FILE')

d = {}

withopen(sys.argv[1])asf:
forsinf:
forwordinre.sub('\W',' ',s).split():
d[word] = d.get(word, 0) + 1

# Uselistcomprehension
l = [(freq, word)forword, freqind.items()]

forfreq, wordinsorted(l):
print('%-6d %s'% (freq, word))
Mypy with static typing
# Display the frequencies of wordsina file.

importsys
importre
fromtypingimportDict

ifnotsys.argv[1:]:
raiseRuntimeError('Usage: wordfreq FILE')

d = {}# type:Dict[str,int]

withopen(sys.argv[1])asf:
forsinf:
forwordinre.sub('\W',' ',s).split():
d[word] = d.get(word, 0) + 1

# Uselistcomprehension
l = [(freq, word)forword, freqind.items()]

forfreq, wordinsorted(l):
print('%-6d %s'% (freq, word))

In this example we add an explicit type declaration for the variable d, as it is not obvious from the local context.

Simple class

Mypy with dynamic typing
classBankAccount:
def__init__(self, initial_balance=0):
self.balance = initial_balance
defdeposit(self, amount):
self.balance += amount
defwithdraw(self, amount):
self.balance -= amount
defoverdrawn(self):
returnself.balance < 0

my_account = BankAccount(15)
my_account.withdraw(5)
print(my_account.balance)
Mypy with static typing
classBankAccount:
def__init__(self, initial_balance:int= 0) -> None:
self.balance = initial_balance
defdeposit(self, amount:int) -> None:
self.balance += amount
defwithdraw(self, amount:int) -> None:
self.balance -= amount
defoverdrawn(self) ->bool:
returnself.balance < 0

my_account = BankAccount(15)
my_account.withdraw(5)
print(my_account.balance)

In this example we chose to use integers to represent balance. This would be fine in a game, for example, but in other applications a different type would make more sense.

This example was adapted from the Python wiki(with the standard Python license).

Prime number sieve with generators

Mypy with dynamic typing
importitertools


defiter_primes():
# An iterator of all numbers between 2 and
# +infinity
numbers = itertools.count(2)

# Generate primes forever
whileTrue:
# Get the first numberfromthe iterator
# (always a prime)
prime = next(numbers)
yieldprime

# This code iteratively builds up a chain
# of filters...
numbers = filter(prime.__rmod__, numbers)

forpiniter_primes():
ifp > 1000:
break
print(p)
Mypy with static typing
importitertools
fromtypingimportIterator

defiter_primes() ->Iterator[int]:
# An iterator of all numbers between 2 and
# +infinity
numbers = itertools.count(2)

# Generate primes forever
whileTrue:
# Get the first numberfromthe iterator
# (always a prime)
prime = next(numbers)
yieldprime

# This code iteratively builds up a chain
# of filters...
numbers = filter(prime.__rmod__, numbers)

forpiniter_primes():
ifp > 1000:
break
print(p)

Like the bank account example, this was adapted from the Python wiki.