Skip to main content

Colorize Different.

Project description

coloredstrings

Python package PyPI Downloads PyPI version Supported Python versions Licence Code style: Ruff

Do more. Type less. Colorize different.


coloredstrings is a small utility for expressive terminal colors and text styles. It exposes a fluent, chainable API for styling strings - similar to the yachalk package, and can act as a drop-in replacement.

Example:

from coloredstrings import style

print(style.bold.underline.red("Error:"), "Something went wrong.")
print(style.blue.bold("Info:"), "Everything is OK")
print(style.italic.green("Success!"))

Colored examples


Features

  • No dependencies
  • Composing styles in a chainable way
  • Nested colors and no nested styling bug
  • NO_COLOR & FORCE_COLOR support
  • Support for 16-color, 256-color, and 24-bit (truecolor / RGB / hex) modes
  • Auto-detection of terminal color capabilities
  • Friendly auto-complete API
  • Ability to call style methods on strings directly (with some black magic help)

Installation

Stable release from PyPI:

pip install coloredstrings

Latest development version:

pip install git+https://github.com/samedit66/coloredstrings.git

Optional: enable the experimental str-patching feature

The package includes an experimental feature that patches Python's built-in str type so you can call style methods directly on string literals (for example, "text".red). This is not enabled by default. To install the optional patched build, run:

pip install "coloredstrings[patched]"

This extra depends on the forbiddenfruit package to attach methods to str at runtime — see Limitations below.


Quick start

Run the bundled demo:

python -m coloredstrings

Examples using the style object:

from coloredstrings import style

print(style.bold.underline.red("Error:"), "Something went wrong.")
print(style.blue.bold("Info:"), "Everything is OK")
print(style.italic.green("Success!"))

Multi-argument and separator support:

# style(...) accepts multiple arguments (stringable values) and a `sep` argument like `print`:
print(style.green("That's", "great!"))
print(style.blue(1, 3.14, True, sep=", "))

Nesting and combining styles:

print(style.red(f"Hello {style.underline.on.blue('world')}!"))

print(
    style.green(
        "I am a green line " +
        style.blue.underline.bold("with a blue substring") +
        " that becomes green again!"
    )
)

24-bit RGB / hex and 256-color:

print(style.rgb(123, 45, 200)("custom"))
print(style.hex("#aabbcc")("hex is also supported"))
print(style.color256(37)("256-color example"))

Define theme helpers:

error = style.bold.red
warning = style.hex("#FFA500")

print(error("Error!"))
print(warning("Warning!"))

style and StyleBuilder - API details

style is a convenience global instance of StyleBuilder. It provides a chainable API for composing foreground color, background color (via the .on helper), and text attributes.

Key behaviour

  • style is immutable: chaining returns new StyleBuilder instances — no mutable global color state.
  • style(...) (i.e. StyleBuilder.__call__) accepts either:
    • a single str argument, or
    • multiple arguments which are converted to strings and joined using sep (default is a single space).
  • Color detection: by default the library tries to detect supported color mode (16/256/truecolor) for the current terminal. You can override it with color_mode(). If you want to find out what color mode is detected, use this:
from coloredstrings.color_support import detect_color_support
print(detect_color_support())

Important methods / properties

  • style(...) — apply the composed style to text; accepts *args, sep and mode (explicit ColorMode).
  • style.color_mode(mode: ColorMode) — return a new StyleBuilder that uses the given color mode by default.
  • style.on — a property that toggles the next color to be applied as a background color rather than a foreground. Example:
    style.red.on.white("text")   # red foreground on white background
    style.on.white.red("text")   # white background with red foreground is the same if used correctly;
                                 # typical usage is style.red.on.white(...)
    

Foreground color builders (properties / methods)

16-color names (properties):

black, red, green, yellow, blue, magenta, cyan, white,
bright_black (aliases: gray, grey),
bright_red, bright_green, bright_yellow, bright_blue, bright_magenta, bright_cyan, bright_white

Extended / truecolor helpers (callable methods):

rgb(r, g, b)        # 24-bit RGB foreground
color256(index)     # 256-color foreground (index clamped to 0..255)
hex("#RRGGBB"|"RGB"|... )  # hex shorthand supported

Background selection

