Mouse Vs Python https://www.blog.pythonlibrary.org/ Where You Can Learn All About Python Programming Mon, 16 Mar 2026 19:42:08 +0000 en-US hourly 1 https://wordpress.org/?v=6.9.4 https://www.blog.pythonlibrary.org/wp-content/uploads/2019/05/cropped-narnyish_highres-32x32.png Mouse Vs Python https://www.blog.pythonlibrary.org/ 32 32 Textual – Creating a Custom Checkbox https://www.blog.pythonlibrary.org/2026/03/16/textual-creating-a-custom-checkbox/ Mon, 16 Mar 2026 19:42:08 +0000 https://www.blog.pythonlibrary.org/?p=12754 Textual is a great Python user interface package. Textual lets you create a GUI-like interface in your terminal. You can use many different widgets in Textual. However, the widget you will be focusing on in this tutorial is the humble checkbox. Checkboxes are used for Boolean choices. They return a True if checked and a […]

The post Textual – Creating a Custom Checkbox appeared first on Mouse Vs Python.

]]>
Textual is a great Python user interface package. Textual lets you create a GUI-like interface in your terminal.

You can use many different widgets in Textual. However, the widget you will be focusing on in this tutorial is the humble checkbox.

Checkboxes are used for Boolean choices. They return a True if checked and a False if unchecked. You can use a checkbox as a clear visual cue to indicate whether one or more options are enabled or disabled.

In this tutorial, you will learn the following:

  • How to create a standard checkbox
  • How to customize the checkbox widget

Let’s get started!

How to Create a Standard Checkbox

You should always start with the default widget to see if it works for you. With that in mind, open up your favorite Python IDE and create a new file with the following code in it:

from textual.app import App, ComposeResult
from textual.containers import VerticalScroll
from textual.widgets import Checkbox


class CheckboxApp(App[None]):

    def compose(self) -> ComposeResult:
        with VerticalScroll():
            yield Checkbox("Mike")

    def on_checkbox_changed(self, event: Checkbox.Changed) -> None:
        self.notify(f"Checkbox value: {event.value}")


if __name__ == "__main__":
    CheckboxApp().run()

The example above is based on a code example from the Textual documentation. You don’t have to use a VerticalScroll container here, but it is convenient when adding a series of widgets to the container.

Your main focus should be on the Checkbox itself. Here, you simply yield it from compose(), and then you catch the Checkbox.Changed event. When the event is fired, you display a notification to the user indicating that they have changed the checkbox value.

When you run this code, you will see something like this:

Textual checkbox

However, if you want to make the widget’s borders always visible, then you’ll need to add a border to the widget.

But what if you want the checkbox to be completely empty, too, rather than a greyed-out “X”? That is what you will learn how to do in the next section!

How to Customize the Checkbox Widget

Having a greyed out “X” isn’t necessarily bad thing if you have set up your Textual application to have a lighter background. But if you are using a default or dark background, then you will have some contrast issues.

Many GUI toolkits will show a checkbox as empty for its False state, though, while Textual defaults to a greyed-out “X.” If you want to change the character that is shown or make it an empty box like other toolkits, then you will need to learn how to customize the widget itself.

Fortunately, making a custom widget in Textual is very straightforward. Create a new Python file in your IDE and enter the following code:

from textual.app import App, ComposeResult
from textual.containers import VerticalScroll
from textual.widgets import Checkbox

class CustomCheck(Checkbox):
    BUTTON_INNER = " "

    def toggle(self) -> None:
        if self.value:
            CustomCheck.BUTTON_INNER = " "
        else:
            CustomCheck.BUTTON_INNER = "X"
        self.value = not self.value
        return self


class CheckboxApp(App[None]):
    #CSS_PATH = "checkbox.tcss"

    def compose(self) -> ComposeResult:
        check = CustomCheck("Mike")

        with VerticalScroll():
            yield check

    def on_checkbox_changed(self, event: Checkbox.Changed) -> None:
        self.notify(f"Checkbox value: {event.value}")


if __name__ == "__main__":
    CheckboxApp().run()

When you want to customize a pre-existing widget in Textual, you will almost always subclass it. So here, you subclass the Checkbox class to create a new CustomCheck class. Next, you override the BUTTON_INNER class attribute as well as the toggle() method.

