skip to navigation
skip to content

Planet Python

Last update: May 19, 2026 01:44 PM UTC

May 19, 2026


Real Python

Quiz: Absolute vs Relative Imports in Python

In this quiz, you’ll test your understanding of Absolute vs Relative Imports in Python.

By working through this quiz, you’ll revisit how Python’s import system resolves modules, the differences between absolute and relative imports, and the PEP 8 conventions for styling import statements.


[ 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 ]

May 19, 2026 12:00 PM UTC

Quiz: Tapping Into the Zen of Python

In this quiz, you’ll test your understanding of Tapping Into the Zen of Python.

By working through this quiz, you’ll revisit the origins of the poem, the meaning of several aphorisms, and the inside jokes hidden throughout.

The questions explore how the principles apply in practice and when it’s okay to bend the rules in the name of practicality.


[ 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 ]

May 19, 2026 12:00 PM UTC


PyCharm

LLM Evaluation and AI Observability for Agent Monitoring

This is a guest post from Naa Ashiorkor, a data scientist and tech community builder.

Artificial intelligence keeps evolving at a rapid pace. The latest major application of AI, specifically of LLMs, is AI agents. These are systems that use their perception of their environment, processes, and input to take action to achieve specific goals, and they are built on LLMs. 

Increasingly, complex AI agents are being used in real-world applications. While simpler agentic applications that use only one agent to achieve a goal still exist, organizations are now shifting towards multi-agent systems that use multiple subagents coordinated by a main agent. These are more adaptable and can mimic human teams when it comes to performing specialized tasks such as data analysis, compliance, customer support, and more. The reasoning and autonomy of AI agents have improved; consequently, they can gather data, conduct cross-references, and generate analysis.

As we move towards these complex, real-world applications of agents, an ever-stronger spotlight is being shone both on how we observe AI agents and how we evaluate the LLMs they’re built upon. The complexity, interactions, and autonomous processes under the surface of AI agents make rigorous monitoring and assessment an essential part of building and maintaining these applications. LLM evaluation determines if the AI agent can work, while AI agent observability determines if it is working. LLM evaluation tests an agent’s basic capabilities before and during deployment, while agent observability provides deep, real-time visibility into an agent’s internal reasoning and operational health once it is live. It is pretty obvious that having just one of these is a loss and a formula for failure. 

In this blog post, we’ll explore how to evaluate agents using advanced metrics and observability tools. It’s designed as a practical, end-to-end reference for teams that want to move beyond demos and actually run AI agents in live, real-world environments, avoiding the common pitfalls that cause failure in production.

Core LLM evaluation metrics for modern AI systems

As LLMs are now applied to a wide range of use cases, it is important that their evaluation covers both the tasks they may perform and their potential risks. Evaluation metrics give a better understanding of the strengths and weaknesses of LLMs, influence the guidance of human-LLM interactions, and highlight the importance of ensuring LLM safety and reliability. Hence, LLM evaluation metrics for assessing the performance of an LLM are indispensable in modern AI systems. Without well-defined evaluation metrics, assessing model quality becomes subjective. 

There are several key evaluation metrics, each with a different purpose, and the table below provides a summary of some of them.

Evaluation MetricWhat the metric evaluates
Hallucination rateFactual accuracy and truthfulness of generated content
Toxicity scoresHarmful, offensive, or inappropriate content
RAGAS (Retrieval Augmented Generation Assessment)Measures whether the RAG system retrieves the right documents and generates answers that are faithful to those sources
DeepEvalTests everything from basic accuracy and safety to complex agent behaviors and security vulnerabilities across the entire LLM application

Hallucination rate

Hallucinations in LLMs produce outputs that seem convincing yet are factually unsupported and can be categorized as either intrinsic, where the output contradicts the source content, or extrinsic, where it simply cannot be verified. They can stem from a range of factors across data, training, and inference, from quality issues in the large datasets used for initial training and the data used to fine-tune model behavior to post-training techniques that make models overly eager to provide responses to imperfect decoding strategies at inference. Because hallucination is an unsolved challenge cutting across every stage of model development, measuring and assessing it remains a vital part of LLM evaluation.

There is a wide variety of techniques for detecting hallucinations. These include: 

There are several metrics for hallucination detection. Some of the most commonly used metrics include:

PyCharm’s Hugging Face integration lets you discover evaluation models and datasets without leaving the IDE. Use the Insert HF Model feature to search for hallucination or toxicity classifiers, and hover over any model or dataset name in your code to instantly preview its model card, including training data, intended use, and limitations. This means you can import a dataset, evaluate your LLM, and verify the tools you’re using, all from one place.

PyCharm's Hugging Face integrationOpening the Hugging Face model browser in PyCharm from the Code menu, then selecting Insert HF Model. PyCharm's Searching for a specific hallucination model and selecting one. Use Model inserts a ready-to-use code snippet into the editor. PyCharm's A ready-to-use code snippet of the Vectara hallucination evaluation model is inserted into the editor. Vectara hallucination evaluation modelHovering over the Vectara hallucination evaluation model in the code to preview its model card within PyCharm.

Trust is imperative in the acceptance and adoption of technology. Trust in AI is especially important in areas such as healthcare, finance, personal assistance, autonomous vehicles, and others. Hallucinations have a huge impact on users’ trust in LLMs.

In 2023, a story went viral about a Manhattan lawyer who submitted a legal brief largely generated by ChatGPT. The judge quickly noticed how different it was from a human-written submission, revealing clear signs of hallucination. Incidents like this highlight the real-world risks of LLM errors and their impact on user trust. As people encounter more examples of hallucination, skepticism around LLM reliability continues to grow.

Toxicity scores

LLMs that have been pretrained on large datasets from the web have the tendency to generate harmful, offensive, and disrespectful content as well as toxic language, such as hate speech, harassment, threats, and biased language, which have a negative impact on their safe deployment. Toxicity detection is the process of identifying and flagging toxic content by integrating open-source tools or APIs into the LLM workflow to analyze both the user input and the LLM output. Some of the available toxicity tools include the OpenAI Moderation API, which is free, works with any text, and has a quick implementation. Perspective API by Google is also widely used with a transparent methodology, but will no longer be in service after 2026. Detoxify, which is open source, has no API costs, and is Python-friendly, and Azure AI Content Safety by Microsoft, which is customizable and best for enterprise deployments and existing Azure users. Hugging Face Toxicity Models have many model options and easy integration with Transformers.

Toxicity detection has become a guardrail; hence, it is important in public-facing applications. They prevent toxic content from reaching users, which protects both individuals and organizations. In public-facing applications, toxicity detection operates by input filtering, output monitoring, and real-time scoring. This prevents attacks where users intentionally train AI to produce toxic content through coordinated toxic inputs; toxic content will never reach the user, even if produced by the underlying AI, so systems can adjust their behavior dynamically based on conversation content and escalating risks. Unguarded AI can be exploited, which leads to reputational damage. 

For toxicity evaluation, PyCharm’s Hugging Face Insert HF Model feature helps you discover classifiers like s-nlp/roberta_toxicity_classifier directly in the IDE. Hovering over the model name reveals its model card, where you can see it was trained on the Jigsaw toxic comment datasets, helping you understand what the model can and can’t detect before you write a single line of evaluation code. 

PyCharm's Hugging Face Insert HF Model featureOpening the Hugging Face model browser in PyCharm from the Code menu, then selecting the Insert HF Model. PyCharm's Searching for a specific toxicity model and selecting one. Use Model inserts a ready-to-use code snippet into the editor. A ready-to-use code snippet of the roberta_toxicity_classifier is inserted into the editor. Hovering over the roberta_toxicity_classifier in the code to preview its model card within PyCharm.

Frameworks for LLM evaluation

Frameworks for LLM evaluation have changed the game; teams don’t have to rely on manual reviews, gut instinct, and subjective judgment to assess model quality. These frameworks automate the measurement of model quality using standardized, quantifiable metrics. They assign numerical scores to outputs that measure faithfulness, relevancy, toxicity, and other important dimensions. This automation results in reproducibility, speed, and objectivity. 

Consequently, the same input always produces the same score; evaluation runs 10–100 times faster, so in minutes instead of days; and there are no more debates on the quality of the output. Some of these frameworks include DeepEval and Retrieval Augmented Generation Assessment (Ragas). DeepEval is an open-source evaluation framework built with seven principles in mind, such as the ability to easily “unit test” LLM outputs in a similar way to Pytest and plug in and use over 50 LLM-evaluated metrics, most of which are backed by research and all of which are multimodal. 

It is extremely easy to build and iterate on LLM applications with two modes of evaluation, namely, end-to-end LLM evals and component-level LLM evals. It is used for comprehensive testing across RAG, agents, and chatbots. Ragas is a framework for reference-free evaluation of RAG pipelines. There are several dimensions to consider, such as the ability of the retrieval system to identify relevant and focused context passages, as well as the capability of the LLM to exploit such passages in a faithful way; hence, it is challenging to evaluate RAG systems. Ragas provides a suite of metrics for evaluating these dimensions without relying on ground-truth human annotations. 

The limits of static prompt evaluation

Traditional LLM evaluation methods are useful for single prompt-response pairs, measuring output quality, RAG systems with straightforward retrieval, and static evaluation with fixed inputs. But they are limited for multi-step agents because LLM evaluation focuses on the final output quality, not the decision-making process that produced it. Multi-step agents exhibit a different kind of complexity, as they chain multiple decisions.

Why traditional LLM evaluation isn’t enough for agents 

Agents operate independently within complex workflows, and this independence can introduce challenges such as deviation from expected behavior, errors in production, and more failure points than in traditional software applications. Hence, an agent can perform well in testing but fail in production. Traditional LLM evaluations don’t have the capacity to test such use cases. Testing is usually done in a controlled environment with limited scenarios, but production involves real users, edge cases, unpredictable inputs, and scale. This means that agents can make decisions that are not seen in testing, and in production, tasks could be completed, though incorrectly, without generating an error signal. This is where advanced evaluation and monitoring practices come to the rescue! They provide the visibility and systematic measurement needed to deploy agents confidently, rather than relying on trial and error.

The complexity of agent behavior

Traditional LLM evaluation measures single prompt-response pairs: provide an input prompt, receive an output response, and measure quality through metrics such as accuracy, relevance, and faithfulness. Due to the complexity and non-deterministic, multi-step reasoning of AI agents, they cannot be reliably evaluated using traditional evaluation metrics.

Agent behavior is complex, and this complexity introduces challenges. Agents operate in dynamic environments where APIs might be down, databases change between queries, and the “right” answer depends on current conditions. They can use external tools and APIs to complete tasks, and may either use the wrong tool or use the right tool with the wrong parameters or input type. Their internal reasoning traces remain hidden unless they are logged explicitly, so it might be challenging to determine whether an agent was successful through logic or chance. An agent’s output could be perfectly correct despite poor internal decisions, or the entire task could fail despite correct step execution.

This is where observability tooling becomes essential. PyCharm’s AI Agents Debugger breaks open the black box of agentic systems, letting you trace LangGraph workflows and inspect each agent node’s inputs, outputs, and reasoning directly in the IDE, with zero extra code. Just install the plugin, run your agent, and the debugger automatically captures execution traces. Click the Graph button to visualize the full workflow, making it easy to spot where an agent chose the wrong tool, passed bad parameters, or succeeded by luck rather than logic.

To see this in action, I built a simple travel-planning agent using LangGraph in two steps: a research node that suggests summer destinations based on my preferences, and a plan node that picks the best option and builds a three-day itinerary. With the AI Agents Debugger, you can trace exactly what information flowed between these two steps – what the research node suggested and how the planner used those suggestions to build the final itinerary.

The AI Agents Debugger shows how the agent moves from initialization to the research stage, displaying the data passed in and out, and the LLM call used to generate the research results. The AI Agents Debugger shows how the planning step processes inputs and produces outputs, using an LLM call to construct the final travel itinerary. The Graph viewprovides a high-level overview of the agent’s workflow, mapping how it progresses from the initial step through research and planning to the final result.

Advanced agent evaluation metrics

The complexity of AI agents demands evaluation that goes beyond considering the final output quality, that is, measuring whether it is accurate, relevant, and grounded. Specialized agent evaluation assesses the complete decision-making process, including the planning logic, tool selection, parameter construction, reasoning coherence, and resource efficiency that led to the final output. Hence, the advanced agent evaluation metrics are designed to make such a process visible and measurable. Some of them are task completion rate, tool usage, reasoning quality, efficiency, and error handling.

Task completion rate

Task completion rate measures the percentage of tasks where an agent successfully achieves the end goal. This is calculated as the number of completed tasks divided by the total number of tasks attempted. The context of “completed” differs by use case. There are real-world use cases for task completion rate. Let’s start with a basic use case. Consider a customer service agent handling a specific food delivery order: “Where is my order #0001? It has not been delivered to me.” Completion rate means successfully looking up the order ID, retrieving the tracking information, and providing an accurate delivery estimate, so all three steps must succeed. If the agent retrieves the wrong order or fails to assess the tracking system, that is a failed task, even if it produces the same output. 

Next, let us look at a medium-complexity use case, sequential API calls. Consider an agent tasked with creating a Jira support ticket and notifying the relevant team in Slack. The agent calls the Jira API to create a ticket, parses the response to get the ticket ID, calls the Slack API with the ticket link, and finally verifies the success of both. If the agent successfully creates the Jira ticket, but the Slack notification fails, that is considered a failed task even if the ticket exists in Jira, since the team wasn’t notified. 

Finally, let’s examine a high-complexity use case: An agent is given the task of completing an online purchase, which means it must handle everything from checkout to order confirmation. Six steps are involved: Verify the item is still in stock, process the payment with a credit or debit card, reserve or decrement inventory, create an order record, generate an order confirmation number, and send a confirmation email to the customer. If the agent successfully charges the customer’s card but the confirmation email fails to send, that’s a failed task, even if the payment was processed and the order was created. In such a situation, the customer has no proof of purchase, so they will likely contact support or attempt to purchase again.

Tool usage correctness

Tool usage correctness assesses whether an agent correctly identifies and invokes the relevant tools and APIs. It is a deterministic measure that is assessed using techniques such as LLM as a judge, like most LLM evaluation metrics. It has three dimensions: 

Hence, it is important for reliability and functional correctness. 

Step-by-step reasoning accuracy

In real-world use cases, an LLM agent’s reasoning is shaped by much more than just the model itself. Modern frameworks such as LangChain expose the agent’s internal “thoughts” through structured logging of intermediate reasoning steps. This is done using the ReAct (Reasoning and Acting) pattern, which involves the agent thinking about what to do, using a tool, observing the tool result, and then repeating until the task is complete. Each “thought” is logged as text, which creates a complete trace of the reasoning process from initial query to final answer. These traces can be extracted programmatically and evaluated to assess whether the agent’s logic is sound even when the final output appears correct. Evaluating planning steps involves assessing aspects such as the overall approach’s logic, the ordering of steps, and whether any steps are unnecessary or redundant. Evaluating execution assesses whether the implementation worked, such as whether tools were called with correct parameters, whether each step was completed successfully, whether errors were handled appropriately, and whether the output was interpreted correctly. This can be done seamlessly in PyCharm using the AI Agents Debugger.

Groundedness (faithfulness)

Groundedness, also known as faithfulness, is the most critical metric for retrieval-augmented generation (RAG), which is a common component of agentic applications. It assesses whether the agent’s response is actually supported by the retrieved source documents or whether, instead, the model hallucinated information. Different evaluation techniques include:

AI observability and why it matters

AI observability is about visibility into what the agent is doing. This covers recording everything that happens when a task is executed, including the agent’s reasoning at each step, which tools were called with what parameters, what data was retrieved, and how decisions were made from start to finish. With such a transparent system where every decision can be logged and traced, teams are able to understand why an agent fails, behaves unexpectedly, or becomes expensive to run because issues can be debugged and behavior can be audited. Consequently, system design improves, and guesswork is eliminated.

Definition of AI observability

AI observability is the real-time monitoring of agent actions, thoughts, and environmental interactions: what went in, what came out, how the agent thought through the problem, and which tools, APIs, and data were used. AI observability builds on the three pillars of DevOps observability – that is, metrics, logs, and traces – but extends each one for AI’s unique needs. DevOps metrics track CPU and latency, while AI metrics track token usage and cost per interaction. DevOps logs capture system errors, while AI logs capture reasoning traces and decision points. DevOps traces follow requests through services, while AI traces follow reasoning through agent steps, tool calls, and observations.

Benefits for agent monitoring

Agent monitoring has immense benefits – here are some of the most important:

Popular tools for agent monitoring

Several frameworks and platforms have emerged to provide built-in observability for AI agents, with each having different strengths and integration approaches and matching different features and requirements. The choice of the right tool depends on the framework, deployment preferences, and primary needs. The table below shows some popular tools and whether they match different features and requirements.

ToolTraces agent steps?Tracks costs?Detects regressions? Self-hostable?Open source?Easy integration?
HeliconeYesYesYesYesYesYes
LangSmithYesYesYesLimitedNoYes
LangFuseYesYesYesYesYesModerate
OpenLLMetryYesLimitedLimitedYesYesModerate
PhoenixYesLimitedYesYesYesModerate
TruLensYesLimitedYesYesYesModerate
DataDogLimitedYesYesNoNoModerate

Best practices for evaluating agents in production

Evaluation does not end after deployment; rather, it is intensified. This continuous evaluation tracks how much the system costs to run, how quickly it responds under various loads, and how it handles errors or unusual inputs. Without such evaluation, problems can only be identified after the users are affected. An agent can pass all the quality checks with excellent faithfulness scores, high completion rates, and strong reasoning but fail in production if costs spiral, latency increases, or edge cases cause instability. Hence, there is a critical need for ongoing evaluation and monitoring, which will lead to systems that are reliable, scalable, and financially sustainable.

Monitor cost and latency

Monitoring cost and latency is critical for production sustainability. Token usage and response time must be tracked continuously because small inefficiencies compound dramatically over time, and the cost per token of the powerful reasoning models used for agents can be high. Production workloads require cost and latency monitoring to identify problems before user experience and budget are impacted. Cost monitoring tracks token usage at different levels, such as per request, per query type, and over time. Without visibility into patterns generated by these, teams end up discovering cost problems through surprise bills. With monitoring, they can proactively cache common queries and optimize prompts to reduce token use. Latency monitoring reveals track response time and component breakdowns to identify bottlenecks.

Cost control in production workloads is important because production costs can spiral quickly, unmonitored systems can exceed budgets, and latency impacts user experience and retention.

Combine offline and online evaluation

Effective agent evaluation requires combining offline and online evaluation, where each addresses gaps the other leaves. Offline evaluation uses fixed test databases for reproducible benchmarking, which enables fast iteration on prompts and models in controlled environments without production risk. Online evaluation monitors real user interactions in production, which reveals edge cases in testing that were never expected, so it is useful for real-time feedback, user data, and observability tools. A combination of both results in an optimal strategy where offline evaluation validates changes before deployment, then online evaluation monitors production reality. 

Use human-in-the-loop when necessary

LLM agents are appreciated for how they have played a positive role in the different ecosystems, but not every agent should run autonomously since they can misinterpret prompts, cross boundaries, or make dreadful errors that can’t be caught by automation alone. Hence, the need for human-in-the-loop failsafes. Human-in-the-loop is also essential during initial setup: Unless teams already have domain-specific evaluation datasets for monitoring the agent, these will need to be created manually by assessing the agent’s performance. A hybrid approach is required when critical decisions require human validation, such as approving transactions, modifying sensitive data, or triggering irreversible workflows. In this approach, it is important that decisions are routed through a human checkpoint before proceeding. The intention is not to slow automation but rather to ensure that the right decisions involve the right oversight. A well-designed human-in-the-loop system delivers compound returns over time. Every human correction becomes feedback, which improves the agent’s accuracy and gradually reduces the need for manual review. Human oversight isn’t treated as a failure but rather as a safety net that makes the system better with use.

Final thoughts

Fundamentally, AI agents are different from single-prompt LLMs. They navigate multi-step workflows, make autonomous decisions, and use external tools, which introduces complexities that demand continuous evaluation, not just static testing. Evaluation must evolve from pre-deployment checkpoints to ongoing monitoring. Production-ready agents aren’t just well-tested; they’re continuously observed and improved based on real behavior. LLM evaluation and AI observability enable faster, safer iteration by catching issues early and feeding production insights back into development.

PyCharm streamlines agent development with integrated debugging, profiling, and testing. Step through reasoning with breakpoints, find cost bottlenecks, and iterate on evaluation tests rapidly. These workflows transform hours of debugging into minutes of systematic investigation. Explore PyCharm for AI development to see how integrated tools can help you build, evaluate, and deploy reliable AI agents.

About the author

Naa Ashiorkor

Naa Ashiorkor is a data scientist and tech community builder. She is deeply involved in the Python community and serves as an organizer for various conferences, including EuroPython. She is currently building PyLadies Tampere.

May 19, 2026 09:46 AM UTC

May 18, 2026


Ari Lamstein

How Remote Work Has Grown — and Shrunk — Since Covid

Remote work surged during Covid — and while it has declined since, it’s still far above pre‑pandemic levels. I just updated my Covid Demographics Explorer with the latest ACS data, and the national trend is striking:

Remote work more than tripled between 2019 and 2021, rising to nearly 28 million people at the height of the pandemic. Since then it has edged down each year, but only modestly. Even today, at about 22 million, it remains roughly 2.5 times the pre‑Covid level.

The app now lets you generate this same graph for every state, as well as for counties and cities with populations of at least 65,000. See how the trend looks where you live.

Exploring Local Trends

I also added a “Compare Years” tab that lets you see which locations saw the biggest change in remote work between any two years. The national trend tells one story, but the local data tells another: the rise and fall of remote work played out very unevenly across the country. Below I run this analysis twice: first for the national increase from 2019-2021, and then for the gradual decline between 2021 and 2024.

The Remote Work Spike: 2019-2021

Between 2019 and 2021, the location that increased the number of remote workers the most was Sunnyvale, California. The number of remote workers there increased almost 11x in two years, from an estimated 3,235 to 38,319. Sunnyvale is in the heart of Silicon Valley, and tech companies were among the fastest to adopt remote work, which helps explain this result:

The scatterplot also shows the broader pattern: most locations cluster between a 150% and 300% increase in remote work during this period. That makes Sunnyvale’s nearly 1,100% jump stand out even more — it’s an order of magnitude beyond the national norm.

Interestingly, only one location in the entire dataset saw a decrease in remote work during this period: Rice County, Minnesota (-7.5%). It’s the lone point below zero on the chart, and I don’t have a clear explanation for it.

The Remote Work Decline: 2021-2024

When we run this same analysis for 2021–2024, we see a very different result: Sunnyvale’s remote workforce shrank by 67.2%, the largest drop in the dataset. This means that Sunnyvale saw both the largest increase between 2019 and 2021 and the largest decrease between 2021 and 2024:

The scatterplot also shows how different the overall pattern is in this period. Instead of large increases, most locations cluster between a 10% and 30% decline in remote work — a sharp contrast with the 2019–2021 graph, where nearly every location saw a substantial increase.

Against this backdrop, Sunnyvale’s 67% drop stands out as an outlier. The likely explanation is the wave of return‑to‑office mandates that swept through the tech industry during this period. The two other largest decreases also happened in Silicon Valley: the city of Fremont (–61%) and Santa Clara County (–56%).

At the other end of the distribution, the few places that saw increases tend to be warm‑weather, high‑amenity destinations: Marion County, Florida (69%), Collier County, Florida (65%), and Maui County, Hawaii (57%) saw the largest gains. These increases may reflect people with remote‑work jobs relocating to places with natural beauty and a high quality of life — a very different dynamic from the employer‑driven declines we see in Silicon Valley.

Conclusion

Three years after the peak, roughly 22 million Americans still work from home — more than double the pre-pandemic baseline. But the story is more complex than a single national number: a dramatic surge, an uneven retreat, and striking differences across the country. How does your corner of the country fit in?

The new version of the Covid Demographics Explorer makes it easy to explore these patterns yourself. In addition to remote‑work trends, you can examine changes in population, median household income, median rent, and public assistance. Analyze your own location.

This app was built in Python with the Streamlit framework. I teach Streamlit for O’Reilly — and if you’d like to learn to build apps like this yourself, I offer a free 7-day email course. Sign up in the form below.

May 18, 2026 08:00 PM UTC


Real Python

Python Built-in Functions: A Complete Guide

Python’s built-in functions are predefined functions you can use anywhere in your code without any imports. They handle common tasks across math, data type creation, iterable processing, and input and output. Knowing which ones to reach for makes your code shorter and more Pythonic.

In this tutorial, you’ll:

  • Recognize Python’s built-in functions and the built-in scope they live in
  • Use the right built-in for math, data types, iterables, and I/O tasks
  • Tell apart true functions and classes that look like functions
  • Apply built-ins to solve practical problems without reinventing the wheel

