Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
119 commits
Select commit Hold shift + click to select a range
d6bbceb
docs: design complete exercise solutions
wolph Jul 28, 2026
9af4bf8
docs: plan complete exercise solutions
wolph Jul 28, 2026
4871931
build: ignore local worktrees
wolph Jul 28, 2026
4c8d505
build: add locked Python exercise environment
wolph Jul 28, 2026
a32452c
build: pin spaCy for Python 3.14
wolph Jul 28, 2026
53a7315
build: configure canonical quality checks
wolph Jul 28, 2026
44c4842
build: fix Pyright alternative exclusions
wolph Jul 28, 2026
855ad93
build: align canonical tool scope
wolph Jul 28, 2026
22d53a6
build: add Lefthook quality gates
wolph Jul 28, 2026
8f29277
build: format after Ruff fixes
wolph Jul 28, 2026
5a28277
ci: test canonical solutions and quality gates
wolph Jul 28, 2026
4d4adf4
ci: harden pinned toolchain
wolph Jul 28, 2026
ca17102
docs: document exercise development workflow
wolph Jul 28, 2026
e5fc2e0
docs: clarify exercise contribution contract
wolph Jul 28, 2026
3a11cb3
docs: distinguish canonical quality commands
wolph Jul 28, 2026
b95d525
docs: clarify alternative validation
wolph Jul 28, 2026
c315e02
feat(ch06): add deterministic execution tracking
wolph Jul 28, 2026
3a20a39
feat(ch02): extend safe completion
wolph Jul 28, 2026
7670e0c
feat(ch04): implement sorted mapping
wolph Jul 28, 2026
f44a057
docs(ch06): quote tracking exercise exactly
wolph Jul 28, 2026
1415821
fix(ch02): delegate standard completion safely
wolph Jul 28, 2026
3424ba2
docs(ch02): quote completion exercise exactly
wolph Jul 28, 2026
a6d10a2
fix(ch06): preserve target exception during timing
wolph Jul 28, 2026
3985322
fix(ch02): prevent completion side effects
wolph Jul 28, 2026
2c30f33
refactor(ch06): extract timing decorator helper
wolph Jul 28, 2026
a606b83
fix(ch02): harden safe completion baseline
wolph Jul 28, 2026
3ad358c
fix(ch04): harden sorted mapping semantics
wolph Jul 28, 2026
5233b61
fix(ch02): reject hostile instance metadata
wolph Jul 28, 2026
08c2400
fix(ch02): narrow safe attribute traversal
wolph Jul 28, 2026
dcd2e0e
fix(ch02): skip unrenderable literal keys
wolph Jul 28, 2026
433fe5e
fix(ch02): skip excessively deep literal keys
wolph Jul 28, 2026
e3a1440
feat(ch02): color completion candidates
wolph Jul 28, 2026
1d66001
test(ch02): cover sequence state-zero color
wolph Jul 28, 2026
ff7d3cb
fix(ch02): keep completion replacements plain
wolph Jul 28, 2026
8420ed2
fix(ch02): restore prompt after color display
wolph Jul 28, 2026
1d5f28f
fix(ch02): restore GNU completion prompt
wolph Jul 28, 2026
e92e183
feat(ch02): add Jedi source completion
wolph Jul 28, 2026
573ec00
fix(ch02): preserve terminal completion lines
wolph Jul 28, 2026
91dc88b
fix(ch02): align source lines with Jedi
wolph Jul 28, 2026
32a93f7
feat(ch02): add editable greeting widget
wolph Jul 28, 2026
11d016d
fix(ch02): handle non-string widget changes
wolph Jul 28, 2026
663bfc1
fix(ch02): close greeting widget resources
wolph Jul 28, 2026
3617fe4
fix(ch02): make widget cleanup retryable
wolph Jul 28, 2026
27d44fd
fix(ch02): bound literal nesting deterministically
wolph Jul 28, 2026
83b50ba
feat(ch02): search IPython session history
wolph Jul 28, 2026
2ef4ad2
fix(ch02): harden IPython history CLI
wolph Jul 28, 2026
a6589fd
feat(ch04): add logarithmic sorted list
wolph Jul 28, 2026
56b5872
docs(ch04): match sorted list question
wolph Jul 28, 2026
180a6a8
fix(ch04): preserve sorted list key inference
wolph Jul 28, 2026
1162885
feat(ch04): isolate Borg state by subclass
wolph Jul 28, 2026
ae6eb45
test(ch04): cover keyword-only Borg initialization
wolph Jul 28, 2026
fae63ad
docs(ch04): restore Borg exercise wording
wolph Jul 28, 2026
028ca47
fix(ch04): make Borg allocation cooperative
wolph Jul 28, 2026
9d2842c
fix(ch04): forward cooperative allocation arguments
wolph Jul 28, 2026
3fa85ab
feat(ch05): complete functional quicksort
wolph Jul 28, 2026
cc2c92b
fix(ch05): enforce quicksort ordering types
wolph Jul 28, 2026
364d223
fix(ch05): type reflected quicksort comparisons
wolph Jul 28, 2026
185f73e
feat(ch05): group non-consecutive values
wolph Jul 28, 2026
c21159f
test(ch05): cover groupby iterator and key semantics
wolph Jul 28, 2026
002630d
feat(ch05): return reusable grouped lists
wolph Jul 28, 2026
d405ac7
feat(ch06): aggregate tracked call statistics
wolph Jul 28, 2026
1663a0c
test(ch06): cover bare track invocation
wolph Jul 28, 2026
0afbd1d
fix(ch06): label general callables safely
wolph Jul 28, 2026
2469e36
fix(ch06): validate wrapped callable metadata
wolph Jul 28, 2026
c8b5430
fix(ch06): preserve type parameter metadata
wolph Jul 28, 2026
866df5f
fix(ch06): retain safe custom metadata
wolph Jul 28, 2026
c66d006
fix(ch06): snapshot callable metadata safely
wolph Jul 28, 2026
4979251
fix(ch06): preserve callable names safely
wolph Jul 28, 2026
167d2bd
feat(ch06): memoize unhashable arguments
wolph Jul 28, 2026
82a1bf3
fix(ch06): preserve memoization exercise contract
wolph Jul 28, 2026
56728da
fix(ch06): make exercise question strict RST
wolph Jul 28, 2026
fc9d944
fix(ch06): isolate callable memoization keys
wolph Jul 28, 2026
d679055
feat(ch06): isolate memoization caches
wolph Jul 28, 2026
ee792b1
test(ch05): make AST assertions version portable
wolph Jul 28, 2026
b142b78
fix(ch06): preserve annotations across Python versions
wolph Jul 28, 2026
62ee96e
fix(ch06): preserve annotate attribute presence
wolph Jul 28, 2026
954907c
feat(ch06): add recalculable cached property
wolph Jul 28, 2026
4c3d8e1
feat: complete metaclass attribute exercise
wolph Jul 28, 2026
ad1569d
feat: add complex dictionary typing exercise
wolph Jul 28, 2026
7af2068
test(ch09): assert required typed dictionary keys
wolph Jul 28, 2026
d5c3c92
fix(ch08): make attribute validation cooperative
wolph Jul 28, 2026
d1d2323
fix(ch06): preserve cached property metadata safely
wolph Jul 28, 2026
d670395
fix(ch06): define cached property metadata contract
wolph Jul 28, 2026
8768c31
fix(ch06): reject hostile annotation mappings
wolph Jul 28, 2026
c2c74c7
feat: complete metaclass inheritance exercise
wolph Jul 28, 2026
93cbaff
feat: add nested type exercise
wolph Jul 28, 2026
ef6099e
feat(ch06): dispatch across selected arguments
wolph Jul 28, 2026
bab7df3
fix(ch06): harden multi-argument dispatch
wolph Jul 28, 2026
dbc9690
fix(ch08): make inheritance validation cooperative
wolph Jul 28, 2026
a7c616c
fix(ch08): canonicalize required base metadata
wolph Jul 28, 2026
d5f9eb8
feat: complete metaclass wrapping exercise
wolph Jul 28, 2026
95f7736
feat: add recursive type exercise
wolph Jul 28, 2026
8d5916d
feat(ch06): enforce typed numeric constraints
wolph Jul 28, 2026
181b8a5
fix(ch06): preserve validation exercise fidelity
wolph Jul 28, 2026
905df79
fix(ch08): make wrapping exercise portable
wolph Jul 28, 2026
f4d3f44
fix(ch09): traverse recursive trees iteratively
wolph Jul 28, 2026
26f4990
fix(ch08): preserve metaclass preparation lifecycle
wolph Jul 28, 2026
8260c9e
fix(ch06): harden typed numeric constraints
wolph Jul 28, 2026
a05972c
fix(ch06): verify forward-reference owners
wolph Jul 28, 2026
669e49a
fix(ch06): resolve annotations without runtime inference
wolph Jul 28, 2026
7d0e8aa
feat(ch07): support negative generator slices
wolph Jul 28, 2026
1ea58d0
feat: add object doctest runner
wolph Jul 28, 2026
c2dd8f9
fix(ch07): validate slice indices eagerly
wolph Jul 28, 2026
7844a25
fix(ch10): isolate doctest runner state
wolph Jul 28, 2026
5716868
feat(ch07): complete generator exercise coverage
wolph Jul 28, 2026
3fb834d
feat: complete debugging and performance exercises
wolph Jul 28, 2026
dcf0991
feat: complete asyncio exercises
wolph Jul 28, 2026
d3e5fd2
feat: complete chapter 14 IPC exercises
wolph Jul 28, 2026
18855a0
build: complete scientific notebook dependencies
wolph Jul 28, 2026
1d0034d
feat: complete chapter 14 worker exercises
wolph Jul 28, 2026
848614d
feat: complete scientific and NLP exercises
wolph Jul 28, 2026
84f2f97
feat: complete native interoperability exercises
wolph Jul 28, 2026
d70e82a
feat: complete packaging exercises
wolph Jul 28, 2026
f7636c2
test(ch09): normalize recursive type hints across versions
wolph Jul 28, 2026
bdacc35
feat(ch10): complete testing and logging solutions
wolph Jul 28, 2026
e7434df
build(deps): declare xarray directly
wolph Jul 28, 2026
d69bcd1
fix(ch10): align pytest plugin collection
wolph Jul 28, 2026
d23afaf
fix(ch10): relocate tox work directory
wolph Jul 28, 2026
1211a7d
fix(ch10): prevent smoke test environment sync
wolph Jul 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: CI

