What the Fuck Python

Purpose of the notebook & overall reaction

  • Many commenters read it as “Python slander,” while others stress it is explicitly framed as a fun tour of internals and gotchas, not a bug list or anti-Python rant.
  • Several people say most examples are contrived, never seen in production, and mainly useful to learn interpreter behavior.
  • Others argue that even “edge-case” inconsistencies matter because beginners and casual users hit them and waste time debugging.

Identity vs equality, id() and is

  • Long subthread on id() and is:
    • id() is a defined builtin whose value is implementation-dependent; it exposes object identity and is suited for identity (not equality) checks.
    • is compares identities; using it for value equality (e.g., strings or ints) is called out as a basic mistake.
    • Many note that string/int interning and constant folding make id() and is behavior look surprising but this is an optimization detail you shouldn’t rely on.
  • Some say the real WTF is that identity has a short infix operator at all; a same_object(a, b)-style function would have been clearer.

Truthiness and bool("False")

  • Heated debate over bool("False") == True:
    • Defenders: bool() is a truthiness check, not a parsing cast; empty values are False, everything else True. This keeps if a: consistent for all types and avoids YAML-style “Norway” issues.
    • Critics: int("35") and float("3.5") do parse strings; naming bool() like a type but giving it different semantics is misleading. They’d prefer either parsing "False" → False or raising on strings.
    • Some argue the real bug is naming and pedagogy around “casting”; others emphasize there is no implicit casting in Python, only constructors with chosen semantics.

Chained comparisons and in

  • Example False == False in [False] surprising many:
    • Python desugars a == b in c to (a == b) and (b in c), and treats in, is, etc., as relational operators participating in chaining.
    • Several find this clever but counter-intuitive, especially when operators aren’t transitive or homogeneous.

Mutability, +=, and reference semantics

  • x += y sometimes mutates in place (lists) and sometimes creates a new object (tuples), leading to silent divergence like shared-list aliasing.
  • Even more confusing: a[0] += [3,4] on a tuple of lists both raises and partially mutates underlying state.
  • Discussion on Python’s model: all values have reference semantics and are passed by assignment; mutability and in-place methods drive the weirdness, not “pass by reference.”

Specs, docs, and design goals

  • Disagreement over whether Python “has a spec”: some insist CPython + tests define behavior; others want a more formal, implementation-independent spec.
  • Mixed views on documentation quality: some say it remains excellent and more comprehensive than early versions; others find it too wordy yet missing crucial precision.
  • One camp leans on “idiomatic use + PEP 8/20” as the answer (“who writes Python this way?”); another counters that languages should be consistent and spec-driven to protect learners and multi-language programmers.

Notebooks and tooling

  • Side thread criticizing Jupyter/Colab as “not real programming environments” versus defenders saying they are fine for exploration, data science, and teaching, though misused in production.
  • Broader point: most real-world Python “wtfs” are in ecosystem/tooling (envs, dependencies) rather than core language semantics, whereas JS has more everyday builtin footguns.