If you go looking at the source code, you will find that BUTTON_INNER defaults to the “X” so here you are defaulting it to an empty string. Then you update toggle() to swap the “X” in when it is checked, and swap it back out when it is unchecked.

The other change is to use the new widget class in your application code.

To increase the widget’s visibility, you can add a border using Textual CSS. Create a new file called checkbox.tcss and add the following code to it:

CustomCheck {
    border: round green;
}

Make sure you save this file in the same folder as your Python file.

Now, when you run this code, you will see the following:

Custom Textual checkbox

Good job! You now have a custom checkbox.

Wrapping Up

Textual is a great way for you to create beautiful user interfaces in your terminal. In this tutorial, you learned how to create a regular checkbox widget and then learned how to create a custom checkbox.

You can apply this knowledge to customize other widgets in Textual. You will need to study the widget’s code closely to understand how it works so you can modify it successfully. You may have to go through several iterations to get exactly what you want.

Don’t give up! You’ll get there eventually, and then you will be proud of yourself for sticking to it!

Learn More

If you thought this article was interesting you and you want to learn more about Textual, check out the following links:

The post Textual – Creating a Custom Checkbox appeared first on Mouse Vs Python.

]]>
Python Typing Book Kickstarter https://www.blog.pythonlibrary.org/2026/02/03/python-typing-book-kickstarter/ Tue, 03 Feb 2026 18:17:00 +0000 https://www.blog.pythonlibrary.org/?p=12748 Python has had type hinting support since Python 3.5, over TEN years ago! However, Python’s type annotations have changed repeatedly over the years. In Python Typing: Type Checking for Python Programmers, you will learn all you need to know to add type hints to your Python applications effectively. You will also learn how to use Python […]

The post Python Typing Book Kickstarter appeared first on Mouse Vs Python.

]]>
Python has had type hinting support since Python 3.5, over TEN years ago! However, Python’s type annotations have changed repeatedly over the years. In Python Typing: Type Checking for Python Programmers, you will learn all you need to know to add type hints to your Python applications effectively.

You will also learn how to use Python type checkers, configure them, and set them up in pre-commit or GitHub Actions. This knowledge will give you the power to check your code and your team’s code automatically before merging, hopefully catching defects before they make it into your products.

Python Typing Book Cover

Support the Book!

What You’ll Learn

You will learn all about Python’s support for type hinting (annotations). Specifically, you will learn about the following topics:

  • Variable annotations
  • Function annotations
  • Type aliases
  • New types
  • Generics
  • Hinting callables
  • Annotating TypedDict
  • Annotating Decorators and Generators
  • Using Mypy for type checking
  • Mypy configuration
  • Using ty for type checking
  • ty configuration
  • and more!

Rewards to Choose From

There are several different rewards you can get in this Kickstarter:

  • A signed paperback copy of the book (See Stretch Goals)
  • An eBook copy of the book in PDF and ePub
  • A t-shirt with the cover art from the book (See Stretch Goals)
  • Other Python eBooks

Kickstart the Book

The post Python Typing Book Kickstarter appeared first on Mouse Vs Python.

]]>
New Book: Vibe Coding Video Games with Python https://www.blog.pythonlibrary.org/2026/01/19/new-book-vibe-coding-video-games-with-python/ Mon, 19 Jan 2026 14:25:39 +0000 https://www.blog.pythonlibrary.org/?p=12743 My latest book, Vibe Coding Video Games with Python, is now available as an eBook. The paperback will be coming soon, hopefully by mid-February at the latest. The book is around 183 pages in length and is 6×9” in size. In this book, you will learn how to use artificial intelligence to create mini-games. You will attempt […]

The post New Book: Vibe Coding Video Games with Python appeared first on Mouse Vs Python.

]]>
My latest book, Vibe Coding Video Games with Python, is now available as an eBook. The paperback will be coming soon, hopefully by mid-February at the latest. The book is around 183 pages in length and is 6×9” in size.

Vibe Coding Video Games with Python

In this book, you will learn how to use artificial intelligence to create mini-games. You will attempt to recreate the look and feel of various classic video games. The intention is not to violate copyright or anything of the sort, but instead to learn the limitations and the power of AI.

Instead, you will simply be learning about whether or not you can use AI to help you know how to create video games. Can you do it with no previous knowledge, as the AI proponents say? Is it really possible to create something just by writing out questions to the ether?

You will use various large language models (LLMs), such as Google Gemini, Grok, Mistral, and CoPilot, to create these games. You will discover the differences and similarities between these tools. You may be surprised to find that some tools give much more context than others.

AI is certainly not a cure-all and is far from perfect. You will quickly discover AI’s limitations and learn some strategies for solving those kinds of issues.

What You’ll Learn

You’ll be creating “clones” of some popular games. However, these games will only be the first level and may or may not be fully functional.

  • Chapter 1 – The Snake Game
  • Chapter 2 – Pong Clone
  • Chapter 3 – Frogger Clone
  • Chapter 4 – Space Invaders Clone
  • Chapter 5 – Minesweeper Clone
  • Chapter 6 – Luna Lander Clone
  • Chapter 7 – Asteroids Clone
  • Chapter 8 – Tic-Tac-Toe
  • Chapter 9 – Pole Position Clone
  • Chapter 10 – Connect Four
  • Chapter 11 – Adding Sprites

Where to Purchase

You can get Vibe Coding Video Games with Python at the following websites:

The post New Book: Vibe Coding Video Games with Python appeared first on Mouse Vs Python.

]]>
How to Type Hint a Decorator in Python https://www.blog.pythonlibrary.org/2026/01/14/how-to-type-hint-a-decorator-in-python/ Wed, 14 Jan 2026 17:04:47 +0000 https://www.blog.pythonlibrary.org/?p=12734 Decorators are a concept that can trip up new Python users. You may find this definition helpful: A decorator is a function that takes in another function and adds new functionality to it without modifying the original function. Functions can be used just like any other data type in Python. A function can be passed […]

The post How to Type Hint a Decorator in Python appeared first on Mouse Vs Python.

]]>
Decorators are a concept that can trip up new Python users. You may find this definition helpful: A decorator is a function that takes in another function and adds new functionality to it without modifying the original function.

Functions can be used just like any other data type in Python. A function can be passed to a function or returned from a function, just like a string or integer.

If you have jumped on the type-hinting bandwagon, you will probably want to add type hints to your decorators. That has been difficult until fairly recently.

Let’s see how to type hint a decorator!

Type Hinting a Decorator the Wrong Way

You might think that you can use a TypeVar to type hint a decorator. You will try that first.

Here’s an example:

from functools import wraps
from typing import Any, Callable, TypeVar


Generic_function = TypeVar("Generic_function", bound=Callable[..., Any])

def info(func: Generic_function) -> Generic_function:
    @wraps(func)
    def wrapper(*args: Any, **kwargs: Any) -> Any:
        print('Function name: ' + func.__name__)
        print('Function docstring: ' + str(func.__doc__))
        result = func(*args, **kwargs)
        return result
    return wrapper

@info
def doubler(number: int) -> int:
    """Doubles the number passed to it"""
    return number * 2

print(doubler(4))

If you run mypy —strict info_decorator.py you will get the following output:

info_decorator.py:14: error: Incompatible return value type (got "_Wrapped[[VarArg(Any), KwArg(Any)], Any, [VarArg(Any), KwArg(Any)], Any]", expected "Generic_function")  [return-value]
Found 1 error in 1 file (checked 1 source file)

That’s a confusing error! Feel free to search for an answer.

The answers that you find will probably vary from just ignoring the function (i.e. not type hinting it at all) to using something called a ParamSpec.

Let’s try that next!

Using a ParamSpec for Type Hinting

The ParamSpec is a class in Python’s typing module. Here’s what the docstring says about ParamSpec:

