Entries tagged python | Hugonweb Annotated Link Bibliography

Enriching exceptions with notes

https://docs.python.org/3/tutorial/errors.html#tut-exception-notes

You can add notes to exceptions in Python 3.13. Combined with f-strings, you can include extra debugging info.

except Exception as e:
    e.add_note('put extra debug info here')
    e.add_note(f"x={x}")
    raise

Notes on structured concurrency, or: Go statement considered harmful

https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/#nurseries-in-practice

The origin post about Trio. I first saw this a few years ago and think it's the way to do async.

Django SQLite Production Config

https://blog.pecar.me/sqlite-django-config

# yourproject/settings.py
DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.sqlite3",
        "OPTIONS": {
            "transaction_mode": "IMMEDIATE",
            "timeout": 5,  # seconds
            "init_command": """
                PRAGMA journal_mode=WAL;
                PRAGMA synchronous=NORMAL;
                PRAGMA mmap_size = 134217728;
                PRAGMA journal_size_limit = 27103364;
                PRAGMA cache_size=2000;
            """,
        },
    }
}

pyinfra

https://pyinfra.com/

Think ansible but Python instead of YAML, and a lot faster.

This seems more up my alley than ansible.

For a server or two, I'm not sure if this is the way to go or something more complicated like Packer

py-spy Python profiler

https://github.com/benfred/py-spy

A Python profiler that profiles unmodified Python processes from its own process. It can profile production code with little performance impact. It profiles extensions and all threads, which the standard library cprofile can't do.

Inverting a dictionary of lists in Python

https://stackoverflow.com/questions/35491223/inverting-a-dictionary-with-list-values

I've needed to do this countless times in particle physics data analysis and other areas.

What I've done before:

data = {'a' : ['alpha', "beta"], 'b' : ["alpha"]}
result = {}
for key in data:
    for value in data[key]:
        try:
            result[value].append(key)
        except KeyError:
            result[value] = [key]

and the simpler solutions suggested in the link:

data = {'a' : ['alpha', "beta"], 'b' : ["alpha"]}
result = {}
for key in data:
    for value in data[key]:
        result.setdefault(value,[]).append(key)

or

from collections import defaultdict

data = {'a' : ['alpha', "beta"], 'b' : ["alpha"]}
result = defaultdict(list)
for key in data:
    for value in data[key]:
        result[value].append(key)

dict.setdefault and collections.defaultdict are new to me and useful!

Stop writing Python __init__ methods

https://blog.glyph.im/2025/04/stop-writing-init-methods.html

The idea is to just set members in object constructors to keep them simple. Any complex data conversion, or side-effects should be moved to a class-method.

This seems like a great way to deal with constructors taking multiple different inputs.

I do think using traditional constructors has the advantage of following a widely used convention (the principle of least surprise in API design) and can be simpler to use.

Python range is not an iterator

https://treyhunner.com/2018/02/python-range-is-not-an-iterator/

Counterintuitively, Python's range function isn't an iterator, because you can't call next() on it. It is lazy like iterators but is more like a "lazy collection." Like a collection, you can make an iterator from one with the iter() function.