Skip to content

Commit 92e2188

Browse files
heikkitoivonencodex
andcommitted
Docs: Fix stdlib introspection and io
Co-Authored-By: Codex <codex@openai.com>
1 parent 7e01881 commit 92e2188

7 files changed

Lines changed: 60 additions & 69 deletions

File tree

docs/stdlib/idlelib.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ The `idlelib` module provides the Python IDLE editor library, used to build the
66

77
| Operation | Time | Space | Notes |
88
|-----------|------|-------|-------|
9-
| Editor initialization | O(1) | O(n) | n = UI components |
10-
| Syntax highlighting | O(n) | O(n) | n = line length |
9+
| Editor initialization | Varies | Varies | Depends on Tk setup and platform |
10+
| Syntax highlighting | Varies | Varies | Depends on highlighter and text size processed |
1111

1212
## IDLE Components
1313

docs/stdlib/imaplib.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ The `imaplib` module provides IMAP4 client functionality for accessing email on
66

77
| Operation | Time | Space | Notes |
88
|-----------|------|-------|-------|
9-
| `login()` | O(1) | O(1) | Authentication |
10-
| List mailboxes | O(n) | O(n) | n = mailboxes |
11-
| Fetch messages | O(n) | O(n) | n = messages |
9+
| `login()` | Varies | Varies | Network round‑trip, server auth |
10+
| List mailboxes | Varies | Varies | Depends on server and response size |
11+
| Fetch messages | Varies | Varies | Depends on server, message sizes, and network |
1212

1313
## Accessing IMAP Mailboxes
1414

docs/stdlib/importlib.md

Lines changed: 32 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@ The `importlib` module provides tools for importing modules and working with Pyt
66

77
| Operation | Time | Space | Notes |
88
|-----------|------|-------|-------|
9-
| `import_module(name)` | O(n) | O(n) | n = import depth |
10-
| `find_loader(name)` | O(1) | O(1) | Check sys.modules |
11-
| `reload(module)` | O(n) | O(n) | n = module size |
12-
| `import_module(package)` | O(n+m) | O(n+m) | n = submodules |
13-
| `resources.files()` | O(1) | O(1) | Get resource path |
9+
| `import_module(name)` | Varies | Varies | Depends on cache, meta path, and I/O |
10+
| `importlib.util.find_spec(name)` | Varies | Varies | Depends on finders and file system |
11+
| `reload(module)` | Varies | Varies | Re-executes module code |
12+
| `resources.files(package)` | Varies | Varies | May import package or access loaders |
1413

1514
## Common Operations
1615

@@ -19,17 +18,17 @@ The `importlib` module provides tools for importing modules and working with Pyt
1918
```python
2019
import importlib
2120

22-
# O(n) where n = import depth/module size
21+
# Cost depends on loaders, cache, and filesystem
2322
# Prefer this over __import__()
2423
module = importlib.import_module('os.path')
2524

2625
# Equivalent to: import os.path
27-
import_module('json') # O(n)
28-
import_module('collections.abc') # O(n)
26+
import_module('json')
27+
import_module('collections.abc')
2928

30-
# From cached sys.modules if already imported - O(1)
29+
# From cached sys.modules if already imported
3130
module = importlib.import_module('json')
32-
module = importlib.import_module('json') # Second call is O(1)
31+
module = importlib.import_module('json') # Second call is cached
3332
```
3433

3534
### Reloading Modules
@@ -38,7 +37,6 @@ module = importlib.import_module('json') # Second call is O(1)
3837
import importlib
3938
import mymodule
4039

41-
# O(n) where n = module size
4240
# Re-executes module code
4341
importlib.reload(mymodule)
4442

@@ -52,33 +50,31 @@ importlib.reload(mymodule)
5250
import importlib.util
5351
import sys
5452

55-
# O(1) - check if module is cached
5653
spec = importlib.util.find_spec('json')
5754
if spec is not None:
58-
print(f"Found: {spec.origin}") # O(1)
55+
print(f"Found: {spec.origin}")
5956

