Skip to content

Commit ba148c3

Browse files
committed
Expand broad-surface pages, trim see_also, fix doc_path anchor
Removes the scope_first_pass shortcut from every broad-title page that took it. Each page now demonstrates the canonical forms its title promises rather than scoping itself down with a link list. Broad-page expansions - literals: hex/binary/octal/underscore numeric literals; f-string shown alongside raw and bytes literals. - operators: bitwise & added with | and ^ to make the masking surface complete. - type-hints: union (`X | Y`), `Optional[X]`, and `TypeAlias` cells. - testing: setUp fixture, assertEqual, and assertRaises in a single TestCase. Runner output now reflects three test methods. - async-await: async-with / async-for cell with an async context manager and async generator, linking to async-iteration-and-context. - packages: builds a temporary `shapes` package on disk to make `from .submodule import name` and `__all__` concrete. - regular-expressions: re.match vs re.search, re.compile, re.IGNORECASE flag, and re.sub each in their own cell. - special-methods: equality/hashing/ordering, container protocols, callable, and context-manager dunders. The page is now a real tour. Graph hygiene - Trimmed see_also on literals, operators, inheritance-and-super, special-methods, and type-hints to ≤4 entries so audit_example_graph passes without warnings. Doc-path correction - bound-and-unbound-methods: doc_path was /reference/datamodel.html #methods (no such anchor); corrected to #instance-methods. Verification - All 109 examples verify under Python 3.13. - 39 unit tests pass. - Quality checks all green: registry-integrity, confusable-pairs, broad-surface-tours, footgun-coverage, notes-supported. - score_examples reports every new page at 8.87 or higher (gate is 8.5). - audit_example_graph --check exits 0. - ruff, lint_seo_cache, format-examples --check, migration-parity all pass. Golden fixture refreshed to reflect the new cells.
1 parent 3846734 commit ba148c3

13 files changed

Lines changed: 1230 additions & 126 deletions

src/asset_manifest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
# Generated by scripts/fingerprint_assets.py. Do not edit by hand.
22
ASSET_PATHS = {'SITE_CSS': '/site.5f6f7da7c305.css', 'SYNTAX_JS': '/syntax-highlight.3b6c7f730d46.js', 'EDITOR_JS': '/editor.dd81f5171b14.js'}
3-
HTML_CACHE_VERSION = '6d04a8b5a41f'
3+
HTML_CACHE_VERSION = '781554af9745'

