skip to navigation
skip to content

Planet Python

Last update: November 19, 2025 01:43 AM UTC

November 18, 2025


The Python Coding Stack

I Don’t Like Magic • Exploring The Class Attributes That Aren’t Really Class Attributes • [Club]

I don’t like magic. I don’t mean the magic of the Harry Potter kind—that one I’d like if only I could have it. It’s the “magic” that happens behind the scenes when a programming language like Python does things out of sight. You’ll often find things you have to “just learn” along the Python learning journey. “That’s the way things are,” you’re told.

That’s the kind of magic I don’t like. I want to know how things work. So let me take you back to when I first learnt about named tuples—the NamedTuple in the typing module, not the other one—and data classes. They share a similar syntax, and it’s this shared syntax that confused me at first. I found these topics harder to understand because of this.

Their syntax is different from other stuff I had learnt up to that point. And I could not reconcile it with the stuff I knew. That bothered me. It also made me doubt the stuff I already knew. Here’s what I mean. Let’s look at a standard class first:

class Person:
    classification = “Human”
​
    def __init__(self, name, age, profession):
        self.name = name
        self.age = age
        self.profession = profession

You define a class attribute, .classification, inside the class block, but outside any of the special methods. All instances will share this class attribute. Then you define the .__init__() special method and create three instance attributes: .name, .age, and .profession. Each instance will have its own versions of these instance attributes. If you’re not familiar with class attributes and instance attributes, you can read my seven-part series on object-oriented programming: A Magical Tour Through Object-Oriented Programming in Python • Hogwarts School of Codecraft and Algorithmancy

Now, let’s assume you don’t actually need the class attribute and that this class will only store data. It won’t have any additional methods. You decide to use a data class instead:

from dataclasses import dataclass
​
@dataclass
class Person:
    name: str
    age: int
    profession: str

Or you prefer to use a named tuple, and you reach out for typing.NamedTuple:

from typing import NamedTuple
​
class Person(NamedTuple):
    name: str
    age: int
    profession: str

The syntax is similar. I’ll tell you why I used to find this confusing soon.

Whichever option you choose, you can create an instance using Person(”Matthew”, 30, “Python Programmer”). And each instance you create will have its own instance attributes .name, .age, and .profession.

But wait a minute! The data class and the named tuple use syntax that’s similar to creating class attributes. You define these just inside the class block and not in an .__init__() method. How come they create instance attributes? “That’s just how they work” is not good enough for me.

These aren’t class attributes. Not yet. There’s no value associated with these identifiers. Therefore, they can’t be class attributes, even though you write them where you’d normally add class attributes in a standard class. However, they can be class attributes if you include a default value:

@dataclass
class Person:
    name: str
    age: int
    profession: str = “Python Programmer”

The .profession attribute now has a string assigned to it. In a data class, this represents the default value. But if this weren’t a data class, you’d look at .profession and recognise it as a class attribute. But in a data class, it’s not a class attribute, it’s an instance attribute, as are .name and .age, which look like…what do they look like, really? They’re just type hints. Yes, type hints without any object assigned. Python type hints allow you to do this:

>>> first_name: str

This line is valid in Python. It does not create the variable name. You can confirm this:

>>> first_name
Traceback (most recent call last):
  File “<input>”, line 1, in <module>
NameError: name ‘first_name’ is not defined

Although you cannot just write first_name if the identifier doesn’t exist, you can use first_name: str. This creates an annotation which serves as the type hint. Third-party tools now know that when you create the variable first_name and assign it a value, it ought to be a string.

So, let’s go back to the latest version of the Person data class with the default value for one of the attributes:

@dataclass
class Person:
    name: str
    age: int
    profession: str = “Python Programmer”

But let’s ignore the @dataclass decorator for now. Indeed, let’s remove this decorator:

class Person:
    name: str
    age: int
    profession: str = “Python Programmer”

You define a class with one class attribute, .profession and three type hints:

How can we convert this information into instance attributes when creating an instance of the class? I won’t try to reverse engineer NamedTuple or data classes here. Instead, I’ll explore my own path to get a sense of what might be happening in those tools.

Let’s start hacking away…

Read more

November 18, 2025 10:01 PM UTC


PyCoder’s Weekly

Issue #709: deepcopy(), JIT, REPL Tricks, and More (Nov. 18, 2025)

#709 – NOVEMBER 18, 2025
View in Browser »

The PyCoder’s Weekly Logo


Why Python’s deepcopy Can Be So Slow

“Python’s copy.deepcopy() creates a fully independent clone of an object, traversing every nested element of the object graph.” That can be expensive. Learn what it is doing and how you can sometimes avoid the cost.
SAURABH MISRA

A Plan for 5-10%* Faster Free-Threaded JIT by Python 3.16

Just In Time compilation is under active development in the CPython interpreter. This blog post outlines the targets for the next two Python releases.
KEN JIN

Fast Container Builds: 202 - Check out the Deep Dive

alt

This blog explores the causes and consequences of slow container builds, with a focus on understanding how BuildKit’s capabilities support faster container builds. →
DEPOT sponsor

The Python Standard REPL: Try Out Code and Ideas Quickly

The Python REPL gives you instant feedback as you code. Learn to use this powerful tool to type, run, debug, edit, and explore Python interactively.
REAL PYTHON

Join in the PSF Year-End Fundraiser & Membership Drive!

PYTHON SOFTWARE FOUNDATION

PEP 814: Add Frozendict Built-in Type (Added)

PYTHON.ORG

PyBay 2025 Videos Released

YOUTUBE.COM

DjangoCon US 2025 Videos Released

YOUTUBE.COM

Python Jobs

Python Video Course Instructor (Anywhere)

Real Python

Python Tutorial Writer (Anywhere)

Real Python

More Python Jobs >>>

Articles & Tutorials

Preparing Data Science Projects for Production

How do you prepare your Python data science projects for production? What are the essential tools and techniques to make your code reproducible, organized, and testable? This week on the show, Khuyen Tran from CodeCut discusses her new book, “Production Ready Data Science.”
REAL PYTHON podcast

Becoming a Core Developer

Throughout your open source journey, you have no doubt been interacting with the core development team of the projects to which you have been contributing. Have you ever wondered how people become core developers of a project?
STEFANIE MOLIN

Modern, Self-Hosted Authentication

alt

Keep your users, your data and your stack with PropelAuth BYO. Easily add Enterprise authentication features like Enterprise SSO, SCIM and session management. Keep your sales team happy and give your CISO piece of mind →
PROPELAUTH sponsor

38 Things Python Developers Should Learn in 2025

Talk Python interviews Peter Wang and Calvin Hendrix-Parker and they discuss loads of things in the Python ecosystem that are worth learning, including free-threaded CPython, MCP, DuckDB, Arrow, and much more.
TALK PYTHON podcast

Trusted Publishing for GitLab Self-Managed and Organizations

The Trusted Publishing system for PyPI is seeing rapid adoption. This post talks about its growth along with the next steps: adding GitLab and handling organizations.
MIKE FIELDER

Decompression Is Up to 30% Faster in CPython 3.15

Zstandard compression got added in Python 3.14, but work is on-going. Python 3.15 is showing performance improvements in both zstd and other compression modules.
EMMA SMITH

__slots__ for Optimizing Classes

Most Python objects store their attributes in __dict__, which is a dictionary. Modules and classes always use __dict__, but not everything does.
TREY HUNNER

Convert Documents Into LLM-Ready Markdown

