Skip to content
hdub-tech edited this page Aug 18, 2026 · 10 revisions

Python

Table of Contents

Quick Resources

Collections

Type Changeable? Ordered? Has Dupes? Indexed? Creation Casting
List ✔️ ✔️ ✔️ ✔️ [1, 2, 2]
or
list((1, 2, 2))`
Set ❌ but can add/remove ❌ ❌ ❌ {1, 2, 2}
or
set((1, 2, 2)) (only keeps {1, 2})
Dictionary ✔️ ✔️ (>=3.7) ❌ ✔️ {'brand': 'suzuki', 'model': 'sv1000s'}
or
dict(brand = 'suzuki', model = 'sv1000s')
Tuple ❌ ✔️ ✔️ ✔️ (1, 2, 2)
or
tuple((1, 2, 2))

Exceptions

Chain multiple in except

Docs
image

Add Notes with e.add_note

https://docs.python.org/3/tutorial/errors.html#enriching-exceptions-with-notes

Concurrency

aiohttp

aiohttp client docs and aiohttp github repo.

asyncio

Tasks start immediately

🫨

It took me asking Claude to really catch this. The Python asyncio docs said it, but I misinterpreted the words and example to mean that tasks weren't run until they were awaited.

Bit I misunderstood image

My question to Claude:

I have a list of asyncio Tasks named tasks. I have chunked them into another list to break up the work (chunked_tasks) and sleep in between chunks. I have a for chunk in chunked_tasks which runs await asyncio.gather(*chunk) followed by await asyncio.sleep(15), with some print statements letting me know where it is. Based on the print statements, it appears that the next chunk is already processing immediately after the sleep. I have also tried time.sleep(15) . Thoughts?

The response that made me go Ohhhhhh:

The issue is almost certainly that tasks contains actual asyncio.Task objects (created via asyncio.create_task() or loop.create_task()), not coroutines. Tasks start executing the moment they're created and scheduled on the event loop — they don't wait for you to await them. Chunking and gathering them later just controls when you wait for their results, not when they run.

So by the time your first gather returns, all the other "chunks" have already been happily running in the background. sleep(15) dutifully sleeps, but the work you thought was gated behind it finished ages ago.

And from there I was able to make this code work.

Pausing a running loop

When I was working on Brute-XMLRPC, before I implemented batching by count, I wanted to pause the running loop every random number of minutes. From what I can tell, that doesn't seem do-able "out of the box". I did stumble on m2farzan's asyncio pause/resume gist and think it might actually be do-able, but it seemed like more of a lift than was necessary.

Linters / Code formatters

Pylint

On my first foray into Python, I decided I needed a linter to keep me in line. After asking Copilot what some of the options were, I went with pylint for basically two reasons:

  • Easy to set-up
  • Strict

The docs are great and easily searchable too.

Bandit

PyCQA/bandit is a tool designed to find common security issues in Python code. Docs are HERE.

Black

Black is a CODE FORMATTER, not a linter. I decided against this, because I kind of wanted to do the work myself for now, as a Python newb.

Clone this wiki locally