Skip to content

gh-133346: Make theming support in _colorize extensible #133347

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 21 commits into from
May 5, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add blurb and some docstrings
  • Loading branch information
ambv committed May 4, 2025
commit 0866fd8a0f22a9df26532625bda4bf0c2be4272f
55 changes: 55 additions & 0 deletions Lib/_colorize.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,34 @@ class ANSIColors:
setattr(NoColors, attr, "")


#
# Experimental theming support (see gh-133346)
#

# - create a theme by copying an existing `Theme` with one or more sections
# replaced, using `default_theme.copy_with()`;
# - create a theme section by copying an existing `ThemeSection` with one or
# more colors replaced, using for example `default_theme.repl.copy_with()`;
# - create a theme from scratch by instantiating a `Theme` data class with
# the required sections (with are also dataclass instances).
#
# Then call `_colorize.set_theme(your_theme)` to set it.
#
# Put your theme configuration in $PYTHONSTARTUP for the interactive shell,
# or sitecustomize.py in your virtual environment or Python installation for
# other uses. Your applications can call `_colorize.set_theme()` too.
#
# Note that thanks to the dataclasses providing default values for all fields,
# creating a new theme or theme section from scratch is possible without
# specifying all keys.


class ThemeSection(Mapping[str, str]):
"""A mixin/base class for theme sections.

It enables dictionary access to a section, as well as implements convenience
methods.
"""
__dataclass_fields__: ClassVar[dict[str, Field[str]]]
_name_to_value: Callable[[str], str]

Expand Down Expand Up @@ -145,6 +172,11 @@ class Unittest(ThemeSection):

@dataclass(frozen=True)
class Theme:
"""A suite of themes for all sections of Python.

When adding a new one, remember to also modify `copy_with` and `no_colors`
below.
"""
repl: REPL = field(default_factory=REPL)
traceback: Traceback = field(default_factory=Traceback)
unittest: Unittest = field(default_factory=Unittest)
Expand All @@ -156,13 +188,24 @@ def copy_with(
traceback: Traceback | None = None,
unittest: Unittest | None = None,
) -> Self:
"""Return a new Theme based on this instance with some sections replaced.

Themes are immutable to protect against accidental modifications that
could lead to invalid terminal states.
"""
return type(self)(
repl=repl or self.repl,
traceback=traceback or self.traceback,
unittest=unittest or self.unittest,
)

def no_colors(self) -> Self:
"""Return a new Theme where colors in all sections are empty strings.

This allows writing user code as if colors are always used. The color
fields will be ANSI color code strings when colorization is desired
and possible, and empty strings otherwise.
"""
return type(self)(
repl=self.repl.no_colors(),
traceback=self.traceback.no_colors(),
Expand Down Expand Up @@ -232,6 +275,18 @@ def get_theme(
force_color: bool = False,
force_no_color: bool = False,
) -> Theme:
"""Returns the currently set theme, potentially in a zero-color variant.

In cases where colorizing is not possible (see `can_colorize`), the returned
theme contains all empty strings in all color definitions.
See `Theme.no_colors()` for more information.

It is recommended not to cache the result of this function for extended
periods of time because the user might influence theme selection by
the interactive shell, a debugger, or application-specific code. The
environment (including environment variable state and console configuration
on Windows) can also change in the course of the application life cycle.
"""
if force_color or (not force_no_color and can_colorize(file=tty_file)):
return _theme
return theme_no_color
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added experimental color theming support to the ``_colorize`` module.
Loading
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy