Skip to content

Sync hashtable with the updated tutorial (Python 3.15) - #923

Merged
bzaczynski merged 2 commits into
masterfrom
maintenance/python-hash-table-20261026
Oct 26, 2026
Merged

bzaczynski merged 2 commits into
masterfrom
maintenance/python-hash-table-20261026

Conversation

@realpython-bot

@realpython-bot realpython-bot commented Oct 26, 2026 •

Copy link
Copy Markdown
Collaborator

Brings hashtable/ in line with the Python 3.15 update of Build a Hash Table in Python With TDD and the new video course built from it.

What changed

  • BLANK (the prototype steps 02-05) and DELETED (linear probing, autoresize, load factor) are built-in sentinel() objects instead of object().
  • HashTable.pairs in 01_hashtable_prototype/07_use_defensive_copying returns copy.deepcopy(...) of the list: a shallow copy still shares mutable values, so a caller could change the table through it (a reader's comment on the tutorial). From folder 08 on, .pairs is a set, whose members must be hashable, so a shallow copy is enough there.
  • HashTable.pairs in 05_separate_chaining unpacks the buckets in a set comprehension, {*bucket for bucket in self._buckets} (PEP 798).
  • requirements.txt pins pytest 9.1.1 and pytest-unordered 0.8.0, resolved for Python 3.15.
  • The README says the code requires Python 3.15 or later, and creates the venv with python3.15.
  • pyproject.toml excludes hashtable from ruff, like python315-frozendict/, python315-lazy-imports, and python315-new-features. Ruff 0.14.1 targets py314, where sentinel is undefined (F821) and unpacking in a comprehension is a syntax error.

The folders keep their structure (match with _find()), as the tutorial describes them.

How it was verified

  • A fresh Python 3.15.1 venv from requirements.txt. Every folder's tests pass with the README's commands, with the same counts as before: the prototype steps 01-12 (PYTHONHASHSEED=128) give 3, 6, 14, 16, 17, 18, 20, 29, 34, 38, 42, and 49 passed, then 57, 58, 67, 62, and 62 passed for 02-06.
  • hash_distribution.py runs.
  • uvx ruff@0.14.1 check . and format --check . are clean.

The tutorial's own update is a separate, unpublished draft in the CMS that uses this code: python-hash-table-update (an [UPDATE] clone of the live post).

- 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)
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.
@bzaczynski
bzaczynski merged commit e6c3416 into master Oct 26, 2026
1 check passed
@bzaczynski
bzaczynski deleted the maintenance/python-hash-table-20261026 branch October 26, 2026 13:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants