02 Jun 2026
Planet Python
PyCoder’s Weekly: Issue #737: Polars 1.41, Email, Great Docs, and More (2026-06-02)
#737 - JUNE 2, 2026
View in Browser »
Announcing Polars 1.41
Polars 1.41 is out and this post covers the new features it includes. Learn about faster parquet metadata decoding, nested subplan elimination, and more.
POLA.RS
Sending Emails With Python
Learn how to send emails with Python using SMTP, attach files, format HTML messages, and personalize bulk emails for your contact list.
REAL PYTHON
Quiz: Sending Emails With Python
Use Python's standard library to send email through secure SMTP connections, attach files, include HTML content, and route replies.
REAL PYTHON
Your Coding Agent Gets Dumber the Longer It Runs. Here's the Fix.
Coding agents degrade as context grows. The fix: a multi-role loop where the planner, builder, and reviewer each get isolated context - no stale assumptions, no compounding noise. A practical breakdown from someone who built it. Read the full breakdown
DEPOT sponsor
Great Docs
Talk Python interviews Rich Iannone and Michael Chow from Posit and they talk about a new Python documentation tool called Great Docs.
TALK PYTHON podcast
Articles & Tutorials
Improving Python Through PEPs and Protocols
Have you ever been confused by the naming of modules you're importing from a package? Is there a standard way to organize and name your Python virtual environments? This week on the show, Brett Cannon returns to discuss the Python Enhancement Proposals (PEPs) he's been working on recently.
REAL PYTHON podcast
Tame Your Pesky Little Scripts
Over time it is common to accumulate little helper scripts, whether they're shell scripts, aliases, or custom functions. They are typically tiny things that can become unwieldy to manage. This post shares a few ideas that might help you take back control.
JUHA-MATTI SANTALA
5-Day Live OOP Workshop (Final Chance to Enroll)
The Object-Oriented Python live cohort begins June 8. Five 2-hour sessions Mon to Fri build one growing application end to end, with OOP features introduced as the code starts needing them: classes, the data model, inheritance vs composition, properties, dataclasses.
REAL PYTHON sponsor
Free-Threading vs the GIL in mod_wsgi 6.0.0
Free-threading in mod_wsgi 6.0.0 lets a single process spread Python work across multiple cores. This post is a metrics based comparison between the GIL being enabled and disabled.
GRAHAM DUMPLETON
Notes About Python Email Packages
Chris recently upgraded his personal mail program from Python 2 to Python 3 and this post talks about what needed to change and notes how the newer code works.
CHRIS SIEBENMANN
Learning Path: Perfect Your Python Development Setup
Set up a Python development environment with VS Code, PyCharm, virtual environments, Git, pyenv, Docker, and AI coding tools like Claude Code and Cursor.
REAL PYTHON
Top 7 Python Libraries for Large-Scale Data Processing
This article covers Python libraries that make large-scale data processing faster, more scalable, and easier to manage across modern data workflows.
BALA PRIYA C
Connecting LLMs to Your Data With Python MCP Servers
Build an MCP server in Python that exposes tools, resources, and prompts so AI agents like Cursor can interact with your data.
REAL PYTHON course
How to Make a Scatter Plot in Python With plt.scatter()
Learn how to make scatter plots in Python with plt.scatter() and customize markers by size, color, shape, and transparency.
REAL PYTHON
Two Python Scoping Bugs: A Lesson in Object Lifetimes
Two Python bugs with opposite symptoms but the same root cause: picking the wrong scope for a stateful object.
BOB BELDERBOS
Sentinel Built-In
A quick post about Python 3.15's new sentinel built-in.
RODRIGO GIRÃO SERRÃO
Projects & Code
Events
Canberra Python Meetup
June 4, 2026
MEETUP.COM
Sydney Python User Group (SyPy)
June 4, 2026
SYPY.ORG
GeoPython 2026
June 8 to June 11, 2026
GEOPYTHON.NET
PiterPy Meetup
June 9, 2026
PITERPY.COM
SciPy 2026, Minneapolis, MN
July 13-19, 2026
SCIPY.ORG • Shared by SciPy Organizers
Happy Pythoning!
This was PyCoder's Weekly Issue #737.
View in Browser »
[ 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 ]
02 Jun 2026 7:30pm GMT
Django community aggregator: Community blog posts
You don't need React to be reactive — djust 1.0 is here
djust 1.0 is here - reactive UI for Django in pure Python. No client state, no JavaScript framework, no build step, no API layer. It brings the proven Phoenix LiveView model to Django with a Rust VDOM on the hot path. Try it live (multi-user, no install) at start.djust.org.
02 Jun 2026 6:00pm GMT
Planet Python
Real Python: Structuring Your Python Script
You may have begun your Python journey interactively, exploring ideas within Jupyter Notebooks or through the Python REPL. While that's great for quick experimentation and immediate feedback, you'll likely find yourself saving code into .py files. However, as your codebase grows, knowing where things should go in your script becomes increasingly important.
Transitioning from interactive environments to structured scripts helps promote readability, enabling better collaboration and more robust development practices. This video course shows you the foundations of organizing a Python script: where the runnable bits go, how to arrange your imports, and how to refactor with constants and a fixed entry point.
By the end of this video course, you'll know how to:
- Make a script directly executable on Unix-like systems with a shebang line
- Organize your import statements using standard grouping conventions
- Automatically sort imports and format your code with the
rufflinter - Replace hard-coded values with meaningful constants
- Define a clear script entry point using
if __name__ == "__main__"
Without further ado, it's time to start working through a concrete script and progressively shape it into well-organized, shareable code.
[ 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 ]
02 Jun 2026 2:00pm GMT
PyCharm: Top Agentic Frameworks for Building Applications 2026
In 2026, the world of AI is changing at a serious pace. The days of AI systems dealing solely in single-prompt interactions are coming to an end. Instead, these models are evolving into agentic systems - long-running, goal-driven software enabled by agentic frameworks that are becoming a critical layer in modern application architecture.
This rapid shift means that Python developers building autonomous systems are increasingly relying on agentic frameworks to manage reasoning, memory, tools, and collaboration among multiple agents.
You've probably already heard of some of the most popular frameworks. LangChain and AutoGen have risen to prominence, but there are dozens more, many of them open-source and only one to two years old. With so many frameworks promising different agentic capabilities, the real challenge is knowing which ones are best suited for the kind of application you want to build.
Let's take a closer look at some of the most important agentic frameworks on the market in 2026, comparing what each does best and rating them based on our key comparison criteria to help you discover which is best for your projects.
What are AI agents?
An AI agent is a piece of software capable of autonomously reasoning, setting goals, and performing tasks on behalf of a user or another system. As the name suggests, AI agents have a level of agency to learn, adapt, and make decisions independently. This means they can improve their behavior and, over time, choose their own actions to achieve specific goals or outcomes.
AI agents work by following a perceive, reason, act, reflect (PRAR) cycle, which allows them to:
- Perceive: Observe the environment, including user input, system state, tools, and memory, to understand the current context and constraints of the task.
- Reason: Plan, make decisions, and select actions using a large language model (LLM) or hybrid logic.
- Act: Execute actions like calling tools, updating memory, or triggering workflows.
- Reflect: Evaluate the outcome of previous actions and adjust future decisions, plans, or prompts to improve results.
AI agents rely on the natural language processing capabilities of large language models, but unlike traditional LLMs and AI chatbots, they don't require continuous user input to perform tasks. Agents are proactive, working autonomously to achieve a goal based on a specified set of rules and parameters.
What is an agentic framework?
An agentic framework provides the infrastructure needed to build, run, and control AI agents at scale. Most modern frameworks offer three core capabilities:
- Orchestration: Controls how agents are sequenced, coordinated, or allowed to collaborate.
- Tools: Define how agents interact with external systems like APIs or databases.
- Memory: Sets out how agents retain and retrieve information across steps or sessions.
While it's possible to build an agent without a framework, they're vital in ensuring agents are reliable, scalable, and safe.
Agentic frameworks help turn experimental agent builds into maintainable software by facilitating:
- Multi-agent coordination: When multiple agents communicate to plan, work together, and specialize in different areas of a task.
- Human-in-the-loop (HITL) checkpoints: Intentional pause points where a human can review what an agent is about to do.
- Observability, control, and reproducibility: The ability to see what an agent is doing, guide agent behavior, or re-run an agent and receive the same results.
Core orchestration paradigms
Before comparing individual frameworks, it's important to understand how they operate. Let's look at the three most commonly used orchestration models in 2026.
Graph-based orchestration
Graph-based orchestration provides maximum control by organizing agents and tools as nodes in a directed graph. Instead of letting an agent freely decide what to do next, the flow that agents are allowed to follow is clearly defined.
Strengths
- More deterministic control: Predictable behavior is critical for production systems that require reliable results.
- Easier debugging: Pinpoint exactly which node failed thanks to clear checkpoints and boundaries.
- Production-grade reliability: This approach is ideal for customer-facing applications, enterprise systems, or regulated environments.
Limitations
- More upfront design: The workflow must be defined in advance, which slows initial development.
- Less "emergent" behavior: Agents are constrained by the graph, leaving less room for experimentation and creativity.
Role-based orchestration
Role-based orchestration is most effective when simplicity is a priority. Agents are assigned specific roles, such as "Planner", "Researcher", or "Builder", and collaborate by sending messages to one another.
Strengths
- Intuitive mental model: This type of operation is easy to understand because it effectively mirrors how human teams work.
- Rapid prototyping: Minimal setup is required, allowing more time to explore outcomes.
Limitations
- Harder-to-constrain behavior: Because agents have the freedom to decide what to do next, it's difficult to enforce strict execution paths.
- Limited determinism: The same input can yield different outcomes, making it tricky to reproduce results and achieve consistency.
Chain-based orchestration
Chain-based orchestration, also known as adaptive orchestration, arguably offers the greatest flexibility. Agents in this model operate in dynamic chains or loops, deciding the next step autonomously.
Strengths
- Flexible workflows: Agents are not constrained to a pre-defined path and can freely explore different strategies.
- Suitability for creative tasks: This approach is ideal for research, discovery, and experimentation, as agents can iteratively explore ideas, pivot strategies, and adapt their approach.
Limitations
- Less predictability: Testing and debugging are more challenging because execution paths are harder to reproduce and trace.
- More difficult governance at scale: This unpredictability grows as tasks become more complex.
Best agentic frameworks for your projects
Now that we're familiar with the key orchestration paradigms of agentic frameworks, it's time to compare some of the most popular frameworks on the market in 2026. Below, we evaluate each framework's performance against our key comparison criteria:
- Primary orchestration model.
- Multi-agent support.
- Memory capabilities.
- Human-in-the-loop (HITL) support.
- Best-fit applications.
| Framework | Orchestration model | Multi-agent support | Memory capabilities | HITL support | Best used for |
| LangChain | Chain-based | Partial | Moderate | Limited to moderate | Rapid LLM app development |
| LangGraph | Graph-based | Yes | Strong | Strong | Production-grade agent workflows |
| LlamaIndex | Retrieval-centric | Limited | Strong | Moderate | Knowledge-heavy agents |
| Haystack | Pipeline-based/modular | Moderate | Strong | Moderate | Production RAG and context-heavy AI systems |
| AutoGen | Role-based | Strong | Moderate | Limited | Conversational multi-agent systems |
| CrewAI | Role-based | Strong | Light | Limited | Task-oriented agent teams |
| Semantic Kernel | Planner-based | Moderate | Moderate | Strong | Enterprise AI |
| smolagents | Minimalist | Limited | Light | Minimal | Lightweight experiments |
| OpenAI Agents SDK | Graph-based | Yes | Managed | Strong | Hosted agent applications |
| Phidata | Agent-centric | Limited to moderate | Strong | Moderate | Data and tool-heavy agents |
Let's take a closer look at the strengths and weaknesses of each framework, along with the applications they're most suited to.
LangChain
- Core design: Chain-based orchestration.
- Philosophy: Developer velocity and flexibility.
Launched in 2022, LangChain is one of the most widely adopted frameworks due to its broad ecosystem of integrations. It serves as an accessible interface for nearly any LLM and is an ideal starting point for enthusiasts or startups looking to explore agentic AI. While not strictly "agent-first", it provides the building blocks for agentic behavior.
LangChain provides less control than other frameworks, but it's still a fantastic entry point into agentic systems, especially for projects where speed and creativity take precedence over enforcing strict workflows.
Strengths
- Huge ecosystem.
- Easy tool integration.
- Rapid prototyping.
Limitations
- Less control than graph-based systems.
- Agent logic that can be difficult to understand as it grows in complexity.
Best applications
- Prototyping of agentic features.
- Tool-augmented chatbots.
- LLM-powered backend services.
If you want to go beyond the basics, read our LangChain Python Tutorial: A Complete Guide for 2026. It takes a deeper look at what LangChain offers and walks through real-world use cases for building AI agents in Python.
LangGraph
- Core design: Graph-based orchestration.
- Philosophy: Explicit control over agent behavior.
LangGraph has emerged as the leading standard for production-grade agent systems. Built on top of LangChain, it replaces implicit chains with explicit graphs, providing strict control over workflows and excellent HITL support via interrupts.
While the graph structure itself can actually make debugging easier by clearly mapping how agents and tools interact, LangGraph does come with a learning curve. Much of this complexity comes from designing the graph and managing explicit state between nodes. Once you understand these concepts, the framework becomes a powerful option for building predictable and controllable agent systems.
Strengths
- Deterministic workflows.
- Native state management.
- Excellent HITL support via interrupts.
- Suitability for regulated or mission-critical systems.
Limitations
- Higher upfront design effort.
- Steeper learning curve due to explicit graph and state management.
- Reduced flexibility for open-ended tasks.
Best applications
- Autonomous customer support systems.
- AI-driven DevOps workflows.
- Multi-step decision engines.
LlamaIndex
- Core design: Retrieval-centric orchestration.
- Philosophy: Data-first agents.
LlamaIndex is a Python framework designed to help AI systems understand, store, and retrieve information from large amounts of documents and data.
Rather than starting with agents and adding data later, LlamaIndex takes the opposite approach - it starts with data and then builds agent behavior around it. This is why it is often described as data-first or retrieval-centric.
Because it operates in this way, LlamaIndex excels at indexing, memory, and retrieval, making it ideal for building agents whose intelligence depends on accessing the right information rather than executing complex actions.
Strengths
- Advanced document indexing.
- Strong long-term memory patterns.
Limitations
- Limited suitability for complex, action-heavy orchestration.
- Limited support for multi-agent orchestration.
Best applications
- Research assistants.
- Knowledge base agents.
- Enterprise document intelligence.
Haystack
- Core design: Modular pipeline orchestration.
- Philosophy: Context engineering and production-ready AI systems.
Haystack is an open-source AI orchestration framework created by deepset for building production-ready AI agents, retrieval-augmented generation (RAG) systems, and multimodal applications.
Instead of focusing purely on agent behavior, Haystack structures applications as explicit pipelines composed of retrievers, routers, memory layers, tools, evaluators, and generators. This modular architecture gives you control over how information flows through a system, allowing each component to be tested and improved independently.
Haystack is particularly strong in applications where the quality of retrieved information determines the quality of the model's output. Its design also makes it well-suited for enterprise environments that require transparency and reliability in production systems.
Strengths
- Highly modular pipeline architecture.
- Excellent support for RAG and document processing.
- Strong ecosystem, particularly in search and RAG-focused enterprise use cases.
- Flexible integrations with models and vector databases.
Limitations
- More infrastructure and setup than lightweight frameworks.
- Less focus on emergent multi-agent collaboration.
Best applications
- Retrieval-augmented generation (RAG) systems.
- Enterprise document intelligence.
- Data-heavy AI applications.
- Production AI pipelines that require strong context control.
AutoGen
- Core design: Role-based multi-agent collaboration.
- Philosophy: Conversation-driven autonomy.
AutoGen, an open-source Microsoft framework, popularized the idea of agents collaborating through structured conversation, organizing systems as teams of agents, each with its own specific role. Unlike in other frameworks, there's no central controller enforcing a strict execution path - the collaboration itself drives progress.
This approach makes AutoGen ideal for exploratory, creative, and research-driven multi-agent systems, at the cost of predictability, HITL, and strict execution control.
Strengths
- Natural multi-agent interaction.
- Minimal orchestration overhead.
- Suitability for emergent problem-solving.
Limitations
- Limited execution control.
- Weak HITL support.
Best applications
- Coding agents.
- Brainstorming systems.
- AI research experiments.
CrewAI
- Core design: Role-based task delegation.
- Philosophy: Teams of specialized agents.
CrewAI is centered around building simple, structured multi-agent systems. It is similar to AutoGen, modeling AI agents as members of a "crew" where each agent has a clearly defined role. The goal is to make multi-agent systems approachable, even if you are new to agentic AI.
CrewAI prioritizes simplicity and speed over deep memory and production controls, making it easy to learn and a strong option for prototypes and small teams. However, its limited toolset for observability, HITL, and error handling at scale makes it less suited for larger systems.
Strengths
- Very approachable API.
- Clear role separation.
- Fast setup.
Limitations
- Lightweight memory.
- Limited production controls.
Best applications
- Content pipelines.
- Market research automation.
- Simple workflow agents.
Semantic Kernel
- Core design: Planner-based orchestration.
- Philosophy: Enterprise-grade AI integration.
Semantic Kernel is another open-source Microsoft framework, designed for building AI-powered applications that integrate with existing enterprise systems.
It was created with production concerns in mind from the start, emphasizing governance, safety, observability, and human oversight. Rather than maximizing agent autonomy, it focuses on making AI predictable, controllable, and auditable.
By combining structured workflows with LLM reasoning, it trades flexibility and emergent behavior for trust, safety, and operational reliability.
Strengths
- Strong HITL support.
- Enterprise-friendly architecture.
- Good observability.
Limitations
- Heavier upfront structure.
- Less flexibility for open-ended autonomy.
- Steeper learning curve.
Best applications
- Internal enterprise tools.
- AI copilots.
- Business process automation.
smolagents
- Core design: Minimalist chain-based.
- Philosophy: Simplicity over scale.
smolagents is a bare-bones framework designed to make agentic AI as straightforward and transparent as possible. It prioritizes simple, readable code that makes it easy to understand how an agent works without needing to learn a large framework.
smolagents aims to make agent behavior accessible and easy to experiment with by keeping abstractions minimal and logic transparent. It offers first-class support for code-based and tool-calling agents, broad model and tool compatibility, and lightweight CLI utilities, while intentionally trading large-scale orchestration and production features for simplicity and clarity.
Strengths
- Extremely lightweight design.
- High degree of transparency.
- Fast experimentation.
Limitations
- Limited suitability for scaling
- Minimal production features.
Best applications
- Educational projects.
- Proofs of concept.
- Lightweight local agents.
OpenAI Agents SDK
- Core design: Managed workflow-driven orchestration (often graph-based).
- Philosophy: Hosted, production-ready agents.
Thanks to ChatGPT's explosion in popularity, we've all heard of OpenAI. The Agents SDK is the company's effort to provide a managed platform for building and running agents without having to maintain your own orchestration infrastructure.
Rather than assembling agents from scratch, you define agent behavior and workflows, while OpenAI provides orchestration, memory management, monitoring, and safety controls. This makes the Agents SDK particularly attractive for teams that want production-ready agents quickly.
Strengths
- Minimal infrastructure burden.
- Built-in safety and observability.
- Strong multi-agent support.
Limitations
- Reduced customization and control.
- Limited suitability for experimental research.
Best applications
- SaaS agent features.
- Customer-facing autonomous systems.
- Teams prioritizing speed over customization.
Phidata
- Core design: Agent-centric, tool-heavy.
- Philosophy: Practical agents for real-world data tasks.
Phidata is designed for building practical, tool-driven AI agents that operate on real-world data.
Rather than focusing on abstract orchestration patterns, Phidata centers the agent around direct interaction with systems such as APIs, databases, and internal services.
Its design reflects the fact that many agents spend most of their time fetching, transforming, and acting on data.
Strengths
- Strong tool integration.
- Suitability for data-centric workflows.
Limitations
- Less emphasis on orchestration.
- Limited multi-agent capabilities.
Best applications
- Data analysis agents.
- Finance and ops automation.
- Tool-driven decision systems.
Choosing the right framework
Now that you're familiar with many of the most popular frameworks in 2026, it's time to choose the right one for your project. Let's take a look at some of the key use cases, along with the frameworks that fit them best.
| Orchestration model | Where to use | Recommended frameworks |
| Graph-based | Projects involving complex branching logic and requiring high levels of reliability, auditability, and control. | LangGraph, OpenAI Agents SDK |
| Role-based | Projects involving rapid development and intuitive design that benefit from emergent collaboration between agents. | AutoGen, CrewAI |
| Chain-based | Projects requiring maximum flexibility, where agents need to adapt dynamically and determine next steps autonomously. | LangChain |
| Retrieval-based | Projects where deep, reliable access to knowledge matters more than high levels of autonomy. | LlamaIndex, Haystack |
| Enterprise-oriented | Projects where strong governance and human-in-the-loop processes are non-negotiable requirements. | Semantic Kernel |
| Lightweight | Rapid prototyping, educational use, and simple local agents where transparency and control matter more than orchestration complexity. | smolagents |
| Tool-centric | Building production agents that primarily interact with APIs, databases, and external systems rather than complex multi-step orchestration. | Phidata |
In 2026, agentic frameworks have evolved from experimental tools into foundational infrastructure for many applications. The key decision is no longer whether to use agents, but how much control, autonomy, and governance your systems require.
02 Jun 2026 12:12pm GMT
Django community aggregator: Community blog posts
Code is cheap
The first time I said "code is cheap" out loud in a meeting, a manager waved at the budget - headcount, salaries, the tooling line - and asked which part of that looked cheap. He wasn't wrong about the number - he was wrong about what it was buying.

02 Jun 2026 10:15am GMT
01 Jun 2026
Django community aggregator: Community blog posts
My PyCon Italia 2026
A timeline of my PyCon Italia 2026 journey, in Bologna (IT), told through the Mastodon posts I shared along the way.
01 Jun 2026 3:00am GMT
22 May 2026
Planet Twisted
Glyph Lefkowitz: Opaque Types in Python
Let's say you're writing a Python library.
In this library, you have some collection of state that represents "options" or "configuration" for a bunch of operations. Such a set of options is a bundle of potentially ever-increasing complexity. Thus, you will want it to have an extremely minimal compatibility surface, with a very carefully chosen public interface, that is either small, or perhaps nothing at all. Such an object conveys state and might have some private behavior, but all you want consumers to be able to do is build it in very constrained, specific ways, and then pass it along as a parameter to your own APIs.
By way of example, imagine that you're wrapping a library that handles shipping physical packages.
There are a zillion ways to do it ship a package. There are different carriers who can ship it for you. There's air freight, and ground freight, and sea freight. There's overnight shipping. There's the option to require a signature. There's package tracking and certified mail. Suffice it to say, lots of stuff.
If you are starting out to implement such a library, you might need an object called something like ShippingOptions that encapsulates some of this. At the core of your library you might have a function like this:
1 2 3 4 5 |
|
If you are starting out implementing such a library, you know that you're going to get the initial implementation of ShippingOptions wrong; or, at the very least, if not "wrong", then "incomplete". You should not want to commit to an expansive public API with a ton of different attributes until you really understand the problem domain pretty well.
Yet, ShippingOptions is absolutely vital to the rest of your library. You'll need to construct it and pass it to various methods like estimateShippingCost and shipPackage. So you're not going to want a ton of complexity and churn as you evolve it to be more complex.
Worse yet, this object has to hold a ton of state. It's got attributes, maybe even quite complex internal attributes that relate to different shipping services.
Right now, today, you need to add something so you can have "no rush", "standard" and "expedited" options. You can't just put off implementing that indefinitely until you can come up with the perfect shape. What to do?
The tool you want here is the opaque data type design pattern. C is lousy with such things (FILE, pthread_*_t, fd_set, etc). A typedef in a header file can easily achieve this.
But in Python, if you expose a dataclass - or any class, really - even if you keep all your fields private, the constructor is still, inherently, public. You can make it raise an exception or something, but your type checker still won't help your users; it'll still look like it's a normal class.
Luckily, Python typing provides a tool for this: typing.NewType.
Let's review our requirements:
- We need a type that our client code can use in its type annotations; it needs to be public.
- They need to be able to consruct it somehow, even if they shouldn't be able to see its attributes or its internal constructor arguments.
- To express high-level things (like "ship fast") that should stay supported as we add more nuanced and complex configurations in the future (like "ship with the fastest possible option provided by the lowest-cost carrier that supports signature verification").
In order to solve these problems respectively, we will use:
- a public
NewType, which gives us our public name... - which wraps a private class with entirely private attributes, to give us an actual data structure, while not exposing the constructor,
- a set of public constructor functions, which returns our
NewType.
When we put that all together, it looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
As a snapshot in time, this is not all that interesting; we could have just exposed _RealShipOpts as a public class and saved ourselves some time. The fact that this exposes a constructor that takes a string is not a big deal for the present moment. For an initial quick and dirty implementation, we can just do checks like if options._speed == "fast" in our shipping and estimation code.
However, the main thing we are doing here is preserving our flexibility to evolve the related APIs into the future, so let's see how we might do that. For example, let's allow the shipping options to contain a concrete and specific carrier and freight method:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
|
As a NewType, our public ShippingOptions type doesn't have a constructor. Since _RealShipOpts is private, and all its attributes are private, we can completely remove the old versions.
Anything within our shipping library can still access the private variables on ShippingOptions; as a NewType, it's the same type as its base at runtime, so it presents minimal1 overhead.
Clients outside our shipping library can still call all of our public constructors: shipFast, shipNormal, and shipSlow all still work with the same (as far as calling code knows) signature and behavior.
If you need to build and convey some state within your public API, while avoiding breakages associated with compatibility churn, hopefully this technique can help you do that!
Acknowledgments
Thanks for reading, and thank you to my patrons who are supporting my writing on this blog. If you like what you've read here and you'd like to read more of it, or you'd like to support my various open-source endeavors, you can support my work as a sponsor.
-
The overhead is minimal, but it is not completely zero. The suggested idiom for converting to a
NewTypeis to call it like a function, as I've done in these examples, but if you are wanting to use this pattern inside of a hot loop, you can use# type: ignore[return-value]comments to avoid that small cost. ↩
22 May 2026 12:33am GMT
04 Apr 2026
Planet Twisted
Donovan Preston: Using osascript with terminal agents on macOS
Here is a useful trick that is unreasonably effective for simple computer use goals using modern terminal agents. On macOS, there has been a terminal osascript command since the original release of Mac OS X. All you have to do is suggest your agent use it and it can perform any application control action available in any AppleScript dictionary for any Mac app. No MCP set up or tools required at all. Agents are much more adapt at using rod terminal commands, especially ones that haven't changed in 30 years. Having a computer control interface that hasn't changed in 30 years and has extensive examples in the Internet corpus makes modern models understand how to use these tools basically Effortlessly. macOS locks down these permissions pretty heavily nowadays though, so you will have to grant the application control permission to terminal. But once you have done that, the range of possibilities for commanding applications using natural language is quite extensive. Also, for both Safari and chrome on Mac, you are going to want to turn on JavaScript over AppleScript permission. This basically allows claude or another agent to debug your web applications live for you as you are using them.In chrome, go to the view menu, developer submenu, and choose "Allow JavaScript from Apple events". In Safari, it's under the safari menu, settings, developer, "Allow JavaScript from Apple events". Then you can do something like "Hey Claude, would you Please use osascript to navigate the front chrome tab to hacker news". Once you suggest using OSA script in a session it will figure out pretty quickly what it can do with it. Of course you can ask it to do casual things like open your mail app or whatever. Then you can figure out what other things will work like please click around my web app or check the JavaScript Console for errors. Another very important tips for using modern agents is to try to practice using speech to text. I think speaking might be something like five times faster than typing. It takes a lot of time to get used to, especially after a lifetime of programming by typing, but it's a very interesting and a different experience and once you have a lot of practice It starts to to feel effortless.
04 Apr 2026 1:31pm GMT
16 Mar 2026
Planet Twisted
Donovan Preston: "Start Drag" and "Drop" to select text with macOS Voice Control
I have been using macOS voice control for about three years. First it was a way to reduce pain from excessive computer use. It has been a real struggle. Decades of computer use habits with typing and the mouse are hard to overcome! Text selection manipulation commands work quite well on macOS native apps like apps written in swift or safari with an accessibly tagged webpage. However, many webpages and electron apps (Visual Studio Code) have serious problems manipulating the selection, not working at all when using "select foo" where foo is a word in the text box to select, or off by one errors when manipulating the cursor position or extending the selection. I only recently expanded my repertoire with the "start drag" and "drop" commands, previously having used "Click and hold mouse", "move cursor to x", and "release mouse". Well, now I have discovered that using "start drag x" and "drop x" makes a fantastic text selection method! This is really going to improve my speed. In the long run, I believe computer voice control in general is going to end up being faster than WIMP, but for now the awkwardly rigid command phrasing and the amount of times it misses commands or misunderstands commands still really holds it back. I've been learning the macOS Voice Control specific command set for years now and I still reach for the keyboard and mouse way too often.
16 Mar 2026 11:04am GMT