'on':
push:
branches:
- master
pull_request:

permissions:
contents: read

concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
quality:
runs-on: ubuntu-24.04
timeout-minutes: 20
steps:
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
persist-credentials: false
- name: Set up uv
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9
with:
version: "0.11.32"
enable-cache: true
python-version: "3.10"
- name: Install dependencies
run: uv sync --locked --all-groups
- name: Check formatting
run: uv run ruff format --check .
- name: Lint
run: uv run ruff check .
- name: Run Pyrefly
run: uv run pyrefly check
- name: Run mypy
run: uv run mypy .
- name: Run Pyright
run: uv run pyright

tests:
runs-on: ubuntu-24.04
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
python-version:
- "3.10"
- "3.14"
steps:
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
persist-credentials: false
- name: Set up uv
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9
with:
version: "0.11.32"
enable-cache: true
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: uv sync --locked --all-groups
- name: Run tests
run: uv run pytest
14 changes: 14 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.worktrees/
.DS_Store
.coverage
.mypy_cache/
.pytest_cache/
.pyrefly_cache/
.ruff_cache/
.tox/
.venv/
__pycache__/
build/
dist/
*.egg-info/
*.py[cod]
1 change: 1 addition & 0 deletions .python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.10
18 changes: 13 additions & 5 deletions CH_02_interactive_python/README.rst
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
Chapter 2 - interactive python
=======================================================================================================================