To get the most out of this tutorial, you’ll need to be familiar with Python programming, including topics like working with built-in data types, functions, classes, decorators, scopes, and the import system.

Get Your Code: Click here to download the free sample code that shows you how to use Python’s built-in functions.

Get the PDF Guide: Click here to download a free PDF guide that gives you a complete overview of Python’s built-in functions and how to use them.

Take the Quiz: Test your knowledge with our interactive “Python Built-in Functions: A Complete Guide” quiz. You’ll receive a score upon completion to help you track your learning progress:


Interactive Quiz

Python Built-in Functions: A Complete Guide

Test your understanding of Python's built-in functions for math, data types, iterables, and I/O—and when to reach for each one.

Built-in Functions in Python

Python has several functions available for you to use directly from anywhere in your code. These functions are known as built-in functions and they cover many common programming problems, from mathematical computations to Python-specific features.

Note: All these functions live in the builtins module, which Python loads at startup and exposes through the built-in scope, so you can use them anywhere without importing the module. Importing the module explicitly is useful if you know that you’ll shadow a built-in name with one of your own variables or functions. Doing so keeps the original within reach as builtins.name.

Among these built-ins, you’ll also find classes with function-style names like str, tuple, list, and dict, which define built-in data types. These classes are listed in the Python documentation as built-in functions, so they’re covered in this tutorial too.

In this tutorial, you’ll learn the basics of Python’s built-in functions. By the end, you’ll know what their use cases are and how they work. You’ll start with the built-in functions for math computations.

In Python, you’ll find a few built-in functions that take care of common math operations, like computing the absolute value of a number, calculating powers, and more. Here’s a summary of the math-related built-in functions in Python:

Function Description
abs() Calculates the absolute value of a number
divmod() Computes the quotient and remainder of integer division
max() Finds the largest of the given arguments or items in an iterable
min() Finds the smallest of the given arguments or items in an iterable
pow() Raises a number to a power
round() Rounds a floating-point value
sum() Sums the values in an iterable

In the following sections, you’ll learn how these functions work and how to use them in your Python code.

Getting the Absolute Value of a Number: abs()

The absolute value or modulus of a real number is its non-negative value. In other words, the absolute value is the number without its sign. For example, the absolute value of -5 is 5, and the absolute value of 5 is also 5.

Note: To learn more about abs(), check out the How to Find an Absolute Value in Python tutorial.

Python’s built-in abs() function allows you to quickly compute the absolute value of a number. Here’s its signature:

Language: Python Syntax
abs(number)

The number argument can be any numeric value, including integers, floating-point numbers, complex numbers, fractions, and decimals. Take a look at a few examples:

Language: Python
>>> from decimal import Decimal
>>> from fractions import Fraction

>>> abs(-42)
42
>>> abs(42)
42

>>> abs(-42.42)
42.42
>>> abs(42.42)
42.42

>>> abs(complex("-2+3j"))
3.605551275463989
>>> abs(complex("2+3j"))
3.605551275463989

>>> abs(Fraction("-1/2"))
Fraction(1, 2)
>>> abs(Fraction("1/2"))
Fraction(1, 2)

>>> abs(Decimal("-0.5"))
Decimal('0.5')
>>> abs(Decimal("0.5"))
Decimal('0.5')

In these examples, you compute the absolute value of different numeric types using the abs() function. First, you use integer numbers, then floating-point and complex numbers, and finally, fractional and decimal numbers. In all cases, when you call the function with a negative value, the final result removes the sign.

For a practical example, say that you need to compute the total profits and losses of your company from a month’s transactions:

Language: Python
>>> transactions = [-200, 300, -100, 500]

>>> incomes = sum(income for income in transactions if income > 0)
>>> expenses = abs(
...     sum(expense for expense in transactions if expense < 0)
... )

>>> print(f"Total incomes: ${incomes}")
Total incomes: $800
>>> print(f"Total expenses: ${expenses}")
Total expenses: $300
>>> print(f"Total profit: ${incomes - expenses}")
Total profit: $500

Read the full article at https://realpython.com/python-built-in-functions/ »


[ 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 ]

May 18, 2026 02:00 PM UTC


Python Bytes

#480 Proud Parents

<strong>Topics covered in this episode:</strong><br> <ul> <li><strong><a href="https://www.better-simple.com/django/2026/05/06/using-django-tasks-in-production/?featured_on=pythonbytes">Using Django Tasks in production</a></strong></li> <li><strong>Co-authored with Claude?</strong></li> <li><strong><a href="https://rushter.com/blog/pypi-packages/?featured_on=pythonbytes">PyPI packages are increasing rapidly</a></strong></li> <li><strong><a href="https://tildeweb.nl/~michiel/httpx2.html?featured_on=pythonbytes">httpx2</a></strong></li> <li><strong>Extras</strong></li> <li><strong>Joke</strong></li> </ul><a href='https://www.youtube.com/watch?v=-x1R3S72gCU' style='font-weight: bold;'data-umami-event="Livestream-Past" data-umami-event-episode="480">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> <strong>Connect with the hosts</strong></li> <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) 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 11am PT. Older video versions available there too. 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.</li> </ul> <p><strong>Brian #1: <a href="https://www.better-simple.com/django/2026/05/06/using-django-tasks-in-production/?featured_on=pythonbytes">Using Django Tasks in production</a></strong></p> <ul> <li>Tim Schilling shares how the Djangonaut Space website has been using Django’s new tasks framework and some of the info missing from the official Django docs.</li> <li>Tasks require a third party package, <a href="https://github.com/RealOrangeOne/django-tasks-db?featured_on=pythonbytes"><code>django-tasks-db</code></a> to actually run the tasks.</li> <li>Article walks through all changes necessary to get an email process running to notify admins of new testimonials. Cool simple example.</li> <li>With the db backend, you can monitor progress of tasks in the admin, to see which tasks are scheduled, completed, or have errors.</li> <li>Some wishes for the community to implement <ul> <li>new tutorial in the Django docs</li> <li>Django Debug toolbar panel for tasks</li> <li>test/mock backend</li> </ul></li> <li>Great title for wish list: Thinks I’d like to see, but I’m too lazy to implement myself.</li> </ul> <p><strong>Michael #2: Co-authored with Claude?</strong></p> <ul> <li>Via Nik T.</li> <li>We don’t put “executed on macOS”, “edited with PyCharm”, etc. in our commits. Why Claude?</li> <li>Seems like a growth hack to me, that I don’t really care to participate in.</li> <li>Some projects that have formalized their thoughts on this: <a href="https://redmonk.com/kholterhoff/2026/02/26/generative-ai-policy-landscape-in-open-source/?featured_on=pythonbytes">The Generative AI Policy Landscape in Open Source</a></li> <li>Adjust to turn off in <code>~/.claude/settings.json</code> see <a href="https://code.claude.com/docs/en/settings#attribution-settings">the docs</a>. <div class="codehilite"> <pre><span></span><code><span class="p">{</span> <span class="w"> </span><span class="nt">&quot;attribution&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">{</span> <span class="w"> </span><span class="nt">&quot;commit&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="w"> </span><span class="nt">&quot;pr&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;&quot;</span> <span class="w"> </span><span class="p">}</span> <span class="p">}</span> </code></pre> </div></li> </ul> <p><strong>Brian #3: <a href="https://rushter.com/blog/pypi-packages/?featured_on=pythonbytes">PyPI packages are increasing rapidly</a></strong></p> <ul> <li>Artem Golubin</li> <li>There’s been an increase of published packages per week on PyPI</li> <li>A pretty big increase in the last handful of months.</li> <li>30% increase since 2025, clearly due to AI</li> <li>Artem is building <a href="https://github.com/rushter/hexora?featured_on=pythonbytes">hexora</a>, a malicious Python code detector.</li> <li>Cool package too, it can: <ul> <li>Audit project dependencies to catch potential supply-chain attacks</li> <li>Detect malicious scripts found on platforms like Pastebin, GitHub, or open directories</li> <li>Analyze IoC files from past security incidents</li> <li>Audit new packages uploaded to PyPi.</li> </ul></li> <li>Artem is using hexora to analyze recently published pypi packages and many are obviously vibecoded and trigger false positives for abuses of <code>eval</code>, <code>exec</code>, and <code>subprocess</code> <ul> <li>Side note: I don’t think that’s necessarily a false positive. Not malicious, but maybe a stupid-code-detector?</li> </ul></li> <li>Lots are LLM related, Lots have bots contributing code</li> <li>Publishing rate is crazy, dozens to hundreds of published versions in a day is a bug, not a feature</li> <li>Brian’s proposal, PyPI should limit releases per day for any package to something a sane human would do, even if they make a mistake on a release, to maybe like 2-3, definitely under 10, in a day. And if the repo has obvious agent contributors listed, maybe lower to the limit to 1-2 a day? Honestly, “move fast and break things” doesn’t apply to breaking the commons.</li> </ul> <p><strong>Michael #4: <a href="https://tildeweb.nl/~michiel/httpx2.html?featured_on=pythonbytes">httpx2</a></strong></p> <ul> <li>More on the httpx, httpxyz, etc changes: Pydantic people started their own fork, <a href="https://github.com/pydantic/httpx2?featured_on=pythonbytes">httpx2</a>.</li> <li>Michiel says “while we think httpxyz was definitely needed, we welcome httpx2 and think it should be the ‘blessed’ fork.”</li> <li>Kludex, who is among other things maintainer of Starlette, was considering a fork</li> <li>As it stands, httpx2 is lacking the performance improvements they added to httpxyz. But it will not be long before they will add those, too.</li> <li>Also they already made some smart decisions: <ul> <li>they are switching from certifi to <a href="https://github.com/pydantic/httpx2/pull/209?featured_on=pythonbytes">truststore</a></li> <li>they are switching to <a href="https://github.com/pydantic/httpx2/pull/933?featured_on=pythonbytes">compression.zstd</a> on Python 3.14+, enabling zstd compression by default</li> <li>they <a href="https://github.com/pydantic/httpx2/commit/160c7f59d7942efe0133516c161d39139780eb45?featured_on=pythonbytes">merged httpcore</a> and vendored it in their repository</li> </ul></li> <li><a href="https://news.ycombinator.com/item?id=48127570&featured_on=pythonbytes">Discussion on Hacker News</a></li> </ul> <p><strong>Extras</strong></p> <p>Brian:</p> <ul> <li><a href="https://anarc.at/blog/2026-05-16-four-horsemen/?featured_on=pythonbytes">The Four Horsemen of the LLM Apocalypse</a> - Anarcat</li> <li><a href="https://www.djangoproject.com/weblog/2026/may/12/2026-django-developers-survey/?featured_on=pythonbytes">Django/JetBrains 2026 developer survey</a> is open</li> <li><a href="https://pyrefly.org/blog/v1.0/?featured_on=pythonbytes">Pyrefly 1.0</a> : “meaning we are confident that Pyrefly is ready for production use.” Michael:</li> <li>Just about ready to release Python Web Security: OWASP Top 10 with Agentic AI course. Be sure to be on <a href="https://training.talkpython.fm/getnotified?featured_on=pythonbytes">the courses newsletter</a> to get notified.</li> </ul> <p><strong>Joke:</strong> <a href="https://x.com/PR0GRAMMERHUM0R/status/1973145866962665752?featured_on=pythonbytes">Proud Parents</a></p>

May 18, 2026 08:00 AM UTC

May 17, 2026


Artem Golubin

PyPI packages are increasing rapidly

PyPI is the main repository for Python packages. One thing that I've noticed recently is the number of published packages per week.

Let's look at published counts of new package versions per week:

There are some dips in the data, but that's because of how the data was collected. We can see a clear increase in the number of published packages, especially in the last few months.

Because of AI, the number of packages published per week has increased by 30% since 2025.

I'm working on hexora, a library that detects malicious Python code in packages.[......]

May 17, 2026 01:37 PM UTC

May 16, 2026


Kay Hayen

Nuitka Release 4.1

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

This release adds many new features and corrections with a focus on async code compatibility, missing generics features, and Python 3.14 compatibility and Python compilation scalability yet again.

Bug Fixes

Package Support

New Features

Optimization

Anti-Bloat

Organizational

Tests

Cleanups

Summary

This release builds on the scalability improvements established in 4.0, with enhanced Python 3.14 support, expanded package compatibility, and significant optimization work.

The --project option seems usable now.

Python 3.14 support remains experimental, but only barely made the cut, and probably will get there in hotfixes. Some of the corrections came in so late before the release, that it was just not possible to feel good about declaring it fully supported just yet.