60-
# Get loader - O(1) if cached, O(n) if needs import
57+
# Get loader
6158
loader = spec.loader
6259

63-
# Manual import from spec - O(n)
60+
# Manual import from spec (executes module code)
6461
module = importlib.util.module_from_spec(spec)
6562
sys.modules[spec.name] = module
66-
spec.loader.exec_module(module) # O(n)
63+
spec.loader.exec_module(module)
6764
```
6865

6966
### Working with Submodules
7067

7168
```python
7269
import importlib
7370

74-
# O(n) where n = total submodules
7571
package = importlib.import_module('email')
7672

77-
# Get submodule - O(m) where m = submodule size
73+
# Get submodule
7874
mime = importlib.import_module('email.mime')
7975
text = importlib.import_module('email.mime.text')
8076

81-
# Check if submodule exists - O(1) after first import
77+
# Check if submodule exists after first import
8278
import email.mime.text
8379
print('email.mime.text' in sys.modules) # O(1)
8480
```
@@ -92,12 +88,12 @@ import importlib
9288
import sys
9389

9490
def try_import(module_name, default=None):
95-
"""Safely import module - O(n) or O(1)"""
91+
"""Safely import module; cost depends on cache and loaders."""
9692
try:
97-
if module_name in sys.modules: # O(1) check
93+
if module_name in sys.modules: # Cached
9894
return sys.modules[module_name]
9995

100-
return importlib.import_module(module_name) # O(n)
96+
return importlib.import_module(module_name)
10197
except ImportError:
10298
return default
10399

@@ -122,7 +118,7 @@ class PluginManager:
122118
self.plugins = {}
123119

124120
def load_plugin(self, name, module_path):
125-
"""Load plugin module - O(n) where n = module size"""
121+
"""Load plugin module; cost depends on loaders and module code."""
126122
try:
127123
module = importlib.import_module(module_path)
128124

@@ -139,7 +135,6 @@ class PluginManager:
139135
"""Get cached plugin - O(1)"""
140136
return self.plugins.get(name)
141137

142-
# Usage - O(n) per plugin
143138
manager = PluginManager()
144139
manager.load_plugin('plugin1', 'plugins.plugin1')
145140
manager.load_plugin('plugin2', 'plugins.plugin2')
@@ -155,11 +150,11 @@ import importlib
155150

156151
module = importlib.import_module('collections')
157152

158-
# O(1) - hasattr checks __dict__
153+
# hasattr checks __dict__
159154
if hasattr(module, 'deque'):
160155
Deque = getattr(module, 'deque')
161156

162-
# O(n) - iterate all attributes where n = module size
157+
# iterate all attributes
163158
for attr_name in dir(module): # O(n)
164159
attr = getattr(module, attr_name)
165160
if callable(attr):
@@ -172,7 +167,7 @@ for attr_name in dir(module): # O(n)
172167
import importlib.util
173168

174169
def module_available(name):
175-
"""Check if module can be imported - O(1) cache or O(n) search"""
170+
"""Check if module can be imported; cost depends on finders."""
176171
spec = importlib.util.find_spec(name)
177172
return spec is not None
178173

@@ -181,8 +176,8 @@ available_mods = {}
181176

182177
def is_available(name):
183178
if name not in available_mods:
184-
available_mods[name] = module_available(name) # O(n) first time
185-
return available_mods[name] # O(1) after cached
179+
available_mods[name] = module_available(name)
180+
return available_mods[name] # Cached
186181
```
187182

188183
## Performance Tips
@@ -192,12 +187,12 @@ def is_available(name):
192187
```python
193188
import importlib
194189

195-
# Bad: O(n) import each time
190+
# Bad: import each time
196191
def process():
197192
json = importlib.import_module('json')
198193
return json.loads(data)
199194

200-
# Good: O(1) after first import
195+
# Good: reuse cached module after first import
201196
json = importlib.import_module('json')
202197

203198
def process():
@@ -209,7 +204,7 @@ def process():
209204
```python
210205
import importlib.util
211206