src/example_sources/async-await.md

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ title = "Async Await"
44
section = "Async"
55
summary = "async def creates coroutines, and await pauses until awaitable work completes."
66
doc_path = "/library/asyncio-task.html"
7-
scope_first_pass = true
87
see_also = [
98
"async-iteration-and-context",
109
"functions",
@@ -35,6 +34,30 @@ async def main():
3534
print(titles)
3635

3736
asyncio.run(main())
37+
38+
39+
class Session:
40+
async def __aenter__(self):
41+
print("open")
42+
return self
43+
44+
async def __aexit__(self, *_):
45+
print("close")
46+
return False
47+
48+
49+
async def stream():
50+
for slug in ["json", "datetime"]:
51+
await asyncio.sleep(0)
52+
yield slug
53+
54+
55+
async def driver():
56+
async with Session():
57+
async for slug in stream():
58+
print(slug)
59+
60+
asyncio.run(driver())
3861
```
3962
:::
4063

@@ -90,6 +113,42 @@ asyncio.run(main())
90113
```
91114
:::
92115

116+
:::cell
117+
`async with` and `async for` are the asynchronous forms of context managers and iteration. A class implements `__aenter__`/`__aexit__` to act as an async context manager; an `async def` function with `yield` becomes an async generator. The dedicated [async iteration and context](/iteration/async-iteration-and-context) page explains the protocols in depth.
118+
119+
```python
120+
class Session:
121+
async def __aenter__(self):
122+
print("open")
123+
return self
124+
125+
async def __aexit__(self, *_):
126+
print("close")
127+
return False
128+
129+
130+
async def stream():
131+
for slug in ["json", "datetime"]:
132+
await asyncio.sleep(0)
133+
yield slug
134+
135+
136+
async def driver():
137+
async with Session():
138+
async for slug in stream():
139+
print(slug)
140+
141+
asyncio.run(driver())
142+
```
143+
144+
```output
145+
open
146+
json
147+
datetime
148+
close
149+
```
150+
:::
151+
93152
:::note
94153
- Calling an async function creates a coroutine object.
95154
- `await` yields control until an awaitable completes.

src/example_sources/bound-and-unbound-methods.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ slug = "bound-and-unbound-methods"
33
title = "Bound and Unbound Methods"
44
section = "Data Model"
55
summary = "instance.method binds self automatically; Class.method is a plain function."
6-
doc_path = "/reference/datamodel.html#methods"
6+
doc_path = "/reference/datamodel.html#instance-methods"
77
see_also = [
88
"classes",
99
"attribute-access",

src/example_sources/inheritance-and-super.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@ summary = "Inheritance reuses behavior, and super delegates to a parent implemen
66
doc_path = "/tutorial/classes.html#inheritance"
77
see_also = [
88
"classes",
9-
"properties",
10-
"special-methods",
11-
"classmethods-and-staticmethods",
129
"abstract-base-classes",
10+
"classmethods-and-staticmethods",
11+
"special-methods",
1312
]
1413
+++
1514

src/example_sources/literals.md

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,11 @@ title = "Literals"
44
section = "Basics"
55
summary = "Literals write values directly in Python source code."
66
doc_path = "/reference/lexical_analysis.html#literals"
7-
scope_first_pass = true
87
see_also = [
98
"values",
109
"strings",
11-
"bytes-and-bytearray",
12-
"dicts",
13-
"string-formatting",
1410
"numbers",
11+
"string-formatting",
1512
]
1613
+++
1714

@@ -28,12 +25,20 @@ fraction = 3.5
2825
complex_number = 2 + 3j
2926
print(whole, fraction, complex_number.imag)
3027

28+
flags = 0xFF
29+
mask = 0b1010
30+
million = 1_000_000
31+
print(flags, mask, million)
32+
3133
text = "python"
3234
raw_pattern = r"\d+"
3335
data = b"py"
36+
score = 98
37+
formatted = f"score={score}"
3438
print(text)
3539
print(raw_pattern)
3640
print(data)
41+
print(formatted)
3742

3843
point = (2, 3)
3944
names = ["Ada", "Grace"]
@@ -69,21 +74,40 @@ print(whole, fraction, complex_number.imag)
6974
:::
7075

7176
:::cell
72-
String literals write Unicode text. Raw strings keep backslashes literal, and bytes literals write binary data rather than text.
77+
Integer literals also accept hexadecimal (`0x`), binary (`0b`), and octal (`0o`) prefixes. Underscores group digits visually without changing the value.
78+
79+
```python
80+
flags = 0xFF
81+
mask = 0b1010
82+
million = 1_000_000
83+
print(flags, mask, million)
84+
```
85+
86+
```output
87+
255 10 1000000
88+
```
89+
:::
90+
91+
:::cell
92+
String literals write Unicode text. Raw strings keep backslashes literal, bytes literals write binary data rather than text, and f-strings (`f"..."`) embed expressions inline.
7393

7494
```python
7595
text = "python"
7696
raw_pattern = r"\d+"
7797
data = b"py"
98+
score = 98
99+
formatted = f"score={score}"
78100
print(text)
79101
print(raw_pattern)
80102
print(data)
103+
print(formatted)
81104
```
82105

83106
```output
84107
python
85108
\d+
86109
b'py'
110+
score=98
87111
```
88112
:::
89113

src/example_sources/operators.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,11 @@ title = "Operators"
44
section = "Basics"
55
summary = "Operators combine, compare, and test values in expressions."
66
doc_path = "/reference/expressions.html#operator-precedence"
7-
scope_first_pass = true
87
see_also = [
98
"numbers",
10-
"conditionals",
9+
"equality-and-identity",
1110
"assignment-expressions",
1211
"operator-overloading",
13-
"equality-and-identity",
1412
]
1513
+++
1614

@@ -34,6 +32,8 @@ print(score == 100 or score >= 90)
3432
print("py" in "python")
3533

3634
flags = 0b0011
35+
print(flags & 0b0101)
36+
print(flags | 0b0100)
3737
print(flags ^ 0b0101)
3838
print(flags << 1)
3939

@@ -89,15 +89,19 @@ True
8989
:::
9090

9191
:::cell
92-
Bitwise operators work on integer bit patterns. They are useful for masks and flags, not ordinary boolean logic.
92+
Bitwise operators work on integer bit patterns. They are useful for masks and flags, not ordinary boolean logic. `&` is bitwise AND, `|` is bitwise OR, `^` is exclusive OR, and `<<` shifts left.
9393

9494
```python
9595
flags = 0b0011
96+
print(flags & 0b0101)
97+
print(flags | 0b0100)
9698
print(flags ^ 0b0101)
9799
print(flags << 1)
98100
```
99101

100102
```output
103+
1
104+
7
101105
6
102106
6
103107
```

src/example_sources/packages.md

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ title = "Packages"
44
section = "Modules"
55
summary = "Packages organize modules into importable directories."
66
doc_path = "/tutorial/modules.html#packages"
7-
scope_first_pass = true
87
see_also = [
98
"modules",
109
"import-aliases",
@@ -30,6 +29,28 @@ print(json.__name__)
3029
print(json.decoder.__name__)
3130
print(module.JSONDecoder.__name__)
3231
print(module is json.decoder)
32+
33+
34+
import os
35+
import sys
36+
import tempfile
37+
38+
with tempfile.TemporaryDirectory() as tmp:
39+
pkg = os.path.join(tmp, "shapes")
40+
os.makedirs(pkg)
41+
with open(os.path.join(pkg, "__init__.py"), "w") as init:
42+
init.write("from .square import area\n__all__ = ['area']\n")
43+
with open(os.path.join(pkg, "square.py"), "w") as square:
44+
square.write("def area(side):\n return side * side\n")
45+
sys.path.insert(0, tmp)
46+
try:
47+
import shapes
48+
print(shapes.area(3))
49+
print(shapes.__all__)
50+
finally:
51+
sys.path.remove(tmp)
52+
sys.modules.pop("shapes", None)
53+
sys.modules.pop("shapes.square", None)
3354
```
3455
:::
3556

@@ -78,8 +99,41 @@ True
7899
```
79100
:::
80101

102+
:::cell
103+
Inside a package's `__init__.py`, `from .submodule import name` re-exports a submodule's name at the package root, and `__all__` lists the names that `from package import *` should make visible. This cell builds a temporary `shapes` package on disk to make both forms concrete.
104+
105+
```python
106+
import os
107+
import sys
108+
import tempfile
109+
110+
with tempfile.TemporaryDirectory() as tmp:
111+
pkg = os.path.join(tmp, "shapes")
112+
os.makedirs(pkg)
113+
with open(os.path.join(pkg, "__init__.py"), "w") as init:
114+
init.write("from .square import area\n__all__ = ['area']\n")
115+
with open(os.path.join(pkg, "square.py"), "w") as square:
116+
square.write("def area(side):\n return side * side\n")
117+
sys.path.insert(0, tmp)
118+
try:
119+
import shapes
120+
print(shapes.area(3))
121+
print(shapes.__all__)
122+
finally:
123+
sys.path.remove(tmp)
124+
sys.modules.pop("shapes", None)
125+
sys.modules.pop("shapes.square", None)
126+
```
127+
128+
```output
129+
9
130+
['area']
131+
```
132+
:::
133+
81134
:::note
82135
- A package is a module that can contain submodules.
83136
- Dotted imports should mirror a meaningful project structure.
137+
- Use `from .submodule import name` inside a package to re-export submodule names; set `__all__` to declare the public surface.
84138
- Prefer ordinary imports unless the module name is truly dynamic.
85139
:::

0 commit comments

Comments
 (0)