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!"))

alt text


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.1.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.1-py3-none-any.whl (20.3 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: coloredstrings-2.0.1.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.1.tar.gz
Algorithm Hash digest
SHA256 16576e6edd2dbc0cfe1d9fa26a6c68efdbb1cf2963b5e9769b94c7b76c9ee174
MD5 5df0d2fdddd2dfce336590f0c282ee1c
BLAKE2b-256 dd9cf80eb60af1ce01901b0e90c46cab2e84eb67869b49379951fdf69a445c9b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for coloredstrings-2.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 0cedf9be682fac65bd3a9ee8c29926f1b98a0e0066e9fc9dc588c6f8f39fbc86
MD5 889405bf372fd1371acfc71d852bbf02
BLAKE2b-256 f54d0e17db238177fef41d1cbb895b09ea815e6a15afc981d75e2db961c9f379

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