212-
# Efficient existence check - O(1) if cached or path-based
207+
# Efficient existence check when cached or path-based
213208
if importlib.util.find_spec('numpy'):
214209
import numpy
215210
# Use numpy
@@ -225,22 +220,19 @@ def ensure_modules(module_list):
225220
"""Import multiple modules efficiently"""
226221
loaded = {}
227222
for name in module_list:
228-
if name not in sys.modules: # O(1) check
229-
loaded[name] = importlib.import_module(name) # O(n)
223+
if name not in sys.modules: # Cached check
224+
loaded[name] = importlib.import_module(name)
230225
else:
231-
loaded[name] = sys.modules[name] # O(1)
226+
loaded[name] = sys.modules[name]
232227
return loaded
233228

234-
# O(k*n) where k = module count, n = avg module size
229+
# Cost depends on module count, loaders, and module code
235230
modules = ensure_modules(['json', 'os', 'sys'])
236231
```
237232

238233
## Version Notes
239234

240-
- **Python 2.7**: Limited support
241-
- **Python 3.1+**: importlib added
242-
- **Python 3.4+**: importlib.util for detailed control
243-
- **Python 3.7+**: Simplified import machinery
235+
- **Python 3.x**: `importlib` and `importlib.util` are available
244236

245237
## Related Documentation
246238

docs/stdlib/inspect.md

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ The `inspect` module provides utilities for inspecting live objects, including m
77
| Operation | Time | Space | Notes |
88
|-----------|------|-------|-------|
99
| `getmembers(obj)` | O(m) | O(m) | Get all members of object |
10-
| `getdoc(obj)` | O(1) | O(n) | Get docstring |
10+
| `getdoc(obj)` | O(n) | O(n) | n = docstring length |
1111
| `signature(func)` | O(p) | O(p) | Get function signature |
12-
| `getsource(obj)` | O(n) | O(n) | Get source code |
13-
| `getsourcelines(obj)` | O(n) | O(n) | Get source + line numbers |
14-
| `getfile(obj)` | O(1) | O(1) | Get file path |
12+
| `getsource(obj)` | Varies | Varies | File I/O + inspect cache |
13+
| `getsourcelines(obj)` | Varies | Varies | File I/O + inspect cache |
14+
| `getfile(obj)` | Varies | Varies | May inspect metadata and loaders |
1515
| `isfunction(obj)` | O(1) | O(1) | Check if function |
1616
| `ismethod(obj)` | O(1) | O(1) | Check if method |
1717
| `isclass(obj)` | O(1) | O(1) | Check if class |
@@ -120,14 +120,14 @@ Where n = source code size.
120120
```python
121121
import inspect
122122

123-
# Get source: O(n) to read file
124-
source = inspect.getsource(func) # O(n)
123+
# Get source: file I/O and caching behavior vary
124+
source = inspect.getsource(func)
125125

126-
# Get lines with line numbers: O(n)
127-
source_lines, start_line = inspect.getsourcelines(func) # O(n)
126+
# Get lines with line numbers
127+
source_lines, start_line = inspect.getsourcelines(func)
128128

129129
# Source is read from disk and cached
130-
# Subsequent calls may be O(1) from cache
130+
# Subsequent calls may be faster if cached
131131
```
132132

133133
#### Space Complexity: O(n)
@@ -304,9 +304,7 @@ frame = sys._getframe(0) # O(1) vs O(d)
304304

305305
## Version Notes
306306

307-
- **Python 3.3+**: `signature()` added
308-
- **Python 3.5+**: Improvements to signature handling
309-
- **Python 3.10+**: Parameter behavior changes
307+
- **Python 3.x**: `inspect` utilities are available
310308

311309
## Related Documentation
312310

docs/stdlib/io.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ stream.seek(0)
6969
for line in stream: # O(n) iteration
7070
print(f"Line: {line.strip()}")
7171

72-
# Clear stream - O(1)
72+
# Close stream - O(1)
7373
stream.close()
7474
```
7575