May 16, 2026 10:00 PM UTC


PyCon

Welcome Back, NVIDIA: Visionary Sponsor of PyCon US 2026

NVIDIA is excited to once again support PyCon US 2026 as a Visionary Sponsor, and to sponsor the Future of AI with Python Conference Track.

Python is a “first-class” language at NVIDIA CUDA, and NVIDIA is committed to bringing our technology to Python developers in close alignment with C++ upon new releases of our hardware. We’re also happy to announce the general availability of CUDA Python 1.0.

NVIDIA’s commitment to Python goes well beyond just our own tech stack. NVIDIA’s Python engineers contribute across a broad swath of the Python ecosystem, from the core interpreter itself, to packaging and PyPI, to the Python community at large. NVIDIA is inspired by the energy of, and privileged to collaborate with, people across the open source Python community.

Since PyCon last year, NVIDIA Pythonistas – in collaboration with many others in the Python community – have made great progress on the evolution of various packaging standards, including working with community partners on the implementation of wheel variants and the establishment of a Packaging Council to better govern the evolution of packaging standards and PyPI. NVIDIA Python engineers are also engaged in implementation, testing, and porting work for the free-threaded build of the interpreter. NVIDIA Python engineers are driving the early exploratory work for adopting Rust for CPython, work on Python performance benchmarking, and are actively involved in many enhancements for Python 3.14 and 3.15, including providing built-in Zstandard support in Python 3.14.

At NVIDIA, we are excited to work with our partners and the open source Python community to help bring the best developer experience for users of high performance computing and AI. Come see NVIDIA at the Anaconda and PyTorch booths, and at the AI Track.

Barry Warsaw
May 2026
Principal System Software Engineer, NVIDIA
Python Core Developer since 1994
Python Steering Council member in 2026

May 16, 2026 02:30 PM UTC

May 15, 2026


Anarcat

The Four Horsemen of the LLM Apocalypse

I have been battling Large Language Models (LLM1) for the past couple of weeks and have struggled to think about what it means and how to deal with its fallout.

Because the fight has come from many fronts, I've come to articulate this in terms of the Four Horsemen of the Apocalypse.

Sound track: Metallica's The Four Horsemen, preferably downloaded from Napster around 2000, but now I guess you get it on YouTube.

War: bot armies

Let's start with War. We've been battling bot armies for control of our GitLab server for a while. Bots crawl virtually infinite endpoints on our Git repositories (as opposed to downloading an archive or shallow clone), including our fork of Firefox, Tor Browser, a massive repository.

At first, we've tried various methods: robots.txt, blocking user agents, and finally blocking entire networks. I wrote asncounter. It worked for a while.

But now, blocking entire networks doesn't work: they come back some other way, typically through shady proxy networks, which is kind of ironic considering we're essentially running the largest proxy network of the world.

Out of desperation, we've forced users to use cookies when visiting our site. We haven't deployed Anubis yet, as we worry that bots have broken Anubis anyways and that it does not really defend against a well-funded attacker, something which Pretix warned against in 2025 already.

(We have a whole discussion regarding those tools here.)

But even that, predictably, has failed. I suspect what we consider bots are now really agents. They run full web browsers, JavaScript included, so a feeble cookie is no match for the massive bot armies.

Side note on LLM "order of battle"

We often underestimate the size of that army. The cloud was huge even before LLMs, serving about two thirds of the web. Even larger swaths of clients like government and corporate databases have all moved to the cloud, in shared, but private infrastructure with massive spare capacity that is readily available to anyone who pays.

LLMs have made the problem worse by dramatically expanding the capacity of the "cloud". We now have data centers that defy imagination with millions of cores, petabytes of memory, exabytes of storage.

I thought that 25 gigabit residential internet in Switzerland could bring balance, but this is nothing compared to the scale of those data centers.

Those companies can launch thousands, if not millions of fully functional web browsers at our servers. Computing power or bandwidth are not a limitation for them, our primitive infrastructure is. No one but hyperscalers can deal with this kind of load, and I suspect that they are also struggling, as even Google is deploying extreme mechanisms in reCAPTCHA.

This is the largest attack on the internet since the Morris worm but while Robert Tappan Morris went to jail on a felony, LLM companies are celebrated as innovators and will soon be too big to fail.2

Which brings us to the second horsemen, famine.

Famine: shortages

All that computing power doesn't come out of thin air: it needs massive amounts of hardware, power, and cooling.

Earlier this year, I've heard from a colleague that their Dell supplier refused to even provide a quote before August. Dell!

In February, Western Digital's hard drive production for 2026 was already sold out. Hard drives essentially doubled in price within a year, and some have now tripled. A server quote we had in November has now quadrupled, going from 10 thousand to FORTY thousand dollars for a single server.

But regular folks are facing real-life shortages as well, as city-size data centers are being built at neck-breaking speed, stealing fresh water and energy from human beings to feed the war machine.

We've been scared of losing our jobs, but it seems that Apocalypse has yet to fully materialize. Regardless for engineers, the market feels tighter than it was a couple years ago, and everyone feels on edge that they will just have to learn to operate LLMs to keep their jobs.

Which brings us, of course, to Death.

Death: security and copyright

Our third horseman is one I did not expect a couple of months ago. Back at FOSDEM, curl's maintainer Daniel Stenberg famously complained about the poor quality of LLM-generated reports but then, a few months later, everyone is scrambling to deal with floods of good reports.

In the past two weeks, this culminated in a significant number of critical security issues across multiple projects. Chained together, remote code execution vulnerabilities in Nginx and Apache and two local privilege escalations in the Linux kernel (dirtyfrag and fragnesia) essentially gave anyone root access to any unpatched server to the web.

As I write this, another vulnerability dropped, which gives read access to any file to a local user, compromising TLS and SSH private keys.

All those vulnerabilities were released without any significant coordination while people scrambled to mitigate.

Many people including Linus Torvalds are now considering issues discovered through LLMs to be essentially public. This puts some debates about disclosure processes in perspective, to say the least.

But this is not merely the death of the traditional coordinated disclosure process, the C programming language, or the Linux kernel: remember that those bots are trained on a large corpus of copyrighted material. Facebook has trained their models on pirated books and Nvidia has done deals with Anna's Archive to secure access to large swaths of copyrighted material. The US Congress seems to think LLM outputs are not copyrightable, like any other machine outputs.

With many people now vibe coding their way out of learning or remembering how computers work, is this the Death of Copyright?

And that, of course, brings us to the final horseman: Pestilence.

Pestilence: slop

There is a growing meme that programming is essentially over as we know it. That you can simply vibe-code applications from scratch and it's pretty good.

Maybe that's true.

So far, most of my attempts at resolving any complex problem with a LLM have often failed with bizarre failures. Some worked surprisingly well. Maybe, of course, I am holding it wrong.

I personally don't believe LLMs will ever be good enough to produce and maintain software at scale. They're surprisingly good at finding security flaws right now. But what I see is also a lot of Bullshit, with a capital B. It's not lying: it does not "know" anything, so it can't lie. It's misleadingly cohesive and deliberate, but it lacks meaning, intent, will.

I have not been confronted with much slop, apart from the lobster Jesus or the yellow man atrocities, and particularly not in my work. But I see what it is doing to my profession: beyond vibe-coding, people are now token-maxxing, and land-grabbing their colleagues.

I don't like what LLMs do to our communities, or the fabric of software we live with.

Software does not evolve in a void. It is a team effort, be it free software or a corporate product. Generations of humans have carefully built the scaffolding of technology required for modern networks and software to operate, in a convoluted contraption that no single human fully understands anymore.

The idea of simply giving up on that understanding entirely and delegating it to an unproven model is not only chilling, it feels just plain stupid. Not stupid as in Skynet, stupid as in "I can't get inside the data center because the authentication system is down". Except we're in a "the power plant doesn't reboot" or "their LLM found an 0day in our slop" kind of stupid.

The fifth horsemen

Researching for this article, I looked up the four horsemen and found out they original seems to have been:

I was surprised. I grew up thinking about the horsemen being Famine, War, Pestilence, and Death. So I went back to my original source which actually claims the horsemen are:

Time has taken its toll on you, the lines that crack your face.
Famine, your body, it has torn through, withered in every place.
Pestilence for what you've had to endure, and what you have put others through
Death, deliverance for you, for sure, now there's nothing you can do

So I guess that makes no sense either, which, fair enough, I shouldn't rely on Metallica for theological references. Especially since that song was originally called Mechanix and was "about having sex at a gas station".

Anyways.

The point is, there are actually five horsemen, and the fifth one is, in my opinion, Conquest.

Those companies (and not "AI", mind you) are taking over the world. I sense a strong connection with the "post-truth" world imposed on us by fascists like Trump and Putin. It's not an accident, it's a power grab part of the Californian Ideology3. Just like Airbnb broke housing, Uber destroyed the transportation and Amazon is taking over retail and server hosting, LLM companies are essentially trying to take over if not everything, at least Cognition as a whole.

But the capitalization of those companies (OpenAI and Nvidia in particular) are so far beyond reason that their inevitable collapse will likely lead to a global financial collapse of biblical proportions.

Because they will inevitably fail like previous bubbles they are built on. And when they fail, I hope it zips all the way back through the blockchain scam, the ad surveillance system, and the dot com then git me back my internet.

The Tower of Babel

While I'm off in the woods hallucinating (ha!) on biblical allegories, I feel there's another sign that the apocalypse is coming.

The Tower of Babel myth says that humans tried to create a big tower up to heaven and become god. God confounds their speech and scatters the human race. End of utopia.

This is what is happening to our human translators now. LLMs being, after all, Language Models, they are excellent at translation work. So much that the only translators not replaced by LLMs right now are interpreters, who translate vocally in real time. But interpreters are worried about their jobs as well.

This concretely means we will lose the human capacity, as a civilization, to translate between each other. It is still an open question whether the remaining revision work will be enough for translators to avoid deskilling, but other research has shown that LLM use leads to cognitive decline, impacts critical thinking, and generally, that deskilling is a common outcome.

Ultimately, I think this is where LLMs bring us. Towards collapse.

So this is a call to arms. Fight back!

Poison bots. Build local real-world communities.

Go low tech. Moore's law is dead, make use of it.

Patch your shit. Go weird.

Refuse slop. Train your brain.

The horsemen will collapse, but let's not go down with them.

Butlerian Jihad!

This article was written without the use of a large language model and should not be used to train one.


  1. I prefer "LLM" to Artificial Intelligence, as I don't consider models to have "Intelligence" which goes far beyond the analytical traits we train models for. Intelligence requires embodiment and social interaction; machines lack the innate human skills of empathy, feeling and care, which explains a lot of the evils behind the current trends.
  2. It should be noted that Morris also happened to be one of the founder of Y Combinator where he is in good company with other techno-fascists like Peter Thiel, Sam Altman, and so on. Crime, after all, pays.
  3. Probably a good time to watch All Watched Over by Machines of Loving Grace.

May 15, 2026 09:25 PM UTC


PyCharm

Pyrefly LSP Integration with Type Engine in PyCharm 2026.1.2

In PyCharm 2026.1.2, you can enable Pyrefly as an external type provider, dramatically increasing the speed of the IDE’s code insight features.

What is the Pyrefly LSP?

“LSP” stands for the Language Server Protocol – a standardized protocol that allows code editors and IDEs to communicate with language servers. The LSP enables language servers to provide code intelligence features, such as:

The key benefit of the LSP is that it allows a single language server to be used across multiple tools. This means that language-specific intelligence does not have to be implemented separately in every editor, IDE, or CI pipeline.

Pyrefly is Meta’s next-generation Python type checker, engineered from the ground up in Rust to replace its predecessor, Pyre (written in OCaml). With the move to Rust, Pyrefly achieves significantly faster performance and improved cross-platform portability. More than just a rewrite, it is designed to be more capable and robust, offering an efficient toolset for maintaining large-scale Python codebases with high precision and minimal overhead.

Pyrefly provides the following benefits:

Pyrefly is highly beneficial for projects and developers dealing with large, complex Python codebases that prioritize performance and robust typing. Integrating Pyrefly via the LSP is part of our ongoing work to enhance code insight performance in PyCharm.

Using Pyrefly in PyCharm

Once enabled, Pyrefly powers all code insight functionality in PyCharm, including type inference and type-related diagnostics, quick documentation, and inlay hints. Delegating analysis to this faster engine delivers significantly improved performance.