Get started with Python MarkItDown to turn PDFs, Office files, images, and URLs into clean, LLM-ready Markdown in seconds.
REAL PYTHON

Quiz: Convert Documents Into LLM-Ready Markdown

Practice MarkItDown basics. Convert PDFs, Word documents, Excel documents, and HTML documents to Markdown. Try the quiz.
REAL PYTHON

Convert Scikit-learn Pipelines into SQL Queries with Orbital

Orbital is a new library that converts Scikit-learn pipelines into SQL queries, enabling machine learning model inference directly within SQL databases.
POSIT sponsor

Python Operators and Expressions

Operators let you combine objects to create expressions that perform computations – the core of how Python works.
REAL PYTHON course

A Generator, Duck Typing, and a Branchless Conditional Walk Into a Bar

What’s your favorite line of code? Rodrigo expounds about generators, duck typing, and branchless conditionals.
RODRIGO GIRÃO SERRÃO

Projects & Code

fastapi-voyager: Explore Your API Interactively

GITHUB.COM/ALLMONDAY

Narwhals-daft: A Narwhals Plugin for Daft Dataframes

MARCO GORELLI • Shared by Marco Gorelli

zensical: A Modern Static Site Generator

GITHUB.COM/ZENSICAL

django-subatomic: Control Transaction Logic in Django

GITHUB.COM/KRAKEN-TECH

httptap: CLI Measuring HTTP Request Phases

GITHUB.COM/OZERANSKII

Events

Weekly Real Python Office Hours Q&A (Virtual)

November 19, 2025
REALPYTHON.COM

DELSU Tech Invasion 3.0

November 19 to November 21, 2025
HAMPLUSTECH.COM

PyData Bristol Meetup

November 20, 2025
MEETUP.COM

PyLadies Dublin

November 20, 2025
PYLADIES.COM

Python Sul 2025

November 21 to November 24, 2025
PYTHON.ORG.BR


Happy Pythoning!
This was PyCoder’s Weekly Issue #709.
View in Browser »

alt

[ Subscribe to 🐍 PyCoder’s Weekly 💌 – Get the best Python news, articles, and tutorials delivered to your inbox once a week >> Click here to learn more ]

November 18, 2025 07:30 PM UTC


Real Python

Break Out of Loops With Python's break Keyword

In Python, the break statement lets you exit a loop prematurely, transferring control to the code that follows the loop. This tutorial guides you through using break in both for and while loops. You’ll also briefly explore the continue keyword, which complements break by skipping the current loop iteration.

By the end of this video course, you’ll understand that:


[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]

November 18, 2025 02:00 PM UTC


Mike Driscoll

Black Friday Python Deals Came Early

Black Friday deals came early this year. You can get 50% off of any of my Python books or courses until the end of November. You can use this coupon code at checkout: BLACKISBACK 

The following links already have the discount applied:

Python eBooks

Python Courses

 

The post Black Friday Python Deals Came Early appeared first on Mouse Vs Python.

November 18, 2025 01:41 PM UTC


PyCon

Join us in “Trailblazing Python Security” at PyCon US 2026

PyCon US 2026 is coming to Long Beach, California! PyCon US is the premiere conference for the Python programming language in North America. Python experts and enthusiasts from around the globe will gather in Long Beach to discuss and learn about the latest developments to the Python programming language and massive ecosystem of Python projects.

New in 2026: Security and AI talk tracks!

Brand new this year are two themed talk tracks: “Trailblazing Python Security” and “Python and the Future of AI”. We want to hear talks from you! The PyCon US Call for Proposals (CFP) for PyCon US 2026 is now open through December 19th, 2025. Don’t wait to submit your talks, the earlier you submit the better.

If your company or organization would like to show support for a more secure Python ecosystem by sponsoring the “Trailblazing Python Security” talk track check out the PyCon US 2026 Sponsor Prospectus or reach out via email to sponsors@python.org. We’ve made three sponsor slots available for the track: one lead sponsor and two co-sponsors, so act fast!

We’re also looking for mentors! If you’re an experienced speaker and want to help someone with their proposal, the PyCon US Proposal Mentorship Program is for you! We typically get twice the number of mentees seeking support than we do for volunteer mentors. Sign up to mentor via this form by November 21, 2025. 

What’s next for Python security?

If you're interested in Python and security: why should you attend PyCon US 2026?

Many Pythonistas use the Open Source software available on the Python Package Index (PyPI). PyCon US is the flagship conference hosted by the Python Software Foundation, the stewards of the Python Package Index. Many brand-new security features are announced and demoed live at PyCon US, such as “PyPI Digital Attestations”, “PyPI Organizations”, and “Trusted Publishers”.

You’ll be among the first Pythonistas to hear about these new features and chat with the developers and maintainers of PyPI.

Open Space about handling vulnerabilities in Python projects

PyCon US always has many opportunities to learn about the latest in Python security. Last year at PyCon US 2025 hosted a “Python Security Mini-Summit” Open Space with speakers discussing the Cyber Resilience Act (CRA), CVE and Open Source, and supply-chain within the Scientific Python community. Expect even more security content this year!

The conference talk schedule includes many talks about using memory-safe systems programming languages like Rust with Python, authentication with popular Web frameworks, how to handle security vulnerabilities as an Open Source project, and how the “Phantom Dependency” problem affects the Python package ecosystem.

We hope you’ll consider joining us in Long Beach, CA for PyCon US 2026. See you there! 🔥🏕️

November 18, 2025 11:17 AM UTC


Seth Michael Larson

BrotliCFFI has two new maintainers

Quick post announcing that the Python package brotlicffi has two new maintainers: Nathan Goldbaum and Christian Clauss. Thank you both for stepping up to help me with this package.

Both these folks (along with a few others) have shown up and gotten straight to work in adding support for Python 3.14, free-threaded Python, and the latest release of Brotli. I’ve given myself the task to change the PyPI publishing workflow to allow a group of contributors to make new releases to mostly get out of their way!

I’m grateful that the project lives under the python-hyper organization which is structured in such a way that allows onboarding new contributors quickly after they’ve shown interest in contributing to a project meaningfully.



Thanks for keeping RSS alive! ♥

November 18, 2025 12:00 AM UTC

November 17, 2025


Rodrigo Girão Serrão

Floodfill algorithm in Python

Learn how to implement and use the floodfill algorithm in Python.

What is the floodfill algorithm?

Click the image below to randomly colour the region you click.

Go ahead, try it!

IMG_WIDTH = 160 IMG_HEIGHT = 160 PIXEL_SIZE = 2 import asyncio import collections import random from pyscript import display from pyodide.ffi import create_proxy import js from js import fetch canvas = js.document.getElementById("bitmap") ctx = canvas.getContext("2d") URL = "/blog/floodfill-algorithm-in-python/_python.txt" async def load_bitmap(url: str) -> list[list[int]]: # Fetch the text file from the URL response = await fetch(url) text = await response.text() bitmap: list[list[int]] = [] for line in text.splitlines(): line = line.strip() if not line: continue row = [int(ch) for ch in line if ch in "01"] if row: bitmap.append(row) return bitmap def draw_bitmap(bitmap): rows = len(bitmap) cols = len(bitmap[0]) if rows > 0 else 0 if rows == 0 or cols == 0: return for y, row in enumerate(bitmap): for x, value in enumerate(row): if value == 1: ctx.fillStyle = "black" else: ctx.fillStyle = "white" ctx.fillRect(x * PIXEL_SIZE, y * PIXEL_SIZE, PIXEL_SIZE, PIXEL_SIZE) _neighbours = [(1, 0), (-1, 0), (0, 1), (0, -1)] async def fill_bitmap(bitmap, x, y): if bitmap[y][x] == 1: return ctx = canvas.getContext("2d") r, g, b = (random.randint(0, 255) for _ in range(3)) ctx.fillStyle = f"rgb({r}, {g}, {b})" def draw_pixel(x, y): ctx.fillRect(x * PIXEL_SIZE, y * PIXEL_SIZE, PIXEL_SIZE, PIXEL_SIZE) pixels = collections.deque([(x, y)]) seen = set((x, y)) while pixels: nx, ny = pixels.pop() draw_pixel(nx, ny) for dx, dy in _neighbours: x_, y_ = nx + dx, ny + dy if x_ < 0 or x_ >= IMG_WIDTH or y_ < 0 or y_ >= IMG_HEIGHT or (x_, y_) in seen: continue if bitmap[y_][x_] == 0: seen.add((x_, y_)) pixels.appendleft((x_, y_)) await asyncio.sleep(0.0001) is_running = False def get_event_coords(event): """Return (clientX, clientY) for mouse/pointer/touch events.""" # PointerEvent / MouseEvent: clientX/clientY directly available if hasattr(event, "clientX") and hasattr(event, "clientY") and event.clientX is not None: return event.clientX, event.clientY # TouchEvent: use the first touch point if hasattr(event, "touches") and event.touches.length > 0: touch = event.touches.item(0) return touch.clientX, touch.clientY # Fallback: try changedTouches if hasattr(event, "changedTouches") and event.changedTouches.length > 0: touch = event.changedTouches.item(0) return touch.clientX, touch.clientY return None, None async def on_canvas_press(event): global is_running if is_running: return is_running = True try: # Avoid scrolling / zooming taking over on touch if hasattr(event, "preventDefault"): event.preventDefault() clientX, clientY = get_event_coords(event) if clientX is None: # Could not read coordinates; bail out gracefully return rect = canvas.getBoundingClientRect() # Account for CSS scaling: map from displayed size to canvas units scale_x = canvas.width / rect.width scale_y = canvas.height / rect.height x_canvas = (clientX - rect.left) * scale_x y_canvas = (clientY - rect.top) * scale_y x_idx = int(x_canvas // PIXEL_SIZE) y_idx...

November 17, 2025 03:49 PM UTC


Real Python

How to Serve a Website With FastAPI Using HTML and Jinja2

By the end of this guide, you’ll be able to serve dynamic websites from FastAPI endpoints using Jinja2 templates powered by CSS and JavaScript. By leveraging FastAPI’s HTMLResponse, StaticFiles, and Jinja2Templates classes, you’ll use FastAPI like a traditional Python web framework.

You’ll start by returning basic HTML from your endpoints, then add Jinja2 templating for dynamic content, and finally create a complete website with external CSS and JavaScript files to copy hex color codes:

To follow along, you should be comfortable with Python functions and have a basic understanding of HTML and CSS. Experience with FastAPI is helpful but not required.

Get Your Code: Click here to download the free sample code that shows you how to serve a website with FastAPI using HTML and Jinja2.

Take the Quiz: Test your knowledge with our interactive “How to Serve a Website With FastAPI Using HTML and Jinja2” quiz. You’ll receive a score upon completion to help you track your learning progress:


Interactive Quiz

How to Serve a Website With FastAPI Using HTML and Jinja2

Review how to build dynamic websites with FastAPI and Jinja2, and serve HTML, CSS, and JS with HTMLResponse and StaticFiles.

Prerequisites

Before you start building your HTML-serving FastAPI application, you’ll need to set up your development environment with the required packages. You’ll install FastAPI along with its standard dependencies, including the ASGI server you need to run your application.

Select your operating system below and install FastAPI with all the standard dependencies inside a virtual environment:

Windows PowerShell
PS> python -m venv venv
PS> .\venv\Scripts\activate
(venv) PS> python -m pip install "fastapi[standard]"
Shell
$ python -m venv venv
$ source venv/bin/activate
(venv) $ python -m pip install "fastapi[standard]"

These commands create and activate a virtual environment, then install FastAPI along with Uvicorn as the ASGI server, and additional dependencies that enhance FastAPI’s functionality. The standard option ensures you have everything you need for this tutorial, including Jinja2 for templating.

Step 1: Return Basic HTML Over an API Endpoint

When you take a close look at a FastAPI example application, you commonly encounter functions returning dictionaries, which the framework transparently serializes into JSON responses.

However, FastAPI’s flexibility allows you to serve various custom responses besides that—for example, HTMLResponse to return content as a text/html type, which your browser interprets as a web page.

To explore returning HTML with FastAPI, create a new file called main.py and build your first HTML-returning endpoint:

Python main.py
from fastapi import FastAPI
from fastapi.responses import HTMLResponse

app = FastAPI()

@app.get("/", response_class=HTMLResponse)
def home():
    html_content = """
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Home</title>
    </head>
    <body>
        <h1>Welcome to FastAPI!</h1>
    </body>
    </html>
    """
    return html_content

The HTMLResponse class tells FastAPI to return your content with the text/html content type instead of the default application/json response. This ensures that browsers interpret your response as HTML rather than plain text.

Before you can visit your home page, you need to start your FastAPI development server to see the HTML response in action:

Read the full article at https://realpython.com/fastapi-jinja2-template/ »


[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]

November 17, 2025 02:00 PM UTC

Quiz: How to Serve a Website With FastAPI Using HTML and Jinja2

In this quiz, you’ll test your understanding of building dynamic websites with FastAPI and Jinja2 Templates.

By working through this quiz, you’ll revisit how to return HTML with HTMLResponse, serve assets with StaticFiles, render Jinja2 templates with context, and include CSS and JavaScript for interactivity like copying hex color codes.

If you are new to FastAPI, review Get Started With FastAPI. You can also brush up on Python functions and HTML and CSS.


[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]

November 17, 2025 12:00 PM UTC


Python Bytes

#458 I will install Linux on your computer