@@ -243,16 +243,16 @@ from io import BytesIO
243243

244244
stream = BytesIO(b"x" * 1000)
245245

246+
def process(data):
247+
print(f"Processing {len(data)} bytes")
248+
246249
# Read in chunks - O(n) total, O(1) per chunk
247250
chunk_size = 100
248251
while True:
249252
chunk = stream.read(chunk_size) # O(k) per chunk
250253
if not chunk:
251254
break
252255
process(chunk) # Process chunk
253-
254-
def process(data):
255-
print(f"Processing {len(data)} bytes")
256256
```
257257

258258
### Seek Performance

docs/stdlib/ipaddress.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ The `ipaddress` module provides utilities for creating and manipulating IPv4 and
1313
| `ip_address(addr)` | O(n) | O(1) | Auto-detect IP type |
1414
| `ip_network(addr)` | O(n) | O(1) | Auto-detect network type |
1515
| Address membership | O(1) | O(1) | Check in network |
16-
| Subnet iteration | O(2^k) | O(1) | Generate subnets |
16+
| Subnet iteration | O(s) | O(1) | s = number of subnets generated |
1717

1818
## IP Address Creation
1919

@@ -189,10 +189,12 @@ if is_private('10.0.0.1'):
189189
from ipaddress import IPv4Network
190190

191191
def find_common_supernet(networks):
192-
"""Find supernet containing all networks: O(n)"""
193-
networks = [IPv4Network(n) for n in networks] # O(n)
194-
supernet = IPv4Network.supernet_of(networks) # O(n)
195-
return supernet
192+
"""Find a supernet containing all networks (naive)."""
193+
nets = [IPv4Network(n) for n in networks]
194+
candidate = nets[0]
195+
while not all(candidate.supernet_of(n) or candidate == n for n in nets):
196+
candidate = candidate.supernet()
197+
return candidate
196198
```
197199

198200
### Parse Mixed Address Types

docs/stdlib/itertools.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ The `itertools` module provides efficient looping tools for creating iterators a
1717

1818
| Function | Time | Space | Notes |
1919
|----------|------|-------|-------|
20-
| `filter(pred, iter)` | O(n) total | O(1) | Filter items |
2120
| `filterfalse(pred, iter)` | O(n) total | O(1) | Opposite filter |
2221
| `compress(iter, sel)` | O(n) total | O(1) | Mask-based filter |
2322
| `dropwhile(pred, iter)` | O(n) total | O(1) | Drop while true |
@@ -44,11 +43,11 @@ The `itertools` module provides efficient looping tools for creating iterators a
4443
| `combinations(iterable, r)` | O(C(n,r)) total | O(r) per item | All r-combinations |
4544
| `combinations_with_replacement(iter, r)` | O(C(n+r-1,r)) total | O(r) per item | Combinations allowing repeats |
4645
| `permutations(iterable, r)` | O(P(n,r)) total | O(r) per item | All permutations |
47-
| `product(iter1, iter2, ...)` | O(n₁×n₂×...×nₖ) | O(n) init + O(k) per item | Cartesian product; stores all inputs in memory first |
46+
| `product(iter1, iter2, ...)` | O(n₁×n₂×...×nₖ) | O(Σnᵢ) init + O(k) per item | Cartesian product; stores all inputs in memory first |
4847

4948
## Memory Characteristics
5049

51-
All itertools functions are lazy - they generate items on demand without storing the entire result.
50+
All itertools functions are lazy iterators, but some cache input data (e.g., `cycle`, `tee`, `product`).
5251

5352
```python
5453
import itertools

0 commit comments

Comments
 (0)