Skip to main content

Colorize Different.

Project description

coloredstrings

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

Colorize Different

A tiny utility that patches Python's built-in str with convenient ANSI color / style helpers so you can write "hello".red() instead of juggling escape sequences or long constant concatenations. Inspired by the Rust text-colorizer crate — ergonomic, expressive, and surprisingly pleasant to type.


Installation

Stable:

pip install coloredstrings

Latest:

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

Quick start

Run a demo:

python -m coloredstrings

Test in code:

import coloredstrings as cs

# Patched `str` methods are available only within the context
def warn(msg: str) -> None:
    with cs.patched():
        print("warning:".yellow().bold(), msg)

# Same idea, but using a decorator
@cs.patched
def info(msg: str) -> None:
    print("[info]:".blue(), msg)

# If you're brave enough and really want it, you can patch `str` globally
cs.patch()

print("ok".green())
print("warn".yellow().bold())
print("bad".red(), "on green".on_green())

# 24-bit RGB:
print("custom".rgb(123, 45, 200))

# 256-color:
print("teal-ish".color256(37))

# And don't forget to unpatch it afterwards
cs.unpatch()

If you like coloredstrings but fear to patch str globally for some reasons, you can always colorize directly with little help from colors module:

from coloredstrings import colors

print(colors.blue("It's also possible to use `colors` module!"))
print(colors.underline("But it's kinda longer tho..."))

Why use this? Isn't patching str un-Pythonic?

Patching builtins is a controversial choice, and at first glance it may look un-Pythonic. Libraries like colorama require you to import constants and build strings by concatenation:

from colorama import Fore, Style

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

That works fine, but it forces you to manage constants and remember to reset, and your code quickly becomes noisy with + and RESET tokens.

Another example using the termcolor package:

from termcolor import colored

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

termcolor offers a nice function colored with a bunch of arguments, but personally, I still find it lacking.

With coloredstrings the color becomes a readable method on the string itself:

import coloredstrings

# `patched()` patches `str` to have awesome `red()` method
with coloredstrings.patched():
    print("error:".red(), "something went wrong")

This reads more like natural prose and keeps color usage local to the value being displayed.


API

Patch str

  • patch() -- attach methods to str
  • unpatch() -- remove the attached methods
  • patched() -- automatically calls patch() and unpatch() in a given context

Foreground colors (basic & bright)

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

Background helpers

  • on_black() (aliases: on_grey() and on_gray())
  • on_red()
  • on_green()
  • on_yellow()
  • on_blue()
  • on_magenta()
  • on_cyan()
  • on_white()
  • on_bright_black() (aliases: on_bright_grey() and on_bright_gray())
  • on_bright_red()
  • on_bright_green()
  • on_bright_yellow()
  • on_bright_blue()
  • on_bright_magenta()
  • on_bright_cyan()
  • on_bright_white()

24-bit / 256-color helpers

  • rgb(r, g, b) -- 24-bit truecolor foreground (clamped to 0..255)
  • color256(idx) -- 256-color foreground (clamped to 0..255)
  • on_rgb(r, g, b) -- set a 24-bit background color (clamped to 0..255)
  • on_color256(idx) -- set a 256-color background color (clamped to 0..255)

Text attributes / styles

  • bold()
  • dim() (aliases: faint() and dark())
  • italic()
  • underline()
  • blink() (alias: slow_blink())
  • rapid_blink()
  • inverse() (alias: reverse())
  • hidden() (aliases: concealed() and password())
  • strike()

Chaining behavior

One important detail of coloredstrings is how styles and colors combine when you chain methods:

  • "ok".green().bold() vs "ok".bold().green()
    The order does not matter. Both calls produce the same result: green text with bold style.
    Internally, coloredstrings merges the styles into a single escape sequence, so you don’t get duplicated codes.

  • "error".red().blue()
    Only the last foreground color applies. In this case, the text will be blue, not red. Foreground/background colors are mutually exclusive, so the newer one replaces the older one.

  • "title".underline().underline()
    Repeating the same style does not add multiple codes. The library ensures there’s only one underline escape sequence, keeping the output clean and deterministic.

This merging logic makes chained styling predictable: attributes (bold, italic, underline, etc.) stack, while foreground/background colors override each other.


Limitations

Under the hood coloredstrings 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.

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-1.3.0.tar.gz (11.8 kB view details)

Uploaded Source

Built Distribution

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

coloredstrings-1.3.0-py3-none-any.whl (13.9 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for coloredstrings-1.3.0.tar.gz
Algorithm Hash digest
SHA256 3aece6e5f65f4c2c06ca2bfb5ea78027e6d32075e1b8219d2a334a82dc58bbe5
MD5 0f1aae1173aa720072879422144ef157
BLAKE2b-256 589012b19372064d9ca04c0207721de65a086d6ba6f612b6c15a29275139d62d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for coloredstrings-1.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 76afe4628c49c263fd07e988b79e934cc1db9f51496291efc07dbf11f6f32ddc
MD5 5f4d8cfb1edc381f03f983df038a28bb
BLAKE2b-256 48ebfb8b310161903b2733ed69c400afcbbcf00249b6c91005133cdbae9af4aa

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