<strong>Topics covered in this episode:</strong><br> <ul> <li><strong>Possibility of a new website for Django</strong></li> <li><strong><a href="https://github.com/slaily/aiosqlitepool?featured_on=pythonbytes">aiosqlitepool</a></strong></li> <li><strong><a href="https://deptry.com?featured_on=pythonbytes">deptry</a></strong></li> <li><strong><a href="https://github.com/juftin/browsr?featured_on=pythonbytes">browsr</a></strong></li> <li><strong>Extras</strong></li> <li><strong>Joke</strong></li> </ul><a href='https://www.youtube.com/watch?v=s2HlckfeBCs' style='font-weight: bold;'data-umami-event="Livestream-Past" data-umami-event-episode="458">Watch on YouTube</a><br> <p><strong>About the show</strong></p> <p>Sponsored by us! Support our work through:</p> <ul> <li>Our <a href="https://training.talkpython.fm/?featured_on=pythonbytes"><strong>courses at Talk Python Training</strong></a></li> <li><a href="https://courses.pythontest.com/p/the-complete-pytest-course?featured_on=pythonbytes"><strong>The Complete pytest Course</strong></a></li> <li><a href="https://www.patreon.com/pythonbytes"><strong>Patreon Supporters</strong></a></li> </ul> <p><strong>Connect with the hosts</strong></p> <ul> <li>Michael: <a href="https://fosstodon.org/@mkennedy">@mkennedy@fosstodon.org</a> / <a href="https://bsky.app/profile/mkennedy.codes?featured_on=pythonbytes">@mkennedy.codes</a> (bsky)</li> <li>Brian: <a href="https://fosstodon.org/@brianokken">@brianokken@fosstodon.org</a> / <a href="https://bsky.app/profile/brianokken.bsky.social?featured_on=pythonbytes">@brianokken.bsky.social</a></li> <li>Show: <a href="https://fosstodon.org/@pythonbytes">@pythonbytes@fosstodon.org</a> / <a href="https://bsky.app/profile/pythonbytes.fm">@pythonbytes.fm</a> (bsky)</li> </ul> <p>Join us on YouTube at <a href="https://pythonbytes.fm/stream/live"><strong>pythonbytes.fm/live</strong></a> to be part of the audience. Usually <strong>Monday</strong> at 10am PT. Older video versions available there too.</p> <p>Finally, if you want an artisanal, hand-crafted digest of every week of the show notes in email form? Add your name and email to <a href="https://pythonbytes.fm/friends-of-the-show">our friends of the show list</a>, we'll never share it.</p> <p><strong>Brian #1: Possibility of a new website for Django</strong></p> <ul> <li>Current Django site: <a href="https://www.djangoproject.com?featured_on=pythonbytes">djangoproject.com</a></li> <li>Adam Hill’s in progress redesign idea: <a href="https://django-homepage.adamghill.com?featured_on=pythonbytes">django-homepage.adamghill.com</a></li> <li>Commentary in the <a href="https://forum.djangoproject.com/t/want-to-work-on-a-homepage-site-redesign/42909/35?featured_on=pythonbytes">Want to work on a homepage site redesign? discussion</a></li> </ul> <p><strong>Michael #2: <a href="https://github.com/slaily/aiosqlitepool?featured_on=pythonbytes">aiosqlitepool</a></strong></p> <ul> <li>🛡️A resilient, high-performance asynchronous connection pool layer for SQLite, designed for efficient and scalable database operations.</li> <li>About 2x better than regular SQLite.</li> <li>Pairs with <a href="https://github.com/omnilib/aiosqlite?featured_on=pythonbytes">aiosqlite</a></li> <li><code>aiosqlitepool</code> in three points: <ul> <li><strong>Eliminates connection overhead</strong>: It avoids repeated database connection setup (syscalls, memory allocation) and teardown (syscalls, deallocation) by reusing long-lived connections.</li> <li><strong>Faster queries via "hot" cache</strong>: Long-lived connections keep SQLite's in-memory page cache "hot." This serves frequently requested data directly from memory, speeding up repetitive queries and reducing I/O operations.</li> <li><strong>Maximizes concurrent throughput</strong>: Allows your application to process significantly more database queries per second under heavy load.</li> </ul></li> </ul> <p><strong>Brian #3: <a href="https://deptry.com?featured_on=pythonbytes">deptry</a></strong></p> <ul> <li>“deptry is a command line tool to check for issues with dependencies in a Python project, such as unused or missing dependencies. It supports projects using Poetry, pip, PDM, uv, and more generally any project supporting PEP 621 specification.”</li> <li>“Dependency issues are detected by scanning for imported modules within all Python files in a directory and its subdirectories, and comparing those to the dependencies listed in the project's requirements.”</li> <li><p>Note if you use <code>project.optional-dependencies</code></p> <div class="codehilite"> <pre><span></span><code><span class="k">[project.optional-dependencies]</span> <span class="n">plot</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;matplotlib&quot;</span><span class="p">]</span> <span class="n">test</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;pytest&quot;</span><span class="p">]</span> </code></pre> </div></li> <li><p>you have to set a config setting to get it to work right:</p> <div class="codehilite"> <pre><span></span><code><span class="k">[tool.deptry]</span> <span class="n">pep621_dev_dependency_groups</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span><span class="s2">&quot;test&quot;</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;docs&quot;</span><span class="p">]</span> </code></pre> </div></li> </ul> <p><strong>Michael #4: <a href="https://github.com/juftin/browsr?featured_on=pythonbytes">browsr</a></strong></p> <ul> <li><strong><code>browsr</code></strong> 🗂️ is a pleasant <strong>file explorer</strong> in your terminal. It's a command line <strong>TUI</strong> (text-based user interface) application that empowers you to browse the contents of local and remote filesystems with your keyboard or mouse.</li> <li>You can quickly navigate through directories and peek at files whether they're hosted <strong>locally</strong>, in <strong>GitHub</strong>, over <strong>SSH</strong>, in <strong>AWS S3</strong>, <strong>Google Cloud Storage</strong>, or <strong>Azure Blob Storage</strong>.</li> <li>View code files with syntax highlighting, format JSON files, render images, convert data files to navigable datatables, and more.</li> </ul> <p><strong>Extras</strong></p> <p>Brian:</p> <ul> <li>Understanding the MICRO</li> <li>TDD chapter coming out later today or maybe tomorrow, but it’s close.</li> </ul> <p>Michael:</p> <ul> <li><a href="https://marketplace.visualstudio.com/items?itemName=johnpapa.vscode-peacock&featured_on=pythonbytes">Peacock</a> is excellent</li> </ul> <p><strong>Joke: <a href="https://x.com/thatstraw/status/1977317574779048171?featured_on=pythonbytes">I will find you</a></strong></p>

November 17, 2025 08:00 AM UTC

November 16, 2025


Ned Batchelder

Why your mock breaks later

In Why your mock doesn’t work I explained this rule of mocking:

Mock where the object is used, not where it’s defined.

That blog post explained why that rule was important: often a mock doesn’t work at all if you do it wrong. But in some cases, the mock will work even if you don’t follow this rule, and then it can break much later. Why?

Let’s say you have code like this:

# user.py

def get_user_settings():
    with open(Path("~/settings.json").expanduser()) as f:
        return json.load(f)

def add_two_settings():
    settings = get_user_settings()
    return settings["opt1"] + settings["opt2"]

You write a simple test:

def test_add_two_settings():
    # NOTE: need to create ~/settings.json for this to work:
    #   {"opt1": 10, "opt2": 7}
    assert add_two_settings() == 17

As the comment in the test points out, the test will only pass if you create the correct settings.json file in your home directory. This is bad: you don’t want to require finicky environments for your tests to pass.

The thing we want to avoid is opening a real file, so it’s a natural impulse to mock out open():

# test_user.py

from io import StringIO
from unittest.mock import patch

@patch("builtins.open")
def test_add_two_settings(mock_open):
    mock_open.return_value = StringIO('{"opt1": 10, "opt2": 7}')
    assert add_two_settings() == 17

Nice, the test works without needing to create a file in our home directory!

Much later...

One day your test suite fails with an error like:

...
  File ".../site-packages/coverage/python.py", line 55, in get_python_source
    source_bytes = read_python_source(try_filename)
  File ".../site-packages/coverage/python.py", line 39, in read_python_source
    return source.replace(b"\r\n", b"\n").replace(b"\r", b"\n")
           ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
TypeErrorreplace() argument 1 must be str, not bytes

What happened!? Coverage.py code runs during your tests, invoked by the Python interpreter. The mock in the test changed the builtin open, so any use of it anywhere during the test is affected. In some cases, coverage.py needs to read your source code to record the execution properly. When that happens, coverage.py unknowingly uses the mocked open, and bad things happen.