To start using Pyrefly in your PyCharm project, go to the Type widget at the bottom of the window. By default, the IDE uses the built-in type engine. Click on the widget and select the option to use Pyrefly. If you do not have Pyrefly installed yet, PyCharm will install it automatically. 

Once you’ve switched to the Pyrefly type engine, you will see a Pyrefly icon at the bottom, which you can hover over to check the version being used.

Please note that the integration currently works for local interpreter configurations. Support for Docker, Docker Compose, WSL, SSH, and multi-module projects is planned for future releases.

Pyrefly vs. the built-in type engine

Now let’s look at how Pyrefly and the built-in type engine behave in a complex Python project. In this FastAPI example, multiple files are typed, but in this file, the variable ref is incorrectly typed, causing four errors. When using the built-in type engine, the IDE identifies that something is wrong, but it suggests running further analysis to fix the problem, which requires an extra step.

Using Pyrefly as the type engine, the IDE reports errors immediately and highlights where they originate. However, it is worth noting that, in our example, there are four errors, but Pyrefly picks up only three of them. It misses the one in self._storage[ref].

Download the latest version of PyCharm and try it out

Ready to experience a dramatic leap in Python development performance? The Pyrefly type engine in PyCharm 2026.1.2 delivers the next generation of type checking. Engineered in Rust for unparalleled speed, it resolves files in as little as 0.5–1 seconds, significantly faster than the built-in engine. If you maintain large, complex Python codebases and prioritize robust typing, this feature is essential, as it allows you to delegate analysis to a faster engine and receive immediate type-related diagnostics. Download the latest version of PyCharm (2026.1.2) to unlock superior efficiency, scalability, and code insight.

May 15, 2026 03:31 PM UTC


Real Python

The Real Python Podcast – Episode #295: Agentic Architecture: Why Files Aren't Always Enough

What are the limitations of using a file-based agent workflow? Why do massive context windows tend to collapse? This week on the show, Mikiko Bazeley from MongoDB joins us to discuss agentic architecture and context engineering.


[ 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 ]

May 15, 2026 12:00 PM UTC

Quiz: Python's Array: Working With Numeric Data Efficiently

In this quiz, you’ll test your understanding of Python’s Array: Working With Numeric Data Efficiently.

By working through this quiz, you’ll revisit the differences between Python’s array module and the built-in list, the meaning of type codes, how to create and manipulate arrays as mutable sequences, and the performance trade-offs of using a low-level numeric container.


[ 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 ]

May 15, 2026 12:00 PM UTC


EuroPython

May Newsletter: Sessions, Speakers, Sprints

Hi all Pythonistas! 👋 

Hope you’ve been enjoying these last few weeks, and hopefully planning your trip to Kraków in July! With two months left before the conference, the EuroPython organising team has been firing on all cylinders to create a conference to remember. Here’s the latest from us:

📋 Session and Speaker Lists Are Available

Our Programme Team is busy preparing a detailed schedule for you. We plan to release it in the upcoming days, but in the meantime we’ve got the list of sessions and speakers for you to check out. It’s going to be an exciting conference!

altLists of sessions and speakers are available at https://ep2026.europython.eu/

👉 All conference sessions: https://ep2026.europython.eu/sessions/

👉 Speakers and tutorial leads: https://ep2026.europython.eu/speakers/ 

🗻 Language & Rust Summits

Summits are an opportunity for project contributors to come together during EuroPython. These are invite-only events with limited capacity at the venue, so registration is required.

🐍 Language Summit

The Python Language Summit is an event for the developers of Python implementations (CPython, PyPy, MicroPython, GraalPython, IronPython, and so on) to share information, discuss our shared problems, and — hopefully — solve them.

These issues might be related to the language itself, the standard library, the development process, the status of Python 3.15 (and plans for 3.16), the documentation, packaging, the website, and so forth. The Summit focuses on discussions and consensus-seeking, more than merely on presentations.

👉 Register for the Language Summit: https://ep2026.europython.eu/language-summit/

⚙️ Rust Summit

This full-day summit is dedicated to exploring the intersection of Rust and the Python ecosystem. Attendees can expect an intensive schedule focused specifically on integrating Rust into Python projects and the development of high-performance Python tools (e.g., using technologies like PyO3, Maturin, or writing performant native extensions). 

This summit is designed for developers who already possess some practical experience in these topics and are looking to deepen their expertise, share lessons learned, and contribute to the community&aposs collective knowledge.

👉 Register for the Rust Summit: https://ep2026.europython.eu/session/rust-summit-at-europython

🗣️ Keynote Speakers

We are excited to announce a new keynote: 

Cover image of Leah Wasser, Executive Director and Founder of pyOpenSci, as a keynoter at EuroPythonLeah Wasser will deliver a keynote at EuroPython 2026

Leah Wasser is the Executive Director and founder of pyOpenSci, a community of 400+ researchers, engineers, and maintainers working to make developing and maintaining research software more accessible, sustainable, and human. She organizes the Maintainers Summit at PyCon US and believes the communities behind research software matter as much as the code itself.

Leah has built nationally recognized programs at the National Ecological Observatory Network (NEON) and the University of Colorado Boulder. Leah holds a PhD in ecology and is an active open source maintainer.

✋ Upcoming Call for Volunteers

We&aposre opening our Call for Volunteers next week! Want to be part of the team and help make EuroPython 2026 awesome? Keep an eye on the website, the signup form drops in just a few days. We&aposll be reviewing applications on a rolling basis, so don&apost wait – apply as soon as it goes live! Whether you&aposre a first-timer or a returning volunteer, we&aposd love to have you.

In my opinion, volunteering enriches the enjoyment of the whole event even further. There are many different roles to suit different personalities and abilities — one of them could suit you very well. Also, volunteering is about the team; you will not be left alone in any case.

Jake Balas, Onsite Volunteers Team Lead at EuroPython 2025 and this year’s Operations Team Lead

💙 Read our full interview with Jake https://blog.europython.eu/humans-of-ep-jake/

💰 Sponsorship: Diamond, Platinum, Silver Available 

If you&aposre passionate about supporting EuroPython and helping make this conference accessible to a diverse, global Python community, consider becoming a sponsor or asking your employer to join us in this effort.

By sponsoring EuroPython, you’re not just backing an event – you&aposre gaining highly targeted visibility that will present your company or personal brand to one of the largest and most diverse Python communities in the world! Here’s what one of our sponsors said about their experience at EuroPython 2025:

The Apify team shares their experience sponsoring EuroPython 2025

We still have some Diamond, Platinum, and Silver slots available. Along with our main packages, there are optional add-ons and extras to craft your brand messaging in exactly the way that you need. 

👉 More information at: https://ep2026.europython.eu/sponsorship/sponsor/ 

👉 Contact us at sponsoring@europython.eu

🚧 Speaker Orientation

Anyone interested in receiving speaker training from our experienced mentors is invited to an online workshop on the 3rd June 2026, at 18:00 CEST. We’ve designed the session for people of all experience levels, from first time speakers to seasoned presenters, and we still have spots for you.

👉 Register now to confirm your place: https://forms.gle/uZKwuAiBkUSmx7gn7

🤝 Community Partners

🇪🇸PyConES 

Barcelona is calling, Pythonistas! PyConES 2026 has extended its CFP. New deadline: 17 May, 23:59 CEST. If you’re still thinking about submitting a talk, workshop, or idea to the community which will meet up in that gorgeous city, you have last days.

👉 Submit the proposal for PyConES 2026 https://pretalx.com/pycones-2026/cfp 

🦬PyStok

PyStok #82 meetup lands on 20 May, 18:00 at Zmiana Klimatu in Białystok, Poland, and free registration is officially live. Grab your spot at https://pystok.org/najblizsze-wydarzenie to dive deep into RAG/LLM Wiki and the PLLuM (Polish Large Language Model) project. Between the "speed dating" networking, JetBrains giveaways and the legendary "Podlaskie afterparty", it’s the perfect spot to soak up those unique North-East Polish vibes and talk Python and AI with the local crowd.

📣 Community Outreach

🏖️PyCon US

Several members of the EuroPython Society have traveled across the ocean to join the biggest gathering of Pythonistas, which this year takes place in Long Beach, California. If you’re there this weekend, make sure to look up the EuroPython booth and say “hi” to the team!

🎁 Sponsor Spotlight

We&aposd like to thank Manychat for sponsoring EuroPython.

Manychat builds AI-powered chat automation for 1M+ creators and brands at real production scale.

altView job openings at Manychat

👋 Stay Connected

Follow us on social media and subscribe to our newsletter for all the updates:

👉 Sign up for the newsletter: https://blog.europython.eu/portal/signup

We’ll be announcing more keynotes in the upcoming days, and the detailed schedule will be available soon, so you can plan your conference experience. Just eight weeks are left before we all meet in the City of Castles and Dragons. See you there! 🐍❤️

Cheers,

The EuroPython Team

May 15, 2026 06:00 AM UTC

May 14, 2026


Real Python

Quiz: Cursor vs Windsurf: Which AI Code Editor Is Best for Python?

In this quiz, you’ll test your understanding of Cursor vs Windsurf: Which AI Code Editor Is Best for Python?

By working through these questions, you’ll revisit how the two editors differ across code completion, agentic multi-file editing, and debugging.

You’ll also reconnect with the audit points worth applying whenever an AI agent writes Python on your behalf.


[ 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 ]

May 14, 2026 12:00 PM UTC

Quiz: Python Metaclasses

In this quiz, you’ll test your understanding of Python Metaclasses.

Metaclasses sit behind every class you write in Python, and they’re one of the language’s deeper object-oriented concepts. By working through this quiz, you’ll revisit how classes are themselves objects, how type creates them, and how a custom metaclass lets you customize class creation.

You’ll also reflect on when a custom metaclass is actually the right tool and when a simpler technique does the job better.


[ 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 ]

May 14, 2026 12:00 PM UTC


Python Engineering at Microsoft

PyCon US 2026

Come See Us at PyCon US 2026!

Microsoft and GitHub will be at PyCon US 2026, May 14–17 in Long Beach, CA. Stop by our booth, say hello, and tell us about your experience with our tools and services. We’d love to meet you.

Don’t miss the Meta booth on Saturday at 1 p.m., where we’ll be showing off the integration of Pylance with Meta’s new Pyrefly type checker. The integration is currently in early preview in our Insiders build, and we can’t wait to bring it to all our users later this year.

Hands-on Labs at the Booth

Drop in for 10-minute interactive labs covering:

Talks and Sessions

Date & Time Room Session Speaker
Wed, May 13 · 9:00 a.m.–12:30 p.m. 101A Build your first MCP server in Python Pamela Fox
Wed, May 13 · 1:30 p.m.–2:30 p.m. 201B Dungeons and Databases: Build NPC agents to work with data in DocumentDB and Postgres (Microsoft Sponsor session) Marko Hotti, Patty Chow
Thu, May 14 · 2:40 p.m.–3:05 p.m. 104C Education Summit: Big Lessons from Small Models, Teaching Python AI with SLMs Gwyneth Peña-Siguenza
Thu, May 14 · 3:40 p.m.–4:05 p.m. 104C Education Summit: Your Slides, But Faster, Building an AI-powered presentation workflow Pamela Fox
Fri, May 15 · 3:30 p.m.–4:00 p.m. 104C PyCharlas: CĂłmo pasĂ© de perdida a enseñar Python + IA a miles, en un año Gwyneth Peña-Siguenza
Sat, May 16 · 2:30 p.m.–3:45 p.m. 201A Maintainer Summit Tools Track: Dev Containers Sarah Kaiser
Sun, May 17 · 1:00 p.m.–1:30 p.m. Grand Ballroom A A bridge over (not) troubled waters: Collecting marine data from your couch Sarah Kaiser

Can’t wait to see you there!

The post PyCon US 2026 appeared first on Microsoft for Python Developers Blog.

May 14, 2026 12:18 AM UTC


Bob Belderbos

Learn agentic AI in Python with 10 small exercises

Most "build an AI agent" tutorials hand you a framework and skip the part where you actually understand what it's doing under the hood. When the abstraction breaks, you can't debug it because you never built the layer underneath. Juanjo and I think that gap is worth closing.

Yesterday we shipped 10 small browser-based exercises that walk through that layer one pattern at a time (more on how we run them in the browser with Pyodide here).

This article is the conceptual journey behind them: how you get from "I can call Claude" to a complete agent loop with a testable architecture and a human-in-the-loop workflow. Each stage builds on the previous one.

Stage 1: make a model reply (exercise 1)

Every agent app starts with the same 3-line skeleton. Build a client, call messages.create, read content[0].text. The shape doesn't change much. Only what wraps around it does.