class ParamSpec(object):
  """ Parameter specification variable.
  
  The preferred way to construct a parameter specification is via the
  dedicated syntax for generic functions, classes, and type aliases,
  where the use of '**' creates a parameter specification::
  
      type IntFunc[**P] = Callable[P, int]
  
  For compatibility with Python 3.11 and earlier, ParamSpec objects
  can also be created as follows::
  
      P = ParamSpec('P')
  
  Parameter specification variables exist primarily for the benefit of
  static type checkers.  They are used to forward the parameter types of
  one callable to another callable, a pattern commonly found in
  higher-order functions and decorators.  They are only valid when used
  in ``Concatenate``, or as the first argument to ``Callable``, or as
  parameters for user-defined Generics. See class Generic for more
  information on generic types.
  
  An example for annotating a decorator::
  
      def add_logging[**P, T](f: Callable[P, T]) -> Callable[P, T]:
          '''A type-safe decorator to add logging to a function.'''
          def inner(*args: P.args, **kwargs: P.kwargs) -> T:
              logging.info(f'{f.__name__} was called')
              return f(*args, **kwargs)
          return inner
  
      @add_logging
      def add_two(x: float, y: float) -> float:
          '''Add two numbers together.'''
          return x + y
  
  Parameter specification variables can be introspected. e.g.::
  
      >>> P = ParamSpec("P")
      >>> P.__name__
      'P'
  
  Note that only parameter specification variables defined in the global
  scope can be pickled.
   """

In short, you use a ParamSpec to construct a parameter specification for a generic function, class, or type alias.

To see what that means in code, you can update the previous decorator to look like this: 

from functools import wraps
from typing import Callable, ParamSpec, TypeVar


P = ParamSpec("P")
R = TypeVar("R")

def info(func: Callable[P, R]) -> Callable[P, R]:
    @wraps(func)
    def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
        print('Function name: ' + func.__name__)
        print('Function docstring: ' + str(func.__doc__))
        return func(*args, **kwargs)
    return wrapper

@info
def doubler(number: int) -> int:
    """Doubles the number passed to it"""
    return number * 2

print(doubler(4))

Here, you create a ParamSpec and a TypeVar. You tell the decorator that it takes in a Callable with a generic set of parameters (P), and you use TypeVar (R) to specify a generic return type.

If you run mypy on this updated code, it will pass! Good job!

What About PEP 695?

PEP 695 adds a new wrinkle to adding type hints to decorators by updating the parameter specification in Python in 3.12.

The main thrust of this PEP is to “simplify” the way you specify type parameters within a generic class, function, or type alias.

In a lot of ways, it does clean up the code as you no longer need to import ParamSpec of TypeVar when using this new syntax. Instead, it feels almost magical.

Here’s the updated code:

from functools import wraps
from typing import Callable


def info[**P, R](func: Callable[P, R]) -> Callable[P, R]:
    @wraps(func)
    def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
        print('Function name: ' + func.__name__)
        print('Function docstring: ' + str(func.__doc__))
        return func(*args, **kwargs)
    return wrapper

@info
def doubler(number: int) -> int:
    """Doubles the number passed to it"""
    return number * 2

print(doubler(4))

Notice that at the beginning of the function you have square brackets. That is basically declaring your ParamSpec implicitly. The “R” is again the return type. The rest of the code is the same as before.

When you run mypy against this version of the type hinted decorator, you will see that it passes happily.

Wrapping Up

Type hinting can still be a hairy subject, but the newer the Python version that you use, the better the type hinting capabilities are.

Of course, since Python itself doesn’t enforce type hinting, you can just skip all this too. But if your employer like type hinting, hopefully this article will help you out.

Related Reading

The post How to Type Hint a Decorator in Python appeared first on Mouse Vs Python.

]]>
How to Switch to ty from Mypy https://www.blog.pythonlibrary.org/2026/01/09/how-to-switch-to-ty-from-mypy/ Fri, 09 Jan 2026 15:16:16 +0000 https://www.blog.pythonlibrary.org/?p=12738 Python has supported type hinting for quite a few versions now, starting way back in 3.5. However, Python itself does not enforce type checking. Instead, you need to use an external tool or IDE. The first and arguably most popular is mypy. Microsoft also has a Python type checker that you can use in VS Code […]

The post How to Switch to ty from Mypy appeared first on Mouse Vs Python.

]]>
Python has supported type hinting for quite a few versions now, starting way back in 3.5. However, Python itself does not enforce type checking. Instead, you need to use an external tool or IDE. The first and arguably most popular is mypy.

Microsoft also has a Python type checker that you can use in VS Code called Pyright, and then there’s the lesser-known Pyrefly type checker and language server.

