Skip to content

Commit a5e4d69

Browse files
committed
Fix mypy edge cases across modules
1 parent bf21c55 commit a5e4d69

8 files changed

Lines changed: 28 additions & 23 deletions

File tree

ultimatepython/advanced/date_time.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
from datetime import datetime, timezone
2727

2828

29-
def convert_dt_to_utc_epoch(dt: datetime) -> int:
29+
def convert_dt_to_utc_epoch(dt: datetime) -> float:
3030
"""Convert datetime to UTC epoch seconds.
3131
3232
Note that the timestamp method assumes that an offset-naive
@@ -36,7 +36,7 @@ def convert_dt_to_utc_epoch(dt: datetime) -> int:
3636
return dt.timestamp()
3737

3838

39-
def convert_utc_epoch_to_dt(epoch: int) -> datetime:
39+
def convert_utc_epoch_to_dt(epoch: float) -> datetime:
4040
"""Convert UTC epoch seconds to datetime."""
4141
return datetime.fromtimestamp(epoch, tz=timezone.utc)
4242

@@ -51,7 +51,7 @@ def get_utc_now_as_dt() -> datetime:
5151
return datetime.now(tz=timezone.utc)
5252

5353

54-
def get_utc_now_as_epoch() -> int:
54+
def get_utc_now_as_epoch() -> float:
5555
"""Get current UTC time as epoch seconds."""
5656
return convert_dt_to_utc_epoch(get_utc_now_as_dt())
5757

ultimatepython/advanced/meta_class.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class ModelMeta(type):
3333
"""
3434

3535
# Model table registry
36-
tables = {}
36+
tables: dict[str, "ModelTable"] = {}
3737

3838
def __new__(mcs, name, bases, attrs):
3939
"""Factory for modifying the defined class at runtime.

ultimatepython/classes/iterator_class.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class EmployeeIterator:
6868
def __init__(self, employee: Employee) -> None:
6969
"""Constructor logic."""
7070
self.employees_to_visit = [employee]
71-
self.employees_visited = set()
71+
self.employees_visited: set[str] = set()
7272

7373
def __iter__(self) -> "EmployeeIterator":
7474
"""Iterator is self by convention."""

ultimatepython/data_structures/deque.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def main() -> None:
2020
# Check out the source code for a list and a deque here:
2121
# https://github.com/python/cpython/blob/3.8/Objects/listobject.c
2222
# https://github.com/python/cpython/blob/3.8/Modules/_collectionsmodule.c
23-
dq = deque()
23+
dq: deque[int] = deque()
2424

2525
for i in range(1, 5):
2626
# Similar to adding a new node to the right of the linked list

ultimatepython/data_structures/heap.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ def main() -> None:
66
nums = [3, 1, 4, 1, 5]
77

88
# Creating a min-heap
9-
min_heap = []
9+
min_heap: list[int] = []
1010
for num in nums:
1111
heapq.heappush(min_heap, num)
1212
assert min_heap[0] == 1 # The root of the heap is the smallest element
@@ -20,7 +20,7 @@ def main() -> None:
2020
assert min_heap[0] == 1 # The root remains the smallest element
2121

2222
# Creating a max-heap
23-
max_heap = []
23+
max_heap: list[int] = []
2424
for num in nums:
2525
heapq.heappush(max_heap, -num) # Negate numbers for a max-heap
2626
assert -max_heap[0] == 5 # The root of the heap is the largest element

ultimatepython/data_structures/list.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ def main() -> None:
9494

9595
# Let's check if these lists are empty
9696
assert len(numbers) == 5
97-
empty_list = []
97+
empty_list: list[object] = []
9898
assert len(empty_list) == 0
9999
assert not empty_list
100100
assert len([None]) == 1

ultimatepython/data_structures/namedtuple.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@
55
"""
66

77
from collections import namedtuple
8+
from typing import Any
89

910

1011
def main() -> None:
1112
# Named Tuple Attributes:
1213
# - namedtuple: Callable from collections to define a named tuple
1314
# - Point: A named tuple type with fields "x" and "y"
14-
Point = namedtuple("Point", ["x", "y"])
15+
Point = namedtuple("Point", ["x", "y"]) # type: Any
1516

1617
# Named Tuple Fields:
1718
# - x and y: Fields of the named tuple Point representing coordinates
@@ -35,7 +36,10 @@ def main() -> None:
3536
# Attempt to change the "x" field of point1 (raises an error)
3637
access_immutable_error = False
3738
try:
38-
point1.x = 5
39+
# Direct assignment to a namedtuple field is not allowed (immutable).
40+
# Use setattr to demonstrate an attempted write at runtime while
41+
# keeping static analyzers from treating it as a real attribute write.
42+
setattr(point1, "x", 5) # will raise AttributeError on namedtuple
3943
except AttributeError:
4044
access_immutable_error = True
4145
assert access_immutable_error is True

ultimatepython/syntax/function.py

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
in an interesting way.
66
"""
77

8-
from typing import Callable
8+
from typing import Any, Callable
99

1010

11-
def add(x: object, y: object) -> object:
11+
def add(x: Any, y: Any) -> Any:
1212
"""Add two objects together to produce a new object.
1313
1414
Two differences between `add` and `main` are that:
@@ -35,14 +35,15 @@ def sum_until(fn: Callable[[int], int], n: int) -> int:
3535
return total
3636

3737

38-
def without_parameters() -> None:
39-
"""A function that does not accept parameters and does not return a value."""
40-
pass
38+
def without_parameters() -> object:
39+
"""A function that does not accept parameters and does not return a value.
4140
42-
43-
def sum(x: int, y: int) -> int:
44-
"""A function that accepts parameters and has type hints."""
45-
return x + y
41+
The return type is annotated as `object` to allow callers that assert
42+
on the returned value (e.g. `assert without_parameters() is None`) without
43+
triggering static checker complaints about a function annotated as
44+
returning None being used as a value.
45+
"""
46+
return None
4647

4748

4849
def main() -> None:
@@ -64,11 +65,11 @@ def main() -> None:
6465

6566
# We can see the `sum_until` docstring by accessing the `__doc__` magic
6667
# attribute! Remember this - everything in Python is an object
67-
assert "includes this docstring!" in sum_until.__doc__
68+
# `__doc__` may be None in some environments, coalesce to an empty string
69+
assert "includes this docstring!" in (sum_until.__doc__ or "")
6870

69-
# Call a few more functions to show that they are valid
71+
# Call a function without parameters
7072
assert without_parameters() is None
71-
assert sum(1, 2) == 3
7273

7374

7475
if __name__ == "__main__":

0 commit comments

Comments
 (0)