import anthropic

client = anthropic.Anthropic()
msg = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=256,
    messages=[{"role": "user", "content": "Say hi"}],
)
print(msg.content[0].text)

Why content[0].text and not .text? Because content is a list of blocks (text, tool_use, and others). That list is how tool use plugs in later without breaking the response shape. Get this mental model before anything else.

Stage 2: make the reply machine-readable (exercises 2, 3)

Raw LLM strings are unreliable. The fix is two paired habits: a specific system prompt that locks the output shape, and a Pydantic model that validates it on the way back in.

from pydantic import BaseModel

class ExpenseResult(BaseModel):
    category: str
    confidence: float

result = ExpenseResult.model_validate_json(msg.content[0].text)

Treat the system prompt like an API contract. Say "JSON only", show the literal shape, forbid improvisation ("no punctuation, no explanation, nothing else"). The phrase "nothing else" is doing real work; without it, models love to append a friendly sentence that breaks your parser.

Stage 3: make it remember (exercise 4)

LLMs don't remember anything. They have no state, no memory, no context beyond the current call. The "conversation" is a fiction we create by sending the whole message history every time.

To get a continuous conversation, you keep the list of {"role": ..., "content": ...} dicts and send the whole thing every turn. Append the user message before the call, the assistant reply after. Roles must alternate.

history = []

def ask(user_msg):
    history.append({"role": "user", "content": user_msg})
    reply = client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=512,
        messages=history,
    ).content[0].text
    history.append({"role": "assistant", "content": reply})
    return reply

State lives in your code, not the model. That single realization clears up most of the confusion students have about context windows and "memory."

Stage 4: give the model hands (exercise 5)

Tool use turns a chatbot into something that can act. The loop is dumber than people think:

while True:
    response = client.messages.create(..., tools=TOOLS, messages=messages)
    if response.stop_reason == "end_turn":
        return response.content[0].text
    # else: run the tool the model asked for, append the result, loop again

Two gotchas: append the full response.content as the assistant turn (it contains the tool_use blocks the model needs to see), and tool results come back wrapped in a user message, not assistant.

Stage 5: make it swappable and testable (exercises 6, 7, 8)

By exercise 6 the chatbot works, but it's also often a highly coupled mess importing external dependencies like anthropic and sqlite3 into the business logic. Time for three common patterns, applied to LLM apps:

That's the four-layer agent architecture, built piece by piece instead of dumped on you all at once.

Stage 6: keep a human in the loop (exercise 9)

When the model returns a confidence score, use it. Above the threshold: auto-accept. Below: show the suggestion and let the user confirm or override.

def process(result, threshold=0.8):
    if result.confidence >= threshold:
        return result.category
    answer = input(f"Accept '{result.category}'? (Enter to confirm): ").strip()
    return answer or result.category

Make the accept path the cheapest action (empty input or y). Users pay the manual handling cost only when overriding. This is what separates a trusted assistant from one that quietly mislabels things, and it's the gap between "AI demo" and production-ready workflow.

Stage 7: generalize the loop (exercise 10)

The agent is exercise 5 with one change: replace the hardcoded function call with a TOOL_FUNCTIONS[name] lookup.

TOOL_FUNCTIONS = {
    "add": lambda a, b: a + b,
    "multiply": lambda a, b: a * b,
}
# inside the loop:
content = str(TOOL_FUNCTIONS[block.name](**block.input))

Now adding a tool is one schema entry plus one dict entry. Swap add/multiply for search_web, query_db, send_email and the loop is identical. Look at agent frameworks under the hood (LangChain, OpenAI Assistants) and you'll see this same pattern.

What the journey teaches

Frameworks make sense once you can write the layer underneath. Skip that, and you are stuck the first time the abstraction leaks. After coaching many developers through this, the dividing line is clear: have they ever written the loop themselves?

The 10 exercises are deliberately small. The arc matters more than any single one. Once you've done them, "agentic AI" stops being "magic" and starts being a loop, schema, and some patterns you might already know.

Try them out:

  1. In the browser: pythonagenticai.com/exercises. No install, no API key, no dependencies. Loads fast.
  2. Locally: clone the repo and work through them in your IDE.

Keep reading

May 14, 2026 12:00 AM UTC

May 13, 2026


"Michiel's Blog"

httpx2!

It’s six weeks after we forked httpx and named our package httpxyz. Yesterday, the Pydantic people started their own fork, httpx2.

TL;DR: while we think httpxyz was definitely needed, we welcome httpx2 and think it should be the ‘blessed’ fork.

httpxyz logo

About httpx2

Our fork

We did a bunch of work on httpx, merging old open pull requests, forking httpcore, and making serious improvements fixing performance and other issues.

The Pydantic fork

Straight after we made our fork, I contacted Kludex, who is among other things maintainer of Starlette, about our fork. He said that he had also been thinking about doing a fork, but that he might prefer to do one himself, and also that he thought that ours could not get popular because it’s on Codeberg instead of on GitHub.

I’m not really sure about that last one. While it’s true that there are still no big examples of popular Python packages on Codeberg, more and more projects are currently moving there. Also, even though we are on Codeberg, every single day we were still gaining ‘stars’ and if the Pydantic team would have backed our fork, with their power we definitely could have made it a success. The majority of users don’t care at what forge the code is hosted, they install from PyPI, via pip or uv. Where the code is hosted is not really a factor in the popularity.

The way forward

The reason I started httpxyz was because of the impasse httpx was in, and that I felt something had to be done. It’s not that I wanted to be the maintainer of an HTTP library per se ;-)

So now that Pydantic, with their skillful team and their powerful ecosystem of packages, is creating their own fork, there is no point really in trying to compete with them. We’ll keep httpxyz up; but we will support httpx2 and will urge anyone who is trying to switch away from httpx to consider httpx2.

The current situation

As it stands, httpx2 is lacking the performance improvements we added to httpxyz. But it will not be long before they will add those, too.

Also they already made some smart decisions I had been unsure about:

I have great trust in their stewardship of the module. We don’t need ‘competing’ forks; we’ll fully support httpx2 and will encourage the community to do the same!

Thanks, and have fun!

Discussion on Hacker News

May 13, 2026 07:00 PM UTC


Python Software Foundation

PSF Welcomes Hudson River Trading (HRT) as a Visionary Sponsor

[May 13, 2026] – The Python Software Foundation (PSF) is excited to announce that Hudson River Trading (HRT), a global leader in quantitative trading, has made a commitment to support Python and the PSF as a Visionary Sponsor. 

HRT’s "Visionary" sponsorship—our highest tier—will help to support the foundation’s core work of advancing and protecting the Python programming language and supporting a diverse and international community of Python programmers. HRT is the first quantitative trading firm to become a PSF Visionary Sponsor, alongside companies including NVIDIA, Google, Fastly, Bloomberg, Meta, and Anthropic. Contributions at this level directly fund the critical work that keeps Python thriving, including:

A Shared Commitment to Python

Hudson River Trading is no stranger to the power of Python. As a leading multi-asset class quantitative trading firm, HRT relies on Python for research, data analysis, and engineering workflows. With this donation, HRT is giving back to the tools that empower their engineers and helping to ensure that Python remains flexible, effective, and welcoming in the ways that have made it one of the most popular programming languages in the world. Read more about Open Source at HRT on this page.

“Python is a cornerstone of HRT’s research and trading infrastructure. Our engineers use Python extensively to build cutting-edge tooling that enhances our developer workflows, and we believe strongly in contributing to the open source software that makes our work possible. We are proud to support the PSF as a Visionary Sponsor helping to safeguard Python as a robust, accessible, and community-driven language for years to come.”  – Prashant Lal, Partner at Hudson River Trading

“Part of HRT's edge is our engineering, and one of our core values is 'Make It Better'. Our support of the Python Software Foundation – alongside our contributions to many other open source projects – reflects our desire to remain active, collaborative participants in the OSS engineering community over the long term, for the benefit of all.” – Hashem, Lead Software Engineer at Hudson River Trading

“At HRT, we’ve always believed that the best way to advance Python is by working hand-in-hand with the community. Our internal work on lazy imports gave us deep expertise in the problem space, and we channeled that experience directly into open collaboration by contributing to the development of PEP 810. We pride ourselves on being exemplary participants in both the trading markets and the open source community, and our sponsorship of the Python Software Foundation reflects that genuine spirit of collaboration.” – Pablo Galindo Salgado, Lead Software Engineer at Hudson River Trading

As part of its ongoing participation in the Python ecosystem, HRT will be open sourcing some of its own projects and announcing additional OSS contributions later this year. To learn more about HRT’s open engineering, research, and data science roles, visit https://www.hudsonrivertrading.com/careers/. 

The PSF is grateful for Hudson River Trading’s support, alongside that of each of our Visionary Sponsors, and we hope you will join us in thanking them for their commitment to  the PSF and the Python community!

About Hudson River Trading (HRT)

Hudson River Trading (HRT) is a leading quantitative trading firm at the forefront of technical innovation in global financial markets. Every day, we bring together the world’s sharpest minds to collaboratively solve challenging problems and build technology that will drive the future of trading. Leveraging one of the world’s most sophisticated computing environments for research and development, we trade across asset classes and time horizons on more than 200 markets worldwide. We are a leading voice advocating for fair and transparent markets everywhere and dedicated to creating a better trading landscape for all. For more information, visit www.hudsonrivertrading.com. 

About the Python Software Foundation (PSF)

The Python Software Foundation is a US non-profit whose mission is to promote, protect, and advance the Python programming language, and to support and facilitate the growth of a diverse and international community of Python programmers. The PSF supports the Python community using corporate sponsorships, grants, and donations. Are you interested in sponsoring or donating to the PSF so we can continue supporting Python and its community? Check out our sponsorship program, donate directly, or contact our team at sponsors@python.org!

May 13, 2026 05:19 PM UTC


Real Python

How to Use OpenCode for AI-Assisted Python Coding

OpenCode is an open-source AI coding agent that runs in your terminal and lets you analyze and refactor a Python project through conversational commands. In this guide, you’ll install it on your system, set it up with a free Google Gemini API key, and learn the basics of how to use it in your daily programming work.

Here’s what OpenCode’s main interface looks like:

OpenCode's Initial ScreenOpenCode's Initial Screen

OpenCode works as a conversational assistant you explicitly direct. Ask it to analyze functions, refactor code, or explain issues. Press Enter to send your query, and you’ll get a response with full awareness of your project context. It supports more than seventy-five AI providers, including Anthropic, OpenAI, and Google Gemini.

If you’re a Python developer who prefers working in the terminal, OpenCode offers deliberate, context-aware assistance and a customizable AGENTS.md configuration file.

Take the Quiz: Test your knowledge with our interactive “How to Use OpenCode for AI-Assisted Python Coding” quiz. You’ll receive a score upon completion to help you track your learning progress:


Interactive Quiz

How to Use OpenCode for AI-Assisted Python Coding

Quiz yourself on OpenCode: install it, connect an AI provider, and use it to analyze and refactor Python from your terminal.

Prerequisites

Before you start working with OpenCode, you’ll need to fulfill the following prerequisites regarding your current system and working environment:

  • Python 3.11 or higher for the sample project
  • A modern terminal emulator

You also need an AI provider account. In this guide, you’ll use Google AI Studio to get a free Gemini API key. The free Gemini tier lets you follow along without any additional costs. However, you can also use Anthropic, OpenAI, or GitHub Copilot if you already have subscriptions to those services.

This guide uses a sample project consisting of a dice-rolling script. You’ll find the full source code in a collapsible block at the start of Step 2. The download below includes the starting script and the final refactored version so you can compare your work when you’re done:

Get Your Code: Click here to download the free sample code you’ll use to learn about AI-assisted Python coding with OpenCode.

You’ll also need some background knowledge of Python programming and basic experience with your operating system’s terminal or command line.

Step 1: Install and Set Up OpenCode

It’s time to install OpenCode and get it talking to a model. You’ll install the tool on your system, authenticate with Gemini using a free API key, configure a default model, and verify that OpenCode responds correctly to your Python questions before you start coding with it.

Install and Launch OpenCode

The quickest way to install OpenCode is to use the official installation script, which you can do with the following command:

Language: Shell
$ curl -fsSL https://opencode.ai/install | bash

This script detects your platform, downloads the appropriate binary, installs the tool, and adds it to your PATH.

If you prefer a package manager, you can also install OpenCode with Homebrew on macOS or Linux:

Language: Shell
$ brew install anomalyco/tap/opencode

Note that the Homebrew team maintains the official formula and updates it less frequently than the installation script above.