The newest type checker on the block is Astral’s ty, the maker of Ruff. Ty is another super-fast Python utility written in Rust.

In this article, you will learn how to switch your project to use ty locally and in GitHub Actions.

Installation

You can run ty with uvx if you do not want to install it by using the following command in your terminal: uvx ty

To install ty with uv, run the following:

uv tool install ty@latest

If you do not want to use uv, you can use the standalone installer. Instructions vary depending on your platform, so it is best to refer to the documentation for the latest information.

Note: Technically, you can use pip or pipx to install ty as well.

Running ty Locally

Once you have ty installed, you can run it using any of the following:

Running with uv

uv run ty

Running without Installation

uvx ty

Running ty Directly

ty check

Configuring ty

You can configure ty using either of the following:
  • pyproject.toml
  • ty.toml

There are many rules that you can change. Check out the documentation for full details.

In general, if you run mypy in strict mode, then running ty without changing any of its settings is very similar. However, ty currently does not highlight missing type hints. If you need to enforce adding type hints, you can use Ruff’s flake8-annotations.

Here is how to enable the flak8-annotations in your pyproject.toml file:

Using Flake8 annotations in Ruff

If you have other rules already selected, you can add “ANN” to the end of the list to enable it.

Running ty in GitHub Actions

Running ty in GitHub Actions is a great, free way to type-check your PRs. To add ty to GitHub Actions, create a new file named ty.yml in your GitHub repo in the following location:

.github/workflows/ty.yml

Make sure you include the leading period!

Next, inside your yaml file, you will add the following code:

name: ty
on:
  pull_request:
    types: [opened, synchronize, reopened, ready_for_review]
  workflow_dispatch:
jobs:
  build:
    if: github.event.pull_request.draft == false
    runs-on: self-hosted
    steps:
      - uses: actions/checkout@v3
      - name: Install Python
        uses: actions/setup-python@v4
        with:
          python-version: “3.12”
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install ty==0.0.7      
      - name: Run ty
        run: ty check
        continue-on-error: false

Now, when your team opens a new PR in your project, it will automatically run ty against it. Feel free to update the Python version to the one you are using. Also note that this GitHub Action sets the ty version to 0.0.7, which you may need to update as newer releases become available.

Using ty with pre-commit

The ty project does not have official support for pre-commit yet. However, there is a ticket to add this functionality. In the meantime, several other people have provided their own workarounds to allow you to use ty with pre-commit:

When Astral supports pre-commit itself, you should update your pre-commit configuration accordingly.

However, for this tutorial, you can use that first link which tells you to add the following to your .pre-commit-config.yaml:

Using ty in pre-commit

Now, when you commit a file locally, pre-commit will run ty to check it for you automatically.

Wrapping Up

Type checkers can be really helpful in finding subtle bugs in your Python code. However, remembering to run them before pushing your code can be difficult, so make your life easier by adding the type checker to your CI!

 

Have fun and happy coding!

The post How to Switch to ty from Mypy appeared first on Mouse Vs Python.

]]>
ANN: Vibe Coding Video Games with Python https://www.blog.pythonlibrary.org/2025/12/01/ann-vibe-coding-video-games-with-python/ Mon, 01 Dec 2025 16:11:24 +0000 https://www.blog.pythonlibrary.org/?p=12725 I am happy to announce my latest book, Vibe Coding Video Games with Python. Here’s the announcement from my Kickstarter: Welcome to Vibe Coding Video Games with Python. In this book, you will learn how to use artificial intelligence to create mini-games. You will attempt to recreate the look and feel of various classic video […]

The post ANN: Vibe Coding Video Games with Python appeared first on Mouse Vs Python.

]]>
I am happy to announce my latest book, Vibe Coding Video Games with Python. Here’s the announcement from my Kickstarter:

Welcome to Vibe Coding Video Games with Python. In this book, you will learn how to use artificial intelligence to create mini-games. You will attempt to recreate the look and feel of various classic video games. The intention is not to violate copyright or anything of the sort, but instead to learn the limitations and the power of AI.

Instead, you will simply be learning about whether or not you can use AI to help you know how to create video games. Can you do it with no previous knowledge, as the AI proponents say? Is it really possible to create something just by writing out questions to the ether?

Release date: January 2026 (eBook) / March 2026 (paperback)

You will be using various large language models (LLMs) such as Google Gemini, Grok, Mistral, CoPilot, and others to create these games. You will discover the differences and similarities between these tools. You may be surprised to find that some tools give much more context than others.

AI is certainly not a cure-all and is far from perfect. You will quickly discover AI’s limitations and learn some strategies for solving those kinds of issues.

Here are some examples of what you will be creating in this book:

Lune Lander Clone

Asteroids Clone

Pong Clone

What You’ll Learn

You’ll be creating “clones” of some popular games. However, these games will only be the first level and may or may not be fully functional.

  • Chapter 1 – The Snake Game
  • Chapter 2 – Pong Clone
  • Chapter 3 – Frogger Clone
  • Chapter 4 – Space Invaders Clone
  • Chapter 5 – Minesweeper Clone
  • Chapter 6 – Luna Lander Clone
  • Chapter 7 – Asteroids Clone
  • Chapter 8 – Tic-Tac-Toe
  • Chapter 9 – Pole Position Clone
  • Chapter 10 – Connect Four
  • Chapter 11 – Intro to Sprites

Rewards to Choose From

There are several different rewards you can get in this Kickstarter:

  • A signed paperback copy of the book
  • An eBook copy of the book in PDF and ePub
  • A t-shirt with the cover art from the book
  • Other Python eBooks

Support the Kickstarter Today

The post ANN: Vibe Coding Video Games with Python appeared first on Mouse Vs Python.

]]>
Black Friday Python Deals Came Early https://www.blog.pythonlibrary.org/2025/11/18/black-friday-python-deals-came-early/ https://www.blog.pythonlibrary.org/2025/11/18/black-friday-python-deals-came-early/#comments Tue, 18 Nov 2025 13:41:56 +0000 https://www.blog.pythonlibrary.org/?p=12721 Black Friday deals came early this year. You can get 50% off of any of my Python books or courses until the end of November. You can use this coupon code at checkout: BLACKISBACK  The following links already have the discount applied: Python eBooks Python 101 Python 201: Intermediate Python The Python Quiz Book Automating […]

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

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

The following links already have the discount applied:

Python eBooks

Python Courses

 

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

]]>
https://www.blog.pythonlibrary.org/2025/11/18/black-friday-python-deals-came-early/feed/ 1
An Intro to Python 3.14’s New Features https://www.blog.pythonlibrary.org/2025/10/09/an-intro-to-python-3-14s-new-features/ https://www.blog.pythonlibrary.org/2025/10/09/an-intro-to-python-3-14s-new-features/#comments Thu, 09 Oct 2025 12:05:18 +0000 https://www.blog.pythonlibrary.org/?p=12710 Python 3.14 came out this week and has many new features and improvements. For the full details behind the release, the documentation is the best source. However, you will find a quick overview of the major changes here. As with most Python releases, backwards compatibility is rarely broken. However, there has been a push to […]

The post An Intro to Python 3.14’s New Features appeared first on Mouse Vs Python.

]]>
Python 3.14 came out this week and has many new features and improvements. For the full details behind the release, the documentation is the best source. However, you will find a quick overview of the major changes here.

As with most Python releases, backwards compatibility is rarely broken. However, there has been a push to clean up the standard library, so be sure to check out what was removed and what has been deprecated. In general, most of the items in these lists are things the majority of Python users do not use anyway.

But enough with that. Let’s learn about the big changes!

Release Changes in 3.14

The biggest change to come to Python in a long time is the free-threaded build of Python. While free-threaded Python existed in 3.13, it was considered experimental at that time. Now in 3.14, free-threads are officially supported, but still optional.

Free-threaded Python is a build option in Python. You can turn it on if you want to when you build Python. There is still debate about turning free-threading on by default, but that has not been decided at the time of writing of this article.

Another new change in 3.14 is an experimental just-in-time (JIT) compiler for MacOS and Windows release binaries. Currently, the JIT compiler is NOT recommended in production. If you’d like you test it out, you can set  PYTHON_JIT=1 as an environmental variable. When running with JIT enabled, you may see Python perform 10% slower or up to 20% faster, depending on workload.

Note that native debuggers and profilers (gdp and perf) are not able to unwind JIT frames, although Python’s own pdb and profile modules work fine with them. Free-threaded builds do not support the JIT compilter though.

The last item of note is that GPG (Pretty Good Privacy) signatures are  not provided for Python 3.14 or newer versions. Instead, users must use  Sigstore verification materials. Releases have been signed using Sigstore since Python 3.11.

Python Interpreter Improvements

There are a slew of new improvements to the Python interpreter in 3.14. Here is a quick listing along with links:

Let’s talk about the top three a little. Deferred evaluation of annotations refers to type annotations. In the past, the type annotations that are added to functions, classes, and modules were evaluated eagarly. That is no longer the case. Instead, the annotations are stored  in special-purpose annotate functions and evaluated only when necessary with the exception of if from __future__ import annotations is used at the top of the module.

the reason for this change it to improve performance and usability of type annotations in Python. You can use the new annotationlib module to inspect deferred annotations. Here is an example from the documentation:

>>> from annotationlib import get_annotations, Format
>>> def func(arg: Undefined):
...    pass
>>> get_annotations(func, format=Format.VALUE)
Traceback (most recent call last):
  ...
NameError: name 'Undefined' is not defined
>>> get_annotations(func, format=Format.FORWARDREF)
{'arg': ForwardRef('Undefined', owner=<function func at 0x...>)}
>>> get_annotations(func, format=Format.STRING)
{'arg': 'Undefined'}

Another interesting change is the addition of multiple interpreters in the standard library. The complete formal definition of this new feature can be found in PEP 734. This feature has been available in Python for more than 20 years, but only throught the C-API. Starting in Python 3.14, you can now use the new concurrent.interpreters module.

Why would you want to use multiple Python interpreters?

  • They support a more human-friendly concurrency model
  • They provide a true multi-core parallelism

These interpreters provide isolated “processes” that run in parallel with no sharing by default.

Another feature to highlightare the template string literals (t-strings). Full details can be found in PEP 750. Brett Cannon, a core developer of the Python language, posted a good introductory article about these new t-strings on his blog. A template string or t-string is a new mechanism for custom string processing. However, unlike an f-string, a t-string will return an object that represents the static and the interpolated parts of the string.

Here’s a quick example from the documentation:

>>> variety = 'Stilton'
>>> template = t'Try some {variety} cheese!'
>>> type(template)
<class 'string.templatelib.Template'>

>>> list(template)
['Try some ', Interpolation('Stilton', 'variety', None, ''), ' cheese!']

You can use t-strings to sanitize SQL, improve logging, implement custom, lightweight DSLs, and more!

Standard Library Improvements

Python’s standard library has several significant improvements. Here are the ones highlighted by the Python documentation:

If you do much compression in Python, then you will be happy that Python has added Zstandard support in addition to the zip and tar archive support that has been there for many years.

Compressing a string using Zstandard can be accomplished with only a few lines of code:

from compression import zstd
import math

data = str(math.pi).encode() * 20
compressed = zstd.compress(data)
ratio = len(compressed) / len(data)
print(f"Achieved compression ratio of {ratio}")

Another neat addition to the Python standard library is asyncio introspection via a new command-line interface. You can now use the following command to introspect:

  • python -m asyncio ps PID
  • python -m asyncio pstree PID

The ps sub-command  will inspect the given process ID and siplay information about the current asyncio tasks. You will see a task table as output which contains a listing of all tasks, their names and coroutine stacks, and which tasks are awaiting them.

The pstree sub-command will fetch the same information, but it will render them using a visual async call tree instead, which shows the coroutine relationships in a hierarcical format. Ths pstree command is especiialy useful for debugging stuck or long-running async programs.

One other neat update to Python is that the default REPL shell now highlights Python syntax. You can change the color theme using an experimental API _colorize.set_theme() which can be called interactively or in the PYTHONSTARTUP script. The REPL also supports impor tauto-completion, which means you can start typing the name of a module and then hit tab to get it to complete.

Wrapping Up

Python 3.14 looks to be an exciting release with many performance improvements. They have also laid down more framework to continue improving Python’s speed.

The latest version of Python has many other imrpovements to modules that aren’t listed here. To see all the nitty gritty details, check out the What’s New in Python 3.14 page in the documentation.

Drop a comment to let us know what you think of Python 3.14 and what you are excited to see in upcoming releases!

The post An Intro to Python 3.14’s New Features appeared first on Mouse Vs Python.

]]>
https://www.blog.pythonlibrary.org/2025/10/09/an-intro-to-python-3-14s-new-features/feed/ 2
Erys – A TUI for Jupyter Notebooks https://www.blog.pythonlibrary.org/2025/09/15/erys-a-tui-for-jupyter-notebooks/ https://www.blog.pythonlibrary.org/2025/09/15/erys-a-tui-for-jupyter-notebooks/#comments Mon, 15 Sep 2025 12:35:24 +0000 https://www.blog.pythonlibrary.org/?p=12661 Have you ever thought to yourself: “Wouldn’t it be nice to run Jupyter Notebooks in my terminal?” Well, you’re in luck. The new Erys project not only makes running Jupyter Notebooks in your terminal a reality, but Erys also lets you create and edit the notebooks in your terminal! Erys is written using the fantastic […]

The post Erys – A TUI for Jupyter Notebooks appeared first on Mouse Vs Python.

]]>
Have you ever thought to yourself: “Wouldn’t it be nice to run Jupyter Notebooks in my terminal?” Well, you’re in luck. The new Erys project not only makes running Jupyter Notebooks in your terminal a reality, but Erys also lets you create and edit the notebooks in your terminal!

Erys is written using the fantastic Textual package. While Textual handles the front-end in much the same way as your browser would normally do, the jupyter-client handles the backend, which executes your code and manages your kernel.

Let’s spend a few moments learning more about Erys and taking it for a test drive.

Installation

The recommended method of installing Erys is to use the uv package manager.  If you have uv installed, you can run the following command in your terminal to install the Erys application:

$ uv tool install erys

Erys also supports using pipx to install it, if you prefer.

Once you have Erys installed, you can run it in your terminal by executing the erys command.

Using Notebooks in Your Terminal

When you run Erys, you will see something like the following in your terminal:

Erys - New Notebook

This is an empty Jupyter Notebook. If you would prefer to open an existing notebook, you would run the following command:

erys PATH_TO_NOTEBOOK

If you passed in a valid path to a Notebook, you will see one loaded. Here is an example using my Python Logging talk Notebook:

Erys - Load Notebook

You can now run the cells, edit the Notebook and more!

Wrapping Up

Erys is a really neat TUI application that gives you the ability to view, create, and edit Jupyter Notebooks and other text files in your terminal. It’s written in Python using the Textual package.

The full source code is on GitHub, so you can check it out and learn how it does all of this or contribute to the application and make it even better.

Check it out and give it a try!

The post Erys – A TUI for Jupyter Notebooks appeared first on Mouse Vs Python.

]]>
https://www.blog.pythonlibrary.org/2025/09/15/erys-a-tui-for-jupyter-notebooks/feed/ 1
Ep 55 – The Python Show Podcast – The Python Documentary with Paul Everitt https://www.blog.pythonlibrary.org/2025/09/03/ep-55-the-python-show-podcast-the-python-documentary-with-paul-everitt/ Wed, 03 Sep 2025 13:55:11 +0000 https://www.blog.pythonlibrary.org/?p=12698 In this episode, we have special guest Paul Everitt on the show to discuss the new Python Documentary that was released last week. Paul is the head of developer advocacy at JetBrains and a “Python oldster”. We chat about Python – the documentary, Paul’s start in programming as well as with Python, and much, much more! Links Python: […]

The post Ep 55 – The Python Show Podcast – The Python Documentary with Paul Everitt appeared first on Mouse Vs Python.

]]>
In this episode, we have special guest Paul Everitt on the show to discuss the new Python Documentary that was released last week. Paul is the head of developer advocacy at JetBrains and a “Python oldster”.

We chat about Python – the documentary, Paul’s start in programming as well as with Python, and much, much more!

Links

The post Ep 55 – The Python Show Podcast – The Python Documentary with Paul Everitt appeared first on Mouse Vs Python.

]]>