Saltar a contenido

Week 2 - Control Flow, Functions, Errors, and the Call Model

2.1 Conceptual Core

  • Functions are first-class objects with attributes (__name__, __doc__, __annotations__, __defaults__, __closure__, __code__).
  • Default arguments are evaluated once, at definition time. The single most common Python footgun: def f(x, acc=[]): - acc is shared across calls. Use None sentinel + body-side default.
  • EAFP over LBYL. try: d[k] over if k in d: d[k]. The exception path is fast in CPython when not raised, and the LBYL form races under threads.

2.2 Mechanical Detail

  • Argument passing: positional, keyword, *args, **kwargs, positional-only (/, PEP 570), keyword-only (*). Know the order: def f(pos1, pos2, /, both, *, kw_only).
  • Closures and the nonlocal keyword. Late binding in closures ([lambda: i for i in range(3)] returns three lambdas all returning 2); fix with default-arg trick lambda i=i: i or with comprehension scoping.
  • The exception hierarchy: BaseExceptionException → everything user-catchable. KeyboardInterrupt and SystemExit are siblings of Exception, not subclasses - except Exception does not catch them, by design.
  • Exception chaining: raise NewError("...") from cause, implicit chaining via __context__. Exception groups (PEP 654, except*) for concurrent code.
  • try / except / else / finally: the else runs only if no exception; finally always runs, even on return.

2.3 Lab - "The Calculator and the Cancel"

  1. Build a tiny expression evaluator over + - * / using ast.parse + a custom NodeVisitor. Reject anything else. (Do not use eval.)
  2. Add a --repl mode. Make Ctrl-C interrupt the current expression but not exit. Make Ctrl-D exit cleanly.
  3. Wrap division; raise a custom EvalError chained from ZeroDivisionError via from.
  4. Add a --time-budget flag using signal.SIGALRM (POSIX) or a watchdog thread (cross-platform). Document the trade-off.

2.4 Idiomatic & Linter Drill

  • Enable ruff rule set TRY (try/except hygiene). Refactor a sample with broad except: and bare raise into PEP-compliant code.

2.5 Production Hardening Slice

  • Add pytest with pytest-cov. Write tests for the calculator. Aim 100% line and branch coverage for the AST evaluator. Commit a coverage badge target.

Comments