Python
- Use pipx to install environment management tools and scripts. (Execute binaries installed in isolated virtual environments.)
- Use pdm to manage packaging and dependencies.
- Use a PYTHONSTARTUP
Hey, there's already a Hitchhiker's Guide to Python! This is quite comprehensive on the Python development basics.
Libraries
Linting
- ruff
- mypy
- vulture
- bandit/dodgy/safety
- Layer Linter (not tried)
Development
Libraries
- passlib - high-level secrets library
- boltons - "boltons should be buitins" (stdlib additions)
- freezegun
Pandas
Understanding SettingWithCopyWarning.
Raising it as an error (setup.cfg
)
[tool:pytest]
filterwarnings =
error::pandas.core.common.SettingWithCopyWarning
error::FutureWarning
Gotchas
Probably the last one you will learn:
x = [1,2,3,4]
lambdas = [
lambda: x[i]
for i in range(4)
]
[f() for f in lambdas]
GIL
- The GIL is required to run bytecode, but not when waiting on I/O - Python can switch to different thread.
- CPython has macros to release and re-aquire GIL which can be used if extension does not need to run python bytecode/do any kind of ref-count changes (e.g. sleep, read/write files, network socket,
numpy
). - The GIL cannot be shared in CPU-bound code. CPU-bound "check" every 100 ticks to allow switching.
- I/O doesn't often block unless you are flushing - OS buffers
- Threads/Processes result in CPU context switches, while async does not.
CPU-bound : Process ←→ Threads ←→ Async : I/O-bound.
Async I/O clearly delineates the context switch locations, in theory.
Processes | Threads | Async I/O | |
---|---|---|---|
Context Switch | Yes | Yes | No |
Race Conditions | Unlikely | Yes (shared memory) | Unlikely |
Dead Locks | Unlikely | Yes | Unlikely |
Memory | High | Medium, new stack | Low, shared stack |