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

  • cqd for debugging (PYTHONSTARTUP it)
  • pysnooper - line-by-line print debugging

Libraries

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.

ProcessesThreadsAsync I/O
Context SwitchYesYesNo
Race ConditionsUnlikelyYes (shared memory)Unlikely
Dead LocksUnlikelyYesUnlikely
MemoryHighMedium, new stackLow, shared stack