1. The `rlcompleter` enhancement we created currently only handles dictionaries. Try and extend the code so it supports lists, strings, and tuples as well.
2. Add colors to the completer (hint: use `colorama` for the coloring).
3. Instead of manually completing using our own object introspection, try and use the `jedi` library for autocompletion, which does static code analysis.
4. Try to create a `Hello` `<ipywidget>` so the name of the person can be edited through a notebook without code changes.
5. Try and create a script that will look for a given pattern through all of your previous ipython sessions.
1. `Exercise 1 <exercise_01/README.rst>`_: The ``rlcompleter`` enhancement we
created currently only handles dictionaries. Try and extend the code so it
supports lists, strings, and tuples as well.
2. `Exercise 2 <exercise_02/README.rst>`_: Add colors to the completer (hint:
use ``colorama`` for the coloring).
3. `Exercise 3 <exercise_03/README.rst>`_: Instead of manually completing using
our own object introspection, try and use the ``jedi`` library for
autocompletion, which does static code analysis.
4. `Exercise 4 <exercise_04/README.rst>`_: Try to create a ``Hello``
``<ipywidget>`` so the name of the person can be edited through a notebook
without code changes.
5. `Exercise 5 <exercise_05/README.rst>`_: Try and create a script that will
look for a given pattern through all of your previous ipython sessions.
48 changes: 48 additions & 0 deletions CH_02_interactive_python/exercise_01/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
Exercise 1 - safe finite-sequence completion
============================================

1. The `rlcompleter` enhancement we created currently only handles dictionaries. Try and extend the code so it supports lists, strings, and tuples as well.

Solution
--------

``Completer`` extends the standard-library ``rlcompleter.Completer`` with safe
name and item completion. Exact built-in dictionaries produce recursively safe
literal keys using ``repr``; non-finite numeric keys, keys nested beyond 64
tuple levels, and keys that exceed interpreter rendering limits are rejected.
Exact lists, tuples, and strings produce finite integer indices. Prefixes
filter candidates, and each request inspects at most 25 items. An explicitly
supplied namespace is shallow-copied once, and both completion paths use that
snapshot. Name completion includes Python hard keywords and built-ins without
inspecting namespace values.

Expressions are parsed with ``ast``. Only names, exact ``SimpleNamespace``
attributes containing safe containers, and exact built-in container subscripts
whose keys are safe literals are resolved. Calls and all other expression
forms are rejected, so completion never evaluates arbitrary Python code.
Importing the module does not register a ``readline`` completer or mutate
terminal state.

Dependencies
------------

The solution uses only the Python standard library. The repository's ``dev``
dependency group supplies pytest and the static-analysis tools.

Run the demonstration:

.. code-block:: console

uv run python CH_02_interactive_python/exercise_01/solution_00.py

Run the focused tests:

.. code-block:: console

uv run pytest CH_02_interactive_python/exercise_01/test_solution_00.py

Reference
---------

The chapter's original dictionary-only implementation is
`T_02_modifying_autocompletion.py <https://github.com/mastering-python/code_2/blob/a012f6ce3f5bf11f5bf380d1c4e7f743355adb89/CH_02_interactive_python/T_02_modifying_autocompletion.py>`_.
1 change: 1 addition & 0 deletions CH_02_interactive_python/exercise_01/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Exercise 1: safe item completion."""
Loading
Loading