When you use a mock, patch it where it’s used, not where it’s defined. In this case, the patch would be:

@patch("myproduct.user.open")
def test_add_two_settings(mock_open):
    ... etc ...

With a mock like this, the coverage.py code would be unaffected.

Keep in mind: it’s not just coverage.py that could trip over this mock. There could be other libraries used by your code, or you might use open yourself in another part of your product. Mocking the definition means anything using the object will be affected. Your intent is to only mock in one place, so target that place.

Postscript

I decided to add some code to coverage.py to defend against this kind of over-mocking. There is a lot of over-mocking out there, and this problem only shows up in coverage.py with Python 3.14. It’s not happening to many people yet, but it will happen more and more as people start testing with 3.14. I didn’t want to have to answer this question many times, and I didn’t want to force people to fix their mocks.

From a certain perspective, I shouldn’t have to do this. They are in the wrong, not me. But this will reduce the overall friction in the universe. And the fix was really simple:

open = open

This is a top-level statement in my module, so it runs when the module is imported, long before any tests are run. The assignment to open will create a global in my module, using the current value of open, the one found in the builtins. This saves the original open for use in my module later, isolated from how builtins might be changed later.

This is an ad-hoc fix: it only defends one builtin. Mocking other builtins could still break coverage.py. But open is a common one, and this will keep things working smoothly for those cases. And there’s precedent: I’ve already been using a more involved technique to defend against mocking of the os module for ten years.

Even better!

No blog post about mocking is complete without encouraging a number of other best practices, some of which could get you out of the mocking mess:

November 16, 2025 12:55 PM UTC

November 15, 2025


Kay Hayen

Nuitka Release 2.8

This is to inform you about the new stable release of Nuitka. It is the extremely compatible Python compiler, “download now”.

This release adds a ton of new features and corrections.

Bug Fixes

Package Support

New Features

Optimization

Anti-Bloat

Organizational

Tests

Cleanups

Summary

This release was supposed to focus on scalability, but that didn’t happen again due to a variety of important issues coming up as well as a created downtime after high private difficulties after a planned surgery. However, the upcoming release will have it finally.

The onefile DLL mode as used on Windows has driven a lot of need for corrections, some of which are only in the final release, and this is probably the first time it should be usable for everything.

For compatibility, working with the popular (yet - not yes recommended UV-Python), Windows UI fixes for temporary onefile and macOS improvements, as well as improved Android support are excellent.

The next release of Nuitka however will have to focus on scalability and maintenance only. But as usual, not sure if it can happen.

November 15, 2025 01:52 PM UTC

November 14, 2025


Real Python

The Real Python Podcast – Episode #274: Preparing Data Science Projects for Production

How do you prepare your Python data science projects for production? What are the essential tools and techniques to make your code reproducible, organized, and testable? This week on the show, Khuyen Tran from CodeCut discusses her new book, "Production Ready Data Science."


[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]

November 14, 2025 12:00 PM UTC


EuroPython Society

Recognising Michael Foord as an Honorary EuroPython Society Fellow

Hi everyone. Today, we are honoured to announce a very special recognition.

The EuroPython Society has posthumously elected Michael Foord (aka voidspace) as an Honorary EuroPython Society Fellow.


Michael Foord (1974–2025)

Michael was a long-time and deeply influential member of the Python community. He began using Python in 2002, became a Python core developer, and left a lasting mark on the language through his work on unittest and the creation of the mock library. He also started the tradition of the Python Language Summits at PyCon US, and he consistently supported and connected the Python community across Europe and beyond.

However, his legacy extends far beyond code. Many of us first met Michael through his writing and tools, but what stayed with people was the example he set through his contributions, and how he showed up for others. He answered questions with patience, welcomed newcomers, and cared about doing the right thing in small, everyday ways. He made space for people to learn. He helped the Python community in Europe grow stronger and more connected. He made our community feel like a community.

His impact was celebrated widely across the community, with many tributes reflecting his kindness, humour, and dedication:

At EuroPython 2025, we held a memorial and kept a seat for him in the Forum Hall:


A lasting tribute

EuroPython Society Fellows are people whose work and care move our mission forward. By naming Michael an Honorary Fellow, we acknowledge his technical contributions and also the kindness and curiosity that defined his presence among us. We are grateful for the example he set, and we miss him.

Our thoughts and thanks are with Michael&aposs friends, collaborators, and family. His work lives on in our tools. His spirit lives on in how we treat each other.

With gratitude,
Your friends at EuroPython Society

November 14, 2025 09:00 AM UTC

November 13, 2025


Paolo Melchiorre

How to use UUIDv7 in Python, Django and PostgreSQL

Learn how to use UUIDv7 today with stable releases of Python 3.14, Django 5.2 and PostgreSQL 18. A step by step guide showing how to generate UUIDv7 in Python, store them in Django models, use PostgreSQL native functions and build time ordered primary keys without writing SQL.

November 13, 2025 11:00 PM UTC


Python Engineering at Microsoft

Python in Visual Studio Code – November 2025 Release

We’re excited to announce that the November 2025 release of the Python extension for Visual Studio Code is now available!

This release includes the following announcements:

If you’re interested, you can check the full list of improvements in our changelogs for the Python and Pylance extensions.

Add Copilot Hover Summaries as docstring

You can now add your AI-generated documentation directly into your code as a docstring using the new Add as docstring command in Copilot Hover Summaries. When you generate a summary for a function or class, navigate to the symbol definition and hover over it to access the Add as docstring command, which inserts the summary below your cursor formatted as a proper docstring.

This streamlines the process of documenting your code, allowing you to quickly enhance readability and maintainability without retyping.

Add as docstring command in Copilot Hover Summaries

Localized Copilot Hover Summaries

GitHub Copilot Hover Summaries inside Pylance now respect your display language within VS Code. When you invoke an AI-generated summary, you’ll get strings in the language you’ve set for your editor, making it easier to understand the generated documentation.

Copilot Hover Summary generated in Portuguese

Convert wildcard imports into Code Action

Wildcard imports (from module import *) are often discouraged in Python because they can clutter your namespace and make it unclear where names come from, reducing code clarity and maintainability. Pylance now helps you clean up modules that still rely on from module import * via a new Code Action. It replaces the wildcard with the explicit symbols, preserving aliases and keeping the import to a single statement. To try it out, you can click on the line with the wildcard import and press Ctrl + . (or Cmd + . on macOS) to select the Convert to explicit imports Code Action.

Convert wildcard imports Code Action

Debugger support for multiple interpreters via the Python Environments Extension

