Sample code for Chapter 10 - "Design patterns with first class functions"
From the book "Fluent Python" by Luciano Ramalho (O'Reilly, 2015) http://shop.oreilly.com/product/0636920032519.do
Running Mypy on classic_strategy.py
from the first edition, with no
type hints:
$ mypy classic_strategy.py Success: no issues found in 1 source file
When the Order.due
method made first assignment to discount as discount = 0
,
Mypy complained:
mypy classic_strategy.py classic_strategy.py:68: error: Incompatible types in assignment (expression has type "float", variable has type "int") Found 1 error in 1 file (checked 1 source file)
To fix it, I made the first assigment as discount = 0
.
I never explicitly declared a type for discount
.
Mypy did not raise any issues with this test case:
def test_bulk_item_promo_with_discount(customer_fidelity_0): cart = [LineItem('banana', 30, .5), LineItem('apple', 10, 1.5)] order = Order(customer_fidelity_0, 10, BulkItemPromo()) assert order.total() == 30.0 assert order.due() == 28.5
The second argument to Order
is declared as Sequence[LineItem]
.
Mypy only checks the body of a function the signature as at least one annotation,
like this:
def test_bulk_item_promo_with_discount(customer_fidelity_0) -> None: cart = [LineItem('banana', 30, .5), LineItem('apple', 10, 1.5)] order = Order(customer_fidelity_0, 10, BulkItemPromo()) assert order.total() == 30.0 assert order.due() == 28.5
Now Mypy complains that "Argument 2 of Order has incompatible type".
However, even with the annotation in the test function signature,
Mypy did not find any problem when I mistyped the name of the cart
argument.
Here, cart_plain
should be cart
:
def test_bulk_item_promo_with_discount(customer_fidelity_0) -> None: cart = [LineItem('banana', 30, .5), LineItem('apple', 10, 1.5)] order = Order(customer_fidelity_0, cart_plain, BulkItemPromo()) assert order.total() == 30.0 assert order.due() == 28.5
Hypotesis: cart_plain
is a function decorated with @pytest.fixture
,
and at the top of the test file I told Mypy to ignore the Pytest import:
import pytest # type: ignore