56,966 blogs ยท [ { "id": "01a08745-7507-702c-b551-47ec67621720", "title": "Python 3.15: features that didn't make the headlines", "url": "https://blog.changs.co.uk/python-315-features-that-didnt-make-the-headlines.html", "published_at": "2026-05-12T23:00:00+00:00" }, { "id": "01a08745-7507-702c-b551-47ec68144113", "title": "You can (kind of) run Django in subinterpreters", "url": "https://blog.changs.co.uk/you-can-kind-of-run-django-in-subinterpreters.html", "published_at": "2026-04-25T23:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40ef5043da5", "title": "Don't make Python code decisions based on whitespace", "url": "https://blog.changs.co.uk/dont-make-python-code-decisions-based-on-whitespace.html", "published_at": "2026-03-14T00:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40ef5c377ec", "title": "Benchmarking Free-threading Performance with Tachyon", "url": "https://blog.changs.co.uk/benchmarking-free-threading-performance-with-tachyon.html", "published_at": "2026-02-21T00:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40ef6217ed4", "title": "Free-threading is slowly getting there", "url": "https://blog.changs.co.uk/free-threading-is-slowly-getting-there.html", "published_at": "2026-02-20T00:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40ef6364e34", "title": "Datetime Arithmetic in Python", "url": "https://blog.changs.co.uk/datetime-arithmetic-in-python.html", "published_at": "2026-02-17T00:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40ef6f0ceac", "title": "Caching an Asyncio Function the Easy Way", "url": "https://blog.changs.co.uk/caching-an-asyncio-function-the-easy-way.html", "published_at": "2026-02-16T00:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40ef7aab54b", "title": "Counting down Chinese New Year with Marimo", "url": "https://blog.changs.co.uk/counting-down-chinese-new-year-with-marimo.html", "published_at": "2026-02-12T00:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40ef86fb6c0", "title": "Replacing tox with UV", "url": "https://blog.changs.co.uk/replacing-tox-with-uv.html", "published_at": "2026-02-01T00:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40ef96ace21", "title": "Webasgi - Run python web apps in a browser", "url": "https://blog.changs.co.uk/webasgi-run-python-web-apps-in-a-browser.html", "published_at": "2026-01-26T00:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40efa00a133", "title": "Writing a SQS task framework from scratch", "url": "https://blog.changs.co.uk/writing-a-sqs-task-framework-from-scratch.html", "published_at": "2026-01-18T00:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40efa3346d3", "title": "Asyncio is neither fast nor slow", "url": "https://blog.changs.co.uk/asyncio-is-neither-fast-nor-slow.html", "published_at": "2026-01-12T00:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40efaaca18d", "title": "I was wrong about Subinterpreters", "url": "https://blog.changs.co.uk/i-was-wrong-about-subinterpreters.html", "published_at": "2026-01-01T00:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40efae31d87", "title": "Trying out marimo notebooks", "url": "https://blog.changs.co.uk/trying-out-marimo-notebooks.html", "published_at": "2025-12-03T00:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40efb3d746f", "title": "Fixing lazy imports: Generating Static Types Dynamically", "url": "https://blog.changs.co.uk/fixing-lazy-imports-generating-static-types-dynamically.html", "published_at": "2025-10-29T00:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40efb7714b9", "title": "Python 3.14: 3 Asyncio Changes", "url": "https://blog.changs.co.uk/python-314-3-asyncio-changes.html", "published_at": "2025-10-08T23:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40efc6b173d", "title": "Finally trying out Mojo ๐Ÿ”ฅ", "url": "https://blog.changs.co.uk/finally-trying-out-mojo.html", "published_at": "2025-10-01T23:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40efcf2f26c", "title": "Blog 1 year in", "url": "https://blog.changs.co.uk/blog-1-year-in.html", "published_at": "2025-09-23T23:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40efd992c7c", "title": "Asyncio backpressure - follow up", "url": "https://blog.changs.co.uk/asyncio-backpressure-follow-up.html", "published_at": "2025-09-13T23:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40efdc0be25", "title": "Simplify lambda deployments with UV", "url": "https://blog.changs.co.uk/simplify-lambda-deployments-with-uv.html", "published_at": "2025-08-31T23:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40efe7133d8", "title": "Dynamic config part 1: Pydantic and file watchers", "url": "https://blog.changs.co.uk/dynamic-config-part-1-pydantic-and-file-watchers.html", "published_at": "2025-08-25T23:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40eff2fcaca", "title": "Subinterpreters and Asyncio", "url": "https://blog.changs.co.uk/subinterpreters-and-asyncio.html", "published_at": "2025-08-04T23:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40eff80a2fa", "title": "Python 3.14: 3 smaller features", "url": "https://blog.changs.co.uk/python-314-3-smaller-features.html", "published_at": "2025-07-10T23:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40effef4742", "title": "My Chinese birthdays, time keeping is hard!", "url": "https://blog.changs.co.uk/my-chinese-birthdays-time-keeping-is-hard.html", "published_at": "2025-06-24T23:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40f001dc27d", "title": "Asyncio backpressure - Processing lots of tasks in parallel", "url": "https://blog.changs.co.uk/asyncio-backpressure-processing-lots-of-tasks-in-parallel.html", "published_at": "2025-06-19T23:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40f00de9016", "title": "Docker's MCP toolkit First Look", "url": "https://blog.changs.co.uk/dockers-mcp-toolkit-first-look.html", "published_at": "2025-06-11T23:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40f0143327d", "title": "First Look at MCP", "url": "https://blog.changs.co.uk/first-look-at-mcp.html", "published_at": "2025-06-02T23:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40f020fcaf2", "title": "Python 3.14: State of free threading", "url": "https://blog.changs.co.uk/python-314-state-of-free-threading.html", "published_at": "2025-05-25T23:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40f0256cbd7", "title": "t-strings: the good and the ugly", "url": "https://blog.changs.co.uk/t-strings-the-good-and-the-ugly.html", "published_at": "2025-05-06T23:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40f02e90ee6", "title": "Why you should write your tools in Python Again", "url": "https://blog.changs.co.uk/why-you-should-write-your-tools-in-python-again.html", "published_at": "2025-04-07T23:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40f0342fdec", "title": "Building a DSL with Python Operators", "url": "https://blog.changs.co.uk/building-a-dsl-with-python-operators.html", "published_at": "2025-03-12T00:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40f03ed87ae", "title": "better-functools: Python functional fun", "url": "https://blog.changs.co.uk/better-functools-python-functional-fun.html", "published_at": "2025-03-09T00:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40f0470ea1f", "title": "Sqlalchemy Footgun: Discarding the statement", "url": "https://blog.changs.co.uk/sqlalchemy-footgun-discarding-the-statement.html", "published_at": "2025-02-02T00:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40f0545e91d", "title": "Jamie's Pattern Matching Cookbook", "url": "https://blog.changs.co.uk/jamies-pattern-matching-cookbook.html", "published_at": "2025-01-16T00:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40f0573cb54", "title": "How good are sub-interpreters in Python now?", "url": "https://blog.changs.co.uk/how-good-are-sub-interpreters-in-python-now.html", "published_at": "2025-01-03T00:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40f05cd0083", "title": "How free are threads in Python now?", "url": "https://blog.changs.co.uk/how-free-are-threads-in-python-now.html", "published_at": "2024-12-31T00:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40f06a053df", "title": "Customising Pattern Matching Behaviour", "url": "https://blog.changs.co.uk/customising-pattern-matching-behaviour.html", "published_at": "2024-12-09T00:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40f06c4b1ee", "title": "Python-in-Python Sandboxing LLM Generated Code", "url": "https://blog.changs.co.uk/python-in-python-sandboxing-llm-generated-code.html", "published_at": "2024-12-02T00:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40f0797445c", "title": "My SQLAlchemy Cookbook", "url": "https://blog.changs.co.uk/my-sqlalchemy-cookbook.html", "published_at": "2024-11-25T00:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40f08926dc4", "title": "TypedDicts are better than you think", "url": "https://blog.changs.co.uk/typeddicts-are-better-than-you-think.html", "published_at": "2024-09-30T23:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40f09143a68", "title": "Closing Python Iterators", "url": "https://blog.changs.co.uk/closing-python-iterators.html", "published_at": "2024-09-27T23:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40f09bb0cf3", "title": "Free Threaded Python With Asyncio", "url": "https://blog.changs.co.uk/free-threaded-python-with-asyncio.html", "published_at": "2024-09-18T23:00:00+00:00" }, { "id": "01a08745-7508-7394-91b3-f40f0a702582", "title": "My First Blog Post", "url": "https://blog.changs.co.uk/my-first-blog-post.html", "published_at": "2024-09-17T23:00:00+00:00" } ] posts Claim your blog
Back to blog.changs.co.uk
Blog ยท corpus.blog/blogs/blog.changs.co.uk/posts

blog.changs.co.uk

blog.changs.co.uk

2026

2025

2024