Skip to content

Commit e6c3416

Browse files
Sync hashtable with the updated tutorial (Python 3.15) (#923)
* Sync hashtable with the updated tutorial (Python 3.15) - BLANK and DELETED are built-in sentinel() objects instead of object() - HashTable.pairs in 05_separate_chaining unpacks the buckets in a set comprehension (PEP 798) - requirements.txt: pytest 9.1.1, pytest-unordered 0.8.0 on Python 3.15 - README: the code requires Python 3.15 or later - pyproject.toml: exclude hashtable from ruff, like the python315-* folders (ruff 0.14.1 targets py314: sentinel is F821 there, and unpacking in a comprehension is a syntax error) * hashtable: a deep copy of the pairs in the defensive-copying step A shallow copy of the list still shares mutable values, so a caller could change the table through it (reported by a reader in 2022). From the next step on, .pairs is a set, whose members must be hashable, so a shallow copy is enough there. --------- Co-authored-by: Bartosz Zaczyński <bartosz@realpython.com>
1 parent 2f3e5dd commit e6c3416

12 files changed

Lines changed: 20 additions & 19 deletions

File tree

‎hashtable/01_hashtable_prototype/02_insert_a_key_value_pair/hashtable.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# hashtable.py
22

3-
BLANK = object()
3+
BLANK = sentinel("BLANK")
44

55

66
class HashTable:

‎hashtable/01_hashtable_prototype/03_find_a_value_by_key/hashtable.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# hashtable.py
22

3-
BLANK = object()
3+
BLANK = sentinel("BLANK")
44

55

66
class HashTable:

‎hashtable/01_hashtable_prototype/04_delete_a_key_value_pair/hashtable.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# hashtable.py
22

3-
BLANK = object()
3+
BLANK = sentinel("BLANK")
44

55

66
class HashTable:

‎hashtable/01_hashtable_prototype/05_update_the_value_of_an_existing_pair/hashtable.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# hashtable.py
22

3-
BLANK = object()
3+
BLANK = sentinel("BLANK")
44

55

66
class HashTable:

‎hashtable/01_hashtable_prototype/07_use_defensive_copying/hashtable.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# hashtable.py
22

3+
import copy
34
from typing import Any, NamedTuple
45

56

@@ -46,7 +47,7 @@ def get(self, key, default=None):
4647

4748
@property
4849
def pairs(self):
49-
return [pair for pair in self._pairs if pair]
50+
return copy.deepcopy([pair for pair in self._pairs if pair])
5051

5152
def _index(self, key):
5253
return hash(key) % len(self)

‎hashtable/02_linear_probing/hashtable.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from typing import Any, NamedTuple
44

5-
DELETED = object()
5+
DELETED = sentinel("DELETED")
66

77

88
class Pair(NamedTuple):

‎hashtable/03_autoresize/hashtable.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from typing import Any, NamedTuple
44

5-
DELETED = object()
5+
DELETED = sentinel("DELETED")
66

77

88
class Pair(NamedTuple):

‎hashtable/04_load_factor/hashtable.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from typing import Any, NamedTuple
44

5-
DELETED = object()
5+
DELETED = sentinel("DELETED")
66

77

88
class Pair(NamedTuple):

‎hashtable/05_separate_chaining/hashtable.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ def get(self, key, default=None):
9191

9292
@property
9393
def pairs(self):
94-
return {pair for bucket in self._buckets for pair in bucket}
94+
return {*bucket for bucket in self._buckets}
9595

9696
@property
9797
def values(self):

‎hashtable/README.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ Code supplementing the [tutorial on the hash table](https://realpython.com/pytho
44

55
## Installation
66

7+
The code requires Python 3.15 or later. It uses the built-in `sentinel()` and unpacking in comprehensions, which are new in Python 3.15.
8+
79
To get started, create and activate a new virtual environment, and then install the required dependencies into it:
810

911
```shell
10-
$ python3 -m venv venv --prompt=hashtable
12+
$ python3.15 -m venv venv --prompt=hashtable
1113
$ source venv/bin/activate
1214
(hashtable) $ python -m pip install -r requirements.txt
1315
```

0 commit comments

Comments
 (0)