Use .on together with a color property or method on the style object: e.g. style.red.on.white("text"), or style.on.rgb(1,2,3)("text").

Text attributes

Properties that add text attributes (they stack; attributes combine instead of overriding):

bold, dim (aliases: faint, dark),
italic, underline,
blink (slow_blink), rapid_blink,
inverse (alias: reverse),
hidden (aliases: concealed),
strike,
framed, encircle (alias: circle),
overline, double_underline

Attribute support varies by terminal. See types.Attribute in the source for start/end ANSI codes and short notes on support.

Chaining semantics (summary)

  • Attributes (bold, italic, underline, etc.) stack: calling .bold.underline applies both.
  • Foreground/background colors are mutually exclusive: the last color-setting operation for foreground replaces previous foreground; same for background.
  • Reapplying the same attribute does not duplicate codes - the builder ensures attributes are applied once.

Isn't patching str un‑Pythonic?

Some time ago I was inspired by the Rust crate text-colorizer — ergonomic, expressive, and pleasant to type. I later discovered colors which uses a similar API. I couldn't find anything like that in Python, so I implemented this approach.

Patching builtins is controversial and can look un‑Pythonic. Libraries like colorama require you to compose ANSI sequences manually:

from colorama import Fore, Style

print(Fore.RED + "error: " + Style.RESET_ALL + "something went wrong")

This works, but it adds visual noise (constants, concatenation, and manual resets). termcolor provides a simpler function-based API:

from termcolor import colored

print(colored("error:", "red"), "something went wrong")

coloredstrings takes a different approach: colors and styles are first-class, readable operations on values. If you enable the optional patching feature, you can also write styles directly on string literals inside a restricted context:

from coloredstrings.patch import colored_strings

# colored_strings() is a context manager that
# temporarily adds style methods to str
with colored_strings():
    print("error:".red, "something went wrong")

# colored_strings() is also a decorator with same mechanics:
# style methods are only available inside the `hello` function
@colored_strings
def hello():
    print("Hello, World!".green.bold.on_white)

This reads more like natural prose and keeps color usage scoped to the values that need it. Maybe it's not for everyone (and because of that the style object exists), but it's pleasant to type.


Limitations

Under the hood coloredstrings[patched] uses forbiddenfruit package, as a result it also has the same limitations:

Forbbiden Fruit is tested on CPython 3.7-3.13. Since Forbidden Fruit is fundamentally dependent on the C API, this library won't work on other python implementations, such as Jython, pypy, etc.


Contributing

I’d love your help to make coloredstrings even better!

  • 💡 Got an idea or found a bug? Open an issue and let’s talk about it
  • 🔧 Want to improve the code? PRs are always welcome! Please include tests for any new behavior.
  • ♻️ Try to keep changes backward-compatible where possible
  • 🎨 Adding new styles or helpers? Don’t forget to update the README and include tests to ensure ANSI - sequences open and close correctly
  • ⭐ If you like this project, consider giving it a star - it really helps others discover it!

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

coloredstrings-2.0.2.tar.gz (17.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

coloredstrings-2.0.2-py3-none-any.whl (20.3 kB view details)

Uploaded Python 3

File details

Details for the file coloredstrings-2.0.2.tar.gz.

File metadata

  • Download URL: coloredstrings-2.0.2.tar.gz
  • Upload date:
  • Size: 17.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.0

File hashes

Hashes for coloredstrings-2.0.2.tar.gz
Algorithm Hash digest
SHA256 8099cd444df87b2db69280b1c600b26a5957633d585badd26138fe4632740716
MD5 d07861757453c6554f9e71743e7bfa2f
BLAKE2b-256 86d6fc67dc351810def8d5f1d5b3793c6077817a8b6abe0844ae30f1dcf2aab9

See more details on using hashes here.

File details

Details for the file coloredstrings-2.0.2-py3-none-any.whl.

File metadata

File hashes

Hashes for coloredstrings-2.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 9de6053f1995d6ca5576a502bf8e2ec449d874fb89547c19b3c777af32c5516e
MD5 2f69fe4e0a6b4be6128d8fbf06e4f945
BLAKE2b-256 d4c97bb84c53bd6aa65462c5acfbf1adadd6261de508163c582a0f11f85c31c2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page