The Python Debugger extension now leverages the APIs from the Python Environments Extension (vscode-python-debugger#849). When enabled, the debugger can recognize and use different interpreters for each project within a workspace. If you have multiple folders configured as projects—each with its own interpreter – the debugger will now respect these selections and use the interpreter shown in the status bar when debugging.

To enable this functionality, set “python.useEnvironmentsExtension”: true in your user settings. The new API integration is only active when this setting is turned on.

Please report any issues you encounter to the Python Debugger repository.

Other Changes and Enhancements

We have also added small enhancements and fixed issues requested by users that should improve your experience working with Python in Visual Studio Code. Some notable changes include:

We would also like to extend special thanks to this month’s contributors:

Try out these new improvements by downloading the Python extension from the Marketplace, or install them directly from the extensions view in Visual Studio Code (Ctrl + Shift + X or ⌘ + ⇧ + X). You can learn more about Python support in Visual Studio Code in the documentation. If you run into any problems or have suggestions, please file an issue on the Python VS Code GitHub page.

The post Python in Visual Studio Code – November 2025 Release appeared first on Microsoft for Python Developers Blog.

November 13, 2025 06:41 PM UTC

November 12, 2025


Python Software Foundation

Python is for everyone: Join in the PSF year-end fundraiser & membership drive!

The Python Software Foundation (PSF) is the charitable organization behind Python, dedicated to advancing, supporting, and protecting the Python programming language and the community that sustains it. That mission and cause are more than just words we believe in. Our tiny but mighty team works hard to deliver the projects and services that allow Python to be the thriving, independent, community-driven language it is today. Some of what the PSF does includes producing PyCon US, hosting the Python Package Index (PyPI), supporting 5 Developers-in-Residence, maintaining critical community infrastructure, and more.

Python is for teaching, learning, playing, researching, exploring, creating, working– the list goes on and on and on! Support this year's fundraiser with your donations and memberships to help the PSF, the Python community, and the language stay strong and sustainable. Because Python is for everyone, thanks to you.

There are two direct ways to join through donate.python.org

 

>>> Donate or Become a Member Today! <<<

 

If you already donated and/or you’re already a member, you can:

 

Your donations and support:

 

Highlights from 2025:

November 12, 2025 05:03 PM UTC


Real Python

The Python Standard REPL: Try Out Code and Ideas Quickly

The Python standard REPL (Read-Eval-Print Loop) lets you run code interactively, test ideas, and get instant feedback. You start it by running the python command, which opens an interactive shell included in every Python installation.

In this tutorial, you’ll learn how to use the Python REPL to execute code, edit and navigate code history, introspect objects, and customize the REPL for a smoother coding workflow.

By the end of this tutorial, you’ll understand that:

  • You can enter and run simple or compound statements in a REPL session.
  • The implicit _ variable stores the result of the last evaluated expression and can be reused in later expressions.
  • You can reload modules dynamically with importlib.reload() to test updates without restarting the REPL.
  • The modern Python REPL supports auto-indentation, history navigation, syntax highlighting, quick commands, and autocompletion, which improves your user experience.
  • You can customize the REPL with a startup file, color themes, and third-party libraries like Rich for a better experience.

With these skills, you can move beyond just running short code snippets and start using the Python REPL as a flexible environment for testing, debugging, and exploring new ideas.

Get Your Code: Click here to download the free sample code that you’ll use to explore the capabilities of Python’s standard REPL.

Take the Quiz: Test your knowledge with our interactive “The Python Standard REPL: Try Out Code and Ideas Quickly” quiz. You’ll receive a score upon completion to help you track your learning progress:


Interactive Quiz

The Python Standard REPL: Try Out Code and Ideas Quickly

Test your understanding of the Python standard REPL. The Python REPL allows you to run Python code interactively, which is useful for testing new ideas, exploring libraries, refactoring and debugging code, and trying out examples.

Getting to Know the Python Standard REPL

In computer programming, you’ll find two kinds of programming languages: compiled and interpreted languages. Compiled languages like C and C++ have an associated compiler program that converts the language’s code into machine code.

This machine code is typically saved in an executable file. Once you have an executable, you can run your program on any compatible computer system without needing the compiler or the source code.

In contrast, interpreted languages like Python need an interpreter program. This means that you need to have a Python interpreter installed on your computer to run Python code. Some may consider this characteristic a drawback because it can make your code distribution process much more difficult.

However, in Python, having an interpreter offers one significant advantage that comes in handy during your development and testing process. The Python interpreter allows for what’s known as an interactive Read-Eval-Print Loop (REPL), or shell, which reads a piece of code, evaluates it, and then prints the result to the console in a loop.

The Python REPL is a built-in interactive coding playground that you can start by typing python in your terminal. Once in a REPL session, you can run Python code:

Python
>>> "Python!" * 3
Python!Python!Python!
>>> 40 + 2
42

In the REPL, you can use Python as a calculator, but also try any Python code you can think of, and much more! Jump to starting and terminating REPL interactive sessions if you want to get your hands dirty right away, or keep reading to gather more background context first.

Note: In this tutorial, you’ll learn about the CPython standard REPL, which is available in all the installers of this Python distribution. If you don’t have CPython yet, then check out How to Install Python on Your System: A Guide for detailed instructions.

The standard REPL has changed significantly since Python 3.13 was released. Several limitations from earlier versions have been lifted. Throughout this tutorial, version differences are indicated when appropriate.

To dive deeper into the new REPL features, check out these resources:

The Python interpreter can execute Python code in two modes:

  1. Script, or program
  2. Interactive, or REPL

In script mode, you use the interpreter to run a source file—typically a .py file—as an executable program. In this case, Python loads the file’s content and runs the code line by line, following the script or program’s execution flow.

Alternatively, interactive mode is when you launch the interpreter using the python command and use it as a platform to run code that you type in directly.

In this tutorial, you’ll learn how to use the Python standard REPL to run code interactively, which allows you to try ideas and test concepts when using and learning Python. Are you ready to take a closer look at the Python REPL? Keep reading!

What Is Python’s Interactive Shell or REPL?

When you run the Python interpreter in interactive mode, you open an interactive shell, also known as an interactive session. In this shell, your keyboard is the input source, and your screen is the output destination.

Note: In this tutorial, the terms interactive shell, interactive session, interpreter session, and REPL session are used interchangeably.

Here’s how the REPL works: it takes input consisting of Python code, which the interpreter parses and evaluates. Next, the interpreter displays the result on your screen, and the process starts again as a loop.

Read the full article at https://realpython.com/python-repl/ »


[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]

November 12, 2025 02:00 PM UTC


Peter Bengtsson

Using AI to rewrite blog post comments

Using AI to correct and edit blog post comments as part of the moderation process.

November 12, 2025 12:42 PM UTC


Python Morsels

Unnecessary parentheses in Python

Python's ability to use parentheses for grouping can often confuse new Python users into over-using parentheses in ways that they shouldn't be used.

Table of contents

  1. Parentheses can be used for grouping
  2. Python's if statements don't use parentheses
  3. Parentheses can go anywhere
  4. Parentheses for wrapping lines
  5. Parentheses that make statements look like functions
  6. Parentheses can go in lots of places
  7. Use parentheses sometimes
  8. Consider readability when adding or removing parentheses

Parentheses can be used for grouping

Parentheses are used for 3 things in Python: calling callables, creating empty tuples, and grouping.

Functions, classes, and other [callable][] objects can be called with parentheses:

>>> print("I'm calling a function")
I'm calling a function

Empty tuples can be created with parentheses:

>>> empty = ()

Lastly, parentheses can be used for grouping:

>>> 3 * (4 + 7)
33

Sometimes parentheses are necessary to convey the order of execution for an expression. For example, 3 * (4 + 7) is different than 3 * 4 + 7:

>>> 3 * (4 + 7)
33
>>> 3 * 4 + 7
19

Those parentheses around 4 + 7 are for grouping that sub-expression, which changes the meaning of the larger expression.

All confusing and unnecessary uses of parentheses are caused by this third use: grouping parentheses.

Python's if statements don't use parentheses

In JavaScript if statements look …

Read the full article: https://www.pythonmorsels.com/unnecessary-parentheses/

November 12, 2025 03:30 AM UTC


Seth Michael Larson

Blogrolls are the Best(rolls)

Happy 6-year blogiversary to me! 🎉 To celebrate I want to talk about other peoples’ blogs, more specifically the magic of “blogrolls”. Blogrolls are “lists of other sites that you read, are a follower of, or recommend”. Any blog can host a blogroll, or sometimes websites can be one big blogroll.

I’ve hosted a blogroll on my own blog since 2023 and encourage other bloggers to do so. My own blogroll is generated from the list of RSS feeds I subscribe to and articles that I “favorite” within my RSS reader. If you want to be particularly fancy you can add an RSS feed (example) to your blogroll that provides readers a method to “subscribe” for future blogroll updates.

Blogrolls are like catnip for me: I cannot resist opening and Ctrl-clicking every link until I can’t see my tabs anymore. The feeling is akin to the first deep breath of air before starting a hike: there’s a rush of new information, topics, and potential new blogs to follow.

Blogrolls can bridge the “effort chasm” I frequently hear as an issue when I recommend folks try an RSS feed reader. We’re not used to empty feeds anymore; self-curating blogs until you receive multiple articles per day takes time and effort. Blogrolls can help here, especially ones that publish using the importable OPML format.

You can instantly populate your feed reader app with hundreds of feeds from blogs that are likely relevant to you. Simply create an account on a feed reader, import the blogroll OPML document from a blogger you enjoy, and watch the articles “roll” in. Blogrolls are almost like Bluesky “Starter Packs” in this way!

Hopefully this has convinced you to either curate your own blogroll or to start looking for (or asking for!) blogrolls from your favorite writers on the Web. Share your favorite blogroll with me on email or social media. Title inspired by “Hexagons are the Best-agons”.



Thanks for keeping RSS alive! ♥

November 12, 2025 12:00 AM UTC

November 11, 2025


Ahmed Bouchefra

Let’s be honest. There’s a huge gap between writing code that works and writing code that’s actually good. It’s the number one thing that separates a junior developer from a senior, and it’s something a surprising number of us never really learn.

If you’re serious about your craft, you’ve probably felt this. You build something, it functions, but deep down you know it’s brittle. You’re afraid to touch it a year from now.

Today, we’re going to bridge that gap. I’m going to walk you through eight design principles that are the bedrock of professional, production-level code. This isn’t about fancy algorithms; it’s about a mindset. A way of thinking that prepares your code for the future.

And hey, if you want a cheat sheet with all these principles plus the code examples I’m referencing, you can get it for free. Just sign up for my newsletter from the link in the description, and I’ll send it right over.

Ready? Let’s dive in.

1. Cohesion & Single Responsibility

This sounds academic, but it’s simple: every piece of code should have one job, and one reason to change.

High cohesion means you group related things together. A function does one thing. A class has one core responsibility. A module contains related classes.

Think about a UserManager class. A junior dev might cram everything in there: validating user input, saving the user to the database, sending a welcome email, and logging the activity. At first glance, it looks fine. But what happens when you want to change your database? Or swap your email service? You have to rip apart this massive, god-like class. It’s a nightmare.

The senior approach? Break it up. You’d have:

Then, your main UserService class delegates the work to these other, specialized classes. Yes, it’s more files. It looks like overkill for a small project. I get it. But this is systems-level thinking. You’re anticipating future changes and making them easy. You can now swap out the database logic or the email provider without touching the core user service. That’s powerful.

2. Encapsulation & Abstraction

This is all about hiding the messy details. You want to expose the behavior of your code, not the raw data.

Imagine a simple BankAccount class. The naive way is to just have public attributes like balance and transactions. What could go wrong? Well, another developer (or you, on a Monday morning) could accidentally set the balance to a negative number. Or set the transactions list to a string. Chaos.

The solution is to protect your internal state. In Python, we use a leading underscore (e.g., _balance) as a signal: “Hey, this is internal. Please don’t touch it directly.”

Instead of letting people mess with the data, you provide methods: deposit(), withdraw(), get_balance(). Inside these methods, you can add protective logic. The deposit() method can check for negative amounts. The withdraw() method can check for sufficient funds.

The user of your class doesn’t need to know how it all works inside. They just need to know they can call deposit(), and it will just work. You’ve hidden the complexity and provided a simple, safe interface.

3. Loose Coupling & Modularity

Coupling is how tightly connected your code components are. You want them to be as loosely coupled as possible. A change in one part shouldn’t send a ripple effect of breakages across the entire system.

Let’s go back to that email example. A tightly coupled OrderProcessor might create an instance of EmailSender directly inside itself. Now, that OrderProcessor is forever tied to that specific EmailSender class. What if you want to send an SMS instead? You have to change the OrderProcessor code.

The loosely coupled way is to rely on an “interface,” or what Python calls an Abstract Base Class (ABC). You define a generic Notifier class that says, “Anything that wants to be a notifier must have a send() method.”

Then, your OrderProcessor just asks for a Notifier object. It doesn’t care if it’s an EmailNotifier or an SmsNotifier or a CarrierPigeonNotifier. As long as the object you give it has a send() method, it will work. You’ve decoupled the OrderProcessor from the specific implementation of the notification. You can swap them in and out interchangeably.


A quick pause. I want to thank boot.dev for sponsoring this discussion. It’s an online platform for backend development that’s way more interactive than just watching videos. You learn Python and Go by building real projects, right in your browser. It’s gamified, so you level up and unlock content, which is surprisingly addictive. The core content is free, and with the code techwithtim, you get 25% off the annual plan. It’s a great way to put these principles into practice. Now, back to it.

4. Reusability & Extensibility

This one’s a question you should always ask yourself: Can I add new functionality without editing existing code?

Think of a ReportGenerator function that has a giant if/elif/else block to handle different formats: if format == 'text', elif format == 'csv', elif format == 'html'. To add a JSON format, you have to go in and add another elif. This is not extensible.

The better way is, again, to use an abstract class. Create a ReportFormatter interface with a format() method. Then create separate classes: TextFormatter, CsvFormatter, HtmlFormatter, each with their own format() logic.

Your ReportGenerator now just takes any ReportFormatter object and calls its format() method. Want to add JSON support? You just create a new JsonFormatter class. You don’t have to touch the ReportGenerator at all. It’s extensible without being modified.

5. Portability

This is the one everyone forgets. Will your code work on a different machine? On Linux instead of Windows? Without some weird version of C++ installed?

The most common mistake I see is hardcoding file paths. If you write C:\Users\Ahmed\data\input.txt, that code is now guaranteed to fail on every other computer in the world.

The solution is to use libraries like Python’s os and pathlib to build paths dynamically. And for things like API keys, database URLs, and other environment-specific settings, use environment variables. Don’t hardcode them! Create a .env file and load them at runtime. This makes your code portable and secure.

6. Defensibility

Write your code as if an idiot is going to use it. Because someday, that idiot will be you.

This means validating all inputs. Sanitizing data. Setting safe default values. Ask yourself, “What’s the worst that could happen if someone provides bad input?” and then guard against it.

In a payment processor, don’t have debug_mode=True as the default. Don’t set the maximum retries to 100. Don’t forget a timeout. These are unsafe defaults.

And for the love of all that is holy, validate your inputs! Don’t just assume the amount is a number or that the account_number is valid. Check it. Raise clear errors if it’s wrong. Protect your system from bad data.

7. Maintainability & Testability

The most expensive part of software isn’t writing it; it’s maintaining it. And you can’t maintain what you can’t test.

Code that is easy to test is, by default, more maintainable.

Look at a complex calculate function that parses an expression, performs the math, handles errors, and writes to a log file all at once. How do you even begin to test that? There are a million edge cases.

The answer is to break it down. Have a separate OperationParser. Have simple add, subtract, multiply functions. Each of these small, pure components is incredibly easy to test. Your main calculate function then becomes a simple coordinator of these tested components.

8. Simplicity (KISS, DRY, YAGNI)

Finally, after all that, the highest goal is simplicity.

Phew, that was a lot. But these patterns are what it takes to level up. It’s a shift from just getting things done to building things that last.

If you enjoyed this, let me know. I’d love to make more advanced videos like this one. See you in the next one.

November 11, 2025 09:03 PM UTC


PyCoder’s Weekly

Issue #708: Debugging Live Code, NiceGUI, Textual, and More (Nov. 11, 2025)

#708 – NOVEMBER 11, 2025
View in Browser »

The PyCoder’s Weekly Logo


Debugging Live Code With CPython 3.14

Python 3.14 added new capabilities to attach to and debug a running process. Learn what this means for debugging and examining your running code.
SURISTER

NiceGUI Goes 3.0

Talk Python interviews Rodja Trappe and Falko Schindler, creators of the NiceGUI toolkit. They talk about what it can do and how it works.
TALK PYTHON

AI Code Reviews Without the Noise

alt

Sentry’s AI Code Review has caught more than 30,000 bugs before they hit production. 🤯 What it hasn’t caught: about a million spammy style nitpicks. Plus, it now predicts bugs 50% faster, and provides agent prompts to automate your fixes. Learn more about Sentry’s AI Code Review →
SENTRY sponsor

Building UIs in the Terminal With Python Textual

Learn to build rich, interactive terminal UIs in Python with Textual: a powerful library for modern, event-driven TUIs.
REAL PYTHON course

PEP 810: Explicit Lazy Imports (Accepted)

PYTHON.ORG

PEP 791: math.integer — submodule for integer-specific mathematics functions (Final)

PYTHON.ORG

PyCon US, Long Beach CA, 2026: Call for Proposals Open

PYCON.BLOGSPOT.COM

Django Security Release: 5.2.8, 5.1.14, and 4.2.26

DJANGO SOFTWARE FOUNDATION

EuroPython 2025 Videos Available

YOUTUBE.COM video

Python Jobs

Python Video Course Instructor (Anywhere)

Real Python

Python Tutorial Writer (Anywhere)

Real Python

More Python Jobs >>>

Articles & Tutorials

How Often Does Python Allocate?

How often does Python allocate? The answer is “very often”. This post demonstrates how you can see that for yourself. See also the associated HN discussion
ZACK RADISIC

Improving Security and Integrity of Python Package Archives

Python packages are built on top of archive formats like ZIP which can be problematic as features of the format can be abused. A recent white paper outlines dangers to PyPI and what can be done about it.
PYTHON SOFTWARE FOUNDATION

The 2025 AI Stack, Unpacked

alt

Temporal’s industry report explores how teams like Snap, Descript, and ZoomInfo are building production-ready AI systems, including what’s working, what’s breaking, and what’s next. Download today to see how your stack compares →
TEMPORAL sponsor

10 Smart Performance Hacks for Faster Python Code

Some practical optimization hacks, from data structures to built-in modules, that boost speed, reduce overhead, and keep your Python code clean.
DIDO GRIGOROV

Understanding the PSF’s Current Financial Outlook

A summary of the Python Software Foundation’s current financial outlook and what that means to the variety of community groups it supports.
PYTHON SOFTWARE FOUNDATION

__dict__: Where Python Stores Attributes

Most Python objects store their attributes in a __dict__ dictionary. Modules and classes always use __dict__, but not everything does.
TREY HUNNER

My Favorite Django Packages

A descriptive list of Mattias’s favorite Django packages divided into areas, including core helpers, data structures, CMS, PDFs, and more.
MATTHIAS KESTENHOLZ

A Close Look at a FastAPI Example Application

Set up an example FastAPI app, add path and query parameters, and handle CRUD operations with Pydantic for clean, validated endpoints.
REAL PYTHON

Quiz: A Close Look at a FastAPI Example Application

Practice FastAPI basics with path parameters, request bodies, async endpoints, and CORS. Build confidence to design and test simple Python web APIs.
REAL PYTHON

An Annual Release Cycle for Django

Carlton wants Django to move to an annual release cycle. This post explains why he thinks this way and what the benefits might be.
CARLTON GIBSON

Behave: ML Tests With Behavior-Driven Development

This walkthrough shows how to use the Behave library to bring behavior-driven testing to data and machine learning Python projects.
CODECUT.AI • Shared by Khuyen Tran

Polars and Pandas: Working With the Data-Frame

This post compares the syntax of Polars and pandas with a quick peek at the changes coming in pandas 3.0.
JUMPINGRIVERS.COM • Shared by Aida Gjoka

Projects & Code

moneyflow: Personal Finance Data Interface for Power Users

GITHUB.COM/WESM

wove: Beautiful Python Async

GITHUB.COM/CURVEDINF

tiny8: A Tiny CPU Simulator Written in Python

GITHUB.COM/SQL-HKR

FuncToWeb: Transform Pythons Function Into a Web Interface

GITHUB.COM/OFFERRALL

dj-spinners: Pure SVG Loading Spinners for Django

GITHUB.COM/ADAMGHILL

Events

Weekly Real Python Office Hours Q&A (Virtual)

November 12, 2025
REALPYTHON.COM

Python Leiden User Group

November 13, 2025
PYTHONLEIDEN.NL

Python Kino-Barcamp Südost

November 14 to November 17, 2025
BARCAMPS.EU

Python Atlanta

November 14, 2025
MEETUP.COM

PyCon Wroclaw 2025

November 15 to November 16, 2025
PYCONWROCLAW.COM

PyCon Ireland 2025

November 15 to November 17, 2025
PYCON.IE


Happy Pythoning!
This was PyCoder’s Weekly Issue #708.
View in Browser »

alt

[ Subscribe to 🐍 PyCoder’s Weekly 💌 – Get the best Python news, articles, and tutorials delivered to your inbox once a week >> Click here to learn more ]

November 11, 2025 07:30 PM UTC


Daniel Roy Greenfeld

Visiting Tokyo, Japan from November 12 to 24

I'm excited to announce that me and Audrey will be visiting Japan from November 12 to November 24, 2025! This will be our first time in Japan, and we can't wait to explore Tokyo. Yes, we'll be in Tokyo for most of it, near the Shinjuku area, working from coffee shops, meeting some colleagues, and exploring the city during our free time. Our six year old daughter is with us, so our explorations will be family-friendly.

Unfortunately, we'll be between Python meetups in the Tokyo area. However, if you are in Toyo and write software in any shape or form, and would like to get together for coffee or a meal, please let me know!

If you do Brazilian Jiu-Jitsu in Tokyo, please let me know as well! I'd love to drop by a gym while I'm there.

November 11, 2025 02:45 PM UTC


Real Python

Python Operators and Expressions

Python operators enable you to perform computations by combining objects and operators into expressions. Understanding Python operators is essential for manipulating data effectively.

This video course covers arithmetic, comparison, Boolean, identity, membership, bitwise, concatenation, and repetition operators, along with augmented assignment operators. You’ll also learn how to build expressions using these operators and explore operator precedence to understand the order of operations in complex expressions.

By the end of this video course, you’ll understand that:


[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]

November 11, 2025 02:00 PM UTC