Alternatively, you can install it as a Node.js package using npm if you already have this tool on your system:

Language: Shell
$ npm install -g opencode-ai

If you’re on Windows, the best experience comes from using WSL (Windows Subsystem for Linux). Set up WSL first by following Microsoft’s WSL installation guide, then open a WSL terminal and run the curl command above. For optimal performance, you should store your project within the WSL filesystem rather than on a Windows drive.

Read the full article at https://realpython.com/opencode-guide/ »


[ 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 ]

May 13, 2026 02:00 PM UTC


PyCharm

Support for uv, Poetry, and Hatch Workspaces (Beta)

Workspaces are increasingly the go-to choice for companies and open-source teams aiming to manage shared code, enforce consistency, and simplify dependency management across multiple services. Working within massive codebases often means juggling many interdependent Python projects simultaneously.

To streamline this experience, PyCharm 2026.1.1 introduced built-in support for uv workspaces, as well as those managed by Poetry and Hatch. This new functionality – currently in Beta – allows the IDE to automatically manage dependencies and environments across your entire workspace.

Intelligent workspace detection

When you open a workspace, PyCharm can now derive its entire structure and all its dependencies directly from your pyproject.toml files. This allows the IDE to understand relationships between projects deeply, significantly reducing the amount of configuration you have to do manually.

Because this is a fundamental change to how PyCharm handles your workspace, we’ve implemented it as an opt-in feature. Here is what you need to know about the transition:

Managing workspaces and their projects

PyCharm now provides an integrated experience that handles the complexities of multi-package setups in uv workspaces automatically. When you open a uv workspace, the IDE identifies the individual projects and their interdependencies, ensuring the project structure is ready for you to work with.

Visualizing workspace dependencies

Once the workspace is loaded, you can verify how your projects relate to one another. PyCharm presents these dependencies in Settings | Project Dependencies.

These relationships are derived directly from your configuration and are shown as read-only in the UI. To make changes to the dependency graph, you can edit the pyproject.toml file manually – PyCharm will then update its internal model.

Automatic environment configuration

PyCharm prioritizes a zero-config approach to your Python SDK. When you open a .py or pyproject.toml file within a project, the IDE performs an immediate check.

If a compatible environment already exists on your system, PyCharm automatically configures it as the SDK for that project. If no environment is detected, a file-level notification will appear suggesting that you create a new uv environment and install the necessary dependencies for that project.

Maintaining environment consistency

Beyond the initial setup, PyCharm continuously monitors the health of your environment to ensure it stays in sync with your defined requirements. 

If a dependency is not defined in your pyproject.toml file but is imported in your code, PyCharm will trigger a warning with a Sync project quick-fix to resolve these discrepancies.

Import management

PyCharm also assists when you are actively writing code by identifying gaps in your project configuration.

If you import a package that isn’t present in the environment and is not yet listed in the project’s pyproject.toml, the IDE will detect the omission. A quick-fix will suggest adding the package to the environment and updating the corresponding .toml file simultaneously.

Transparency via the Python Process Output tool window

While PyCharm automates the backend execution of commands – such as uv sync –all-packages – it still remains fully transparent.

You can track all executed commands and their live output in the Python Process Output tool window. If synchronization fails for an environment, you can analyze the specific error logs to quickly identify the root cause.

Poetry and Hatch workspaces

The logic for Poetry and Hatch workspaces follows this exact same workflow. PyCharm detects projects via their pyproject.toml files and manages the environments with the same automated precision.

The only minor difference is in tool selection – the suggested environment tool is determined by what you have specified in your pyproject.toml. If no tool is specified, PyCharm will prioritize uv (if installed) or a standard virtual environment to get you up and running quickly.

Looking ahead

This Beta version of the functionality is just the beginning of our focus on supporting complex workspace structures. We are already working on expanding the UI to allow creating new projects, linking dependencies, and activating the terminal for specific projects.

As we refine these features, your feedback is our best guide – please share your thoughts or report any issues on our YouTrack issue tracker.

May 13, 2026 12:28 PM UTC


Python GUIs

How to Add Custom Widgets to Qt Designer — Use widget promotion to integrate your own Python widgets into Qt Designer layouts

Can I use custom widgets in Qt Designer?

When you're building Python GUI applications with PyQt6 and Qt Designer, you'll reach a point where the built-in widgets aren't enough. Maybe you've created a custom plotting widget or a specialized input control in Python, and you want to place it into your Qt Designer layouts alongside all the standard widgets.

The good news is that Qt Designer supports exactly this through a feature called widget promotion. In this tutorial, you'll learn how to take any custom Python widget and integrate it into your Qt Designer .ui files, so you can position and size it visually just like any built-in widget.

The bad news is that since Qt Designer is a C++ application, it can't run your Python code. That means you won't see your custom widget rendered in the Designer preview. Instead, you'll see a placeholder (the base widget type you promoted from). Once you load the .ui file in your running Python application, your custom widget appears in all its glory.

With that caveat aside, let's look at how we can use custom widgets in Qt Designer.

What is Widget Promotion?

Widget promotion is Qt Designer's way of letting you swap a standard widget for a custom one. You start by placing a regular widget on your form, a plain QWidget for example, and then tell Qt Designer: "When this UI is actually used, replace this placeholder with my custom widget class instead."

Behind the scenes, this adds some extra information to the .ui file. When you load that file in Python using uic.loadUi() or compile it with pyuic6, the loader knows to import your custom class and use it in place of the base widget.

Creating a Custom Widget

Before we get into Qt Designer, let's create a simple custom widget in Python. We'll make a basic colored widget that draws a gradient background—something you'd never get from a standard widget.

Create a new file called custom_widgets.py:

python
from PyQt6.QtWidgets import QWidget
from PyQt6.QtGui import QPainter, QLinearGradient, QColor
from PyQt6.QtCore import Qt


class GradientWidget(QWidget):
    """A custom widget that displays a gradient background."""

    def __init__(self, parent=None):
        super().__init__(parent)

    def paintEvent(self, event):
        painter = QPainter(self)
        gradient = QLinearGradient(0, 0, self.width(), self.height())
        gradient.setColorAt(0.0, QColor("#2c3e50"))
        gradient.setColorAt(1.0, QColor("#3498db"))
        painter.fillRect(self.rect(), gradient)
        painter.end()

This widget overrides paintEvent to draw a diagonal gradient from dark blue to lighter blue. It's a straightforward example, but the same promotion process works for any custom widget—complex plotting canvases, custom controls, or anything else you build by subclassing a Qt widget.

Setting Up Your Project Structure

For widget promotion to work, the Python file containing your custom widget needs to be importable when your application runs. The simplest way to achieve this is to keep everything in the same directory:

python
my_project/
&boxvr&boxh&boxh custom_widgets.py      # Your custom widget classes
&boxvr&boxh&boxh mainwindow.ui          # Your Qt Designer file
&boxur&boxh&boxh main.py                # Your application entry point

The file name and class name matter here—you'll need to tell Qt Designer both of these during the promotion step.

Promoting a Widget in Qt Designer

Now we can open Qt Designer and set up the promotion.

Place a base widget on your form

Open Qt Designer and create a new Main Window (or open your existing .ui file). From the widget box on the left, drag a plain Widget (QWidget) onto your form. Position and resize it however you like—this is where your custom widget will appear when the application runs.

You can use any base widget class as your starting point. If your custom widget subclasses QPushButton, promote a QPushButton. If it subclasses QLabel, promote a QLabel. For our GradientWidget, which subclasses QWidget, a plain QWidget is the right choice.

Open the Promote Widgets dialog

Right-click on the widget you just placed. In the context menu, select Promote to.... This opens the Promoted Widgets dialog.

Promote to option in Qt Designer context menu

Fill in the promotion details

In the dialog, you'll see fields for three pieces of information:

Promoted Widgets dialog filled in

Leave the Global include checkbox unchecked.

Add and promote

Click Add to add your class to the list of known promoted widgets. Then, with your class selected in the list, click Promote. The dialog closes, and you'll notice the widget's class name in the Object Inspector (top-right panel) now shows GradientWidget instead of QWidget.

That's it for the Designer side. Save your .ui file.

Promoting additional widgets

Once you've added a promoted class through this dialog, it becomes available for reuse. The next time you want to promote a widget to GradientWidget, just right-click the widget and you'll see it listed directly in the Promote to submenu—no need to open the full dialog again.

Loading the UI in Python

Now let's write the Python code to load the .ui file and see our custom widget in action. Create main.py:

python
import sys
from PyQt6.QtWidgets import QApplication, QMainWindow
from PyQt6 import uic


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        uic.loadUi("mainwindow.ui", self)


app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()

When you run this, uic.loadUi() reads the .ui file and sees that one of the widgets has been promoted to GradientWidget from the custom_widgets module. It automatically does the equivalent of:

python
from custom_widgets import GradientWidget

...and creates an instance of GradientWidget wherever you placed that promoted widget in your layout. Instead of a blank QWidget, you'll see your gradient background.

Using Compiled UI Files

If you prefer to compile your .ui files to Python using pyuic6 rather than loading them at runtime, promotion works the same way. Run:

sh
pyuic6 mainwindow.ui -o ui_mainwindow.py

If you open the generated ui_mainwindow.py, you'll find an import line near the bottom:

python
from custom_widgets import GradientWidget

The compiled code creates your GradientWidget instance in the right place automatically. You can then use the generated file in your application:

python
import sys
from PyQt6.QtWidgets import QApplication, QMainWindow
from ui_mainwindow import Ui_MainWindow


class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)


app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()

Both approaches—runtime loading and compiled files—handle promoted widgets in the same way.

A More Practical Example: Embedding PyQtGraph

One of the most common reasons to promote widgets is to embed third-party plotting libraries like PyQtGraph into your Designer layouts. PyQtGraph's PlotWidget is a subclass of QGraphicsView, so you'd promote a QGraphicsView in Designer.

Here's how you'd fill in the promotion dialog for PyQtGraph:

That's all it takes. When your application runs, the placeholder QGraphicsView becomes a fully functional PlotWidget that you can plot data on.

python
import sys
from PyQt6.QtWidgets import QApplication, QMainWindow
from PyQt6 import uic


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        uic.loadUi("mainwindow.ui", self)

        # self.graphWidget is the promoted PlotWidget
        # (use the objectName you set in Designer)
        self.graphWidget.plot([1, 2, 3, 4, 5], [10, 20, 15, 30, 25])


app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()

Promoting Widgets from Submodules

If your custom widget lives in a submodule or package, you can use dotted import paths in the Header file field. For example, if your project structure looks like this:

python
my_project/
&boxvr&boxh&boxh widgets/
&boxv   &boxvr&boxh&boxh __init__.py
&boxv   &boxur&boxh&boxh gradient.py    # contains GradientWidget
&boxvr&boxh&boxh mainwindow.ui
&boxur&boxh&boxh main.py

You would enter widgets.gradient as the header file in the promotion dialog. The loader will then do:

python
from widgets.gradient import GradientWidget

This keeps things organized as your project grows.

Troubleshooting Common Issues

"No module named 'custom_widgets'" — This means Python can't find the file containing your custom widget class. Make sure the module file is in the same directory as your script (or somewhere on your Python path), and that the name in the promotion dialog matches the file name exactly (without .py).

The widget appears blank or as a plain QWidget — Double-check that the promoted class name matches your Python class name exactly, including capitalization. GradientWidget and gradientwidget are different classes as far as Python is concerned.

The widget doesn't resize properly — Make sure you've added the promoted widget to a layout in Qt Designer. Widgets outside of layouts won't resize with the window, regardless of whether they're promoted or not.

Changes to your custom widget don't appear in Designer — Remember, Qt Designer can't render Python widgets. You'll always see the base widget type in the Designer preview. Run your application to see your custom widget.

Summary

Widget promotion is a straightforward way to bridge the gap between Qt Designer's visual layout tools and your custom Python widgets. The process is always the same:

  1. Place a base widget of the appropriate type in Qt Designer.
  2. Right-click and promote it, specifying your custom class name and module path.
  3. Save the .ui file and load it in your Python application.

Your custom widget won't be visible in the Designer preview—that's expected. But when your application runs, the promoted widget is swapped in seamlessly, giving you the best of both worlds: visual layout design with the full power of custom Python widgets.

For an in-depth guide to building Python GUIs with PyQt6 see my book, Create GUI Applications with Python & Qt6.

May 13, 2026 06:00 AM UTC


Bob Belderbos

Coding exercises that run in the browser with Pyodide

I've built coding-exercise platforms before (Python, Rust). AWS API Gateway + Lambda, Docker, etc. It works great, but that's a lot of infrastructure to teach someone a four-line function.

For our new Agentic AI cohort I wanted a free warm-up: ten short Python exercises that introduce the AI vendor SDK patterns (in this case Anthropic). The hard constraint was that visitors should be able to click "Run" without signing up, without bringing an API key, and without complex third party infrastructure. As this site is built on Cloudflare Pages, that meant an in-browser Python runtime. Enter Pyodide ...

Unlike toy Python interpreters, Pyodide runs real CPython compiled to WebAssembly (listen to my interview Elmer Bulthuis why Wasm is cool), which enables broad compatibility with the Python ecosystem, including native extension packages.

Getting it working was easy with some Claude Code prototyping; the interesting part was the last 20%. Some of the challenges I faced and how I worked around them.

Mocked tests + a stubbed SDK

Every exercise has a solution.py and a test_exercise.py. The tests look like this:

from unittest.mock import MagicMock, patch
from solution import get_completion

def test_returns_text():
    mock_client = MagicMock()
    mock_client.messages.create.return_value.content = [MagicMock(text="Hello, Pythonista!")]
    with patch("solution.anthropic.Anthropic", return_value=mock_client):
        assert get_completion("Say hello") == "Hello, Pythonista!"

patch("solution.anthropic.Anthropic") replaces the class with a mock for the duration of the with block. The original Anthropic class is never instantiated. Which means the only thing the real SDK contributes is the name anthropic.Anthropic existing somewhere on the Python path.

So I don't install it. I write a tiny stub package straight to Pyodide's in-browser filesystem:

const ANTHROPIC_INIT = `
class Anthropic:
    def __init__(self, *args, **kwargs):
        pass
`;
const ANTHROPIC_TYPES = `
class TextBlock: ...
class MessageParam: ...
class ToolParam: ...
class ToolUseBlock: ...
`;

await pyodide.loadPackage(["pytest", "pydantic"]);
pyodide.FS.mkdirTree("/home/pyodide/anthropic");
pyodide.FS.writeFile("/home/pyodide/anthropic/__init__.py", ANTHROPIC_INIT);
pyodide.FS.writeFile("/home/pyodide/anthropic/types.py", ANTHROPIC_TYPES);

It's a package, not a single file, because some exercises also do from anthropic.types import TextBlock, which I needed to fix ty type errors. Both modules exist only so the imports resolve. The bodies never execute under test thanks to the mocking.

# Inside Pyodide, before running pytest:
sys.path.insert(0, "/home/pyodide")
# `import anthropic` finds the stub. `patch` replaces it. Tests run.

That one decision cuts ~3 seconds and several megabytes off the boot. The real anthropic package pulls in pydantic-core, httpx, httpcore, anyio, sniffio, idna, distro, certifi, typing-extensions. Every byte irrelevant to learning the pattern, because the test never lets the SDK run anyway.

If you've read build the data layer before you touch the LLM, this is the same strategy: cut the AI piece down to its smallest shape so the rest of the engineering is more flexible.

Lazy-loading the runtime

Pyodide is 5MB+ over the network. I don't want this to load on the homepage, not even on the exercise index page. Even on an exercise page, visitors might skim and leave. So the pyodide.js script tag isn't in the HTML. The page ships a ~250-line runner.js and that script injects Pyodide on demand:

// Module-level constants, defined once at the top of runner.js:
const PYODIDE_VERSION = "0.27.7";
const PYODIDE_URL = `https://cdn.jsdelivr.net/pyodide/v${PYODIDE_VERSION}/full/`;
const PYODIDE_JS_SRI = "sha384-90so5tCKvl0xs9agU29IMKlAVzhfzFX7QO//YxQkRhJG58bBZrFN+2ZTRB026X5X";

async function ensurePyodide() {
  if (pyodide) return pyodide;
  if (bootPromise) return bootPromise;
  bootPromise = (async () => {
    if (typeof loadPyodide !== "function") {
      await new Promise((resolve, reject) => {
        const s = document.createElement("script");
        s.src = PYODIDE_URL + "pyodide.js";
        s.integrity = PYODIDE_JS_SRI;
        s.crossOrigin = "anonymous";
        s.onload = resolve;
        s.onerror = () => reject(new Error("Failed to load pyodide.js"));
        document.head.appendChild(s);
      });
    }
    pyodide = await loadPyodide({ indexURL: PYODIDE_URL });
    await pyodide.loadPackage(["pytest", "pydantic"]);
    // write the anthropic stub here

    return pyodide;
  })();
  return bootPromise;
}

Two triggers prewarm the runtime before the user clicks Run:

cm.on("focus", prewarm);
runBtn.addEventListener("mouseenter", prewarm, { once: true });

The moment they tab into the editor or hover the button, the 3-second cold start starts ticking. By the time they're done typing, the runtime is usually ready. The cached bootPromise deduplicates: focus and hover both await the same in-flight promise, never two parallel boots.

Tracking progress without a backend

No users, no database, no sessions, but I still want:

One localStorage key holds the whole state:

const STORAGE_KEY = "pyai_progress_v1";
// { "first-api-call": { passed: true, code: "...", lastRun: 1736... } }

Three operations carry the state: saveCode(slug, code) runs on every CodeMirror change, markPassed(slug) runs when pytest returns 0, and get(slug) reads on page load to restore drafts and badges.

In a similar vein, the Solution tab stays locked until the tests pass. The point of an exercise is the struggle, not the answer.

Once markPassed(slug) writes to localStorage, it also fires a pyai:passed event, and a separate tabs.js listener flips the solution from <div data-solution-locked> to <div data-solution-revealed> and lazy-fetches solution.py for a side-by-side compare. No reload. One key, three consumers (runner, list page, solution tab).

And the key is versioned: pyai_progress_v1. The day I want to change the shape, I can bump it to _v2 and old state cleanly stops loading. No migration code, no schema check.

The list page reads the same store on render and walks the DOM:

document.querySelectorAll(".exercises-list-item").forEach((item) => {
  const slug = item.dataset.exerciseSlug;
  const { passed } = window.PyAIProgress.get(slug);
  if (passed) item.classList.add("is-passed");
});

When passedCount() >= total, a hidden next-step block flips visible. That's the whole mechanism: ten green checks reveal one element, all computed in the browser from that one localStorage key.

All static, all local

The whole thing is a static site. Cloudflare serves the HTML, JS, and the synced exercise files. The browser does the rest. Zero extra cost. It scales for free because the load is on the client, not a server.

For development, uv runs the end-to-end check with a single command:

uv run scripts/e2e_test.py

It walks every exercise in headless Chromium, pastes the reference solution, clicks Run, asserts the test suite passes. Ten exercises in ~22 seconds. Anytime the upstream content changes I know in under half a minute whether all ten warm-ups still pass end-to-end. I will save the details of this Playwright end-to-end testing for another article.

Starter code

The site this runs on is standalone so I put together a single-file Pyodide starter gist of a mini coding platform experience: code in the browser, click "Run tests", pytest runs against your code, all in the browser. Lazy boot and the Solution/Tests tabs are wired up. The SDK stub and localStorage progress I left out for simplicity, but the core Pyodide integration is there. You can download and build on it if you want to try your hand at a browser-based Python coding experience.

Try it out

Back to the 10 exercises, you can try them out here. They cover the basics that show up in the typical production Agentic AI app: a first API call, structured outputs with Pydantic, system prompts, multi-turn state, tool use, then the architectural patterns (Protocol, Repository, Service layer, HITL, the agent loop).

Keep reading

One bigger lesson I'm taking away from this: every time I've built a thing server-side over the years, I was usually paying a complexity tax for flexibility I didn't need. Sometimes the right architecture is to push the work to the client, especially where modern browsers and Wasm can handle this performantly and securely.

May 13, 2026 12:00 AM UTC

May 12, 2026


PyCoder’s Weekly

Issue #734: Dunder-Gets, Django Tasks in Prod, Codex CLI, and More (2026-05-12)

#734 – MAY 12, 2026
View in Browser »

The PyCoder’s Weekly Logo


Do You Get It Now?

Learn about Python’s .__getitem__(), .__getattr__(), .__getattribute__(), and .__get__(): how they’re different and where to use them.
STEPHEN GRUPPETTA

Using Django Tasks in Production

Django added a generic API for dealing with concurrent tasks in version 6. This post talks about how it has been used in production.
TIM SCHILLING

Use Codex CLI to Enhance Your Python Projects

Learn how to use Codex CLI to add features to Python projects directly from your terminal, without needing a browser or IDE plugins.
REAL PYTHON course

Depot CI: Built for the Agent era

alt

Depot CI: A new CI engine. Fast by design. Your GitHub Actions workflows, running on a fundamentally faster engine — instant job startup, parallel steps, full debuggability, per-second billing. One command to migrate →
DEPOT sponsor

PEP 828: Supporting ‘Yield From’ in Asynchronous Generators (Deferred to 3.16)

PYTHON.ORG

PEP 797: Shared Object Proxies (Deferred to 3.16)

PYTHON.ORG

Django Security Releases: 6.0.5 and 5.2.14

DJANGO SOFTWARE FOUNDATION

Articles & Tutorials

Handling Schema Issues in Polars

You’ve got this great data pipeline going until one day it stops working. A schema error causes by a column upstream has stopped you in your tracks. This post talks about the four different causes of schema errors and what to do about them.
THIJS NIEUWDORP

Textual: An Intro to DOM Queries (Part II)

Textual is a TUI framework library for building terminal applications. It uses a DOM to represent the widgets in the application, and that DOM is queryable. This is part 2 in a series on how to find things in your Textual DOM.
MIKE DRISCOLL

Everything You Always Wanted to Know About PyCon Sprints!

PyCon US includes coding sprints to work on CPython itself, or projects in the ecosystem like Django, Flask, and BeeWare. This post tells you all about sprints and how you can join in on the fun.
DEB NICHOLSON

Why TUIs Are Back

Terminal User Interfaces are seeing a resurgence in the tools space. This opinion piece briefly talks about the history of interfaces and why we are where we are now.
ALCIDES FONSECA

Parallel Python at Anyscale With Ray

Talk Python interviews Richard Liaw and Edward Oakes. They talk about Ray, an open source Python framework a distributed execution engine for AI workloads.
TALK PYTHON podcast

Python 3.14.5 Release Candidate

Normally nobody fusses over a release candidate of a point release, but 3.14.5 includes a major change: rolling back of the incremental garbage collector.
HUGO VAN KEMENADE

Wagtail 7.4: Custom Page Explorer, Preview Checks & More

Between autosave improvements, new ways to sort your pages, and a content checker upgrade, you’ll have a lot of reasons to move to Wagtail 7.4
MEAGEN VOSS

The Simplest MCP Example Possible in Python

This guide introduces you to connecting your code to a local LLM model. It covers Ollama and FastMCP and what you can do with these tools.
AL SWEIGART

ChatterBot: Build a Chatbot With Python

Build a Python chatbot with the ChatterBot library. Clean real conversation data, train on custom datasets, and add local AI with Ollama.
REAL PYTHON

Hardening Firefox With Claude Mythos Preview

New details about what Mozilla found and how agentic harnesses helped them reproduce real bugs and dismiss false positives.
MOZILLA

Projects & Code

pytest-fly: pytest Observer

GITHUB.COM/JAMESABEL

Pymetrica: A Codebase Analysis Tool

GITHUB.COM/JUANJFARINA ‱ Shared by Juan JosĂ© Farina

PyWry: Cross-Platform Rendering Engine and UI Toolkit

GITHUB.COM/DEELEERAMONE

secure: HTTP Security Headers for FastAPI, Flask, Django

GITHUB.COM/TYPEERROR ‱ Shared by Caleb Kinney

Kirokyu: Modular Task Management System

GITHUB.COM/AMRYOUNIS ‱ Shared by Amr Younis

Events

Weekly Real Python Office Hours Q&A (Virtual)

May 13, 2026
REALPYTHON.COM

PyCon US 2026

May 13 to May 20, 2026
PYCON.ORG

Python Atlanta

May 14 to May 15, 2026
MEETUP.COM

Chattanooga Python User Group

May 15 to May 16, 2026
MEETUP.COM

PyDelhi User Group Meetup

May 16, 2026
MEETUP.COM

PyData London

June 5 to June 7, 2026
PYDATA.ORG ‱ Shared by Tomara Youngblood


Happy Pythoning!
This was PyCoder’s Weekly Issue #734.
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 ]

May 12, 2026 07:30 PM UTC