How to Upgrade to v3.0.0¶
v3.0.0 changes how rich-color-ext decides what a color string means. Most
projects upgrade with no code changes, but three behaviors are breaking. This
page shows what changed, how to find affected code, and how to fix it.
1. Upgrade¶
Confirm the installed version:
2. Breaking changes¶
Rich's parser now runs first¶
In v2, CSS color names were checked before Rich's parser. In v3,
rich-color-ext parses with Rich's own Color.parse first and falls back to
rich-color-ext (3-digit hex and the CSS map) only when Rich fails.
Names that both Rich and CSS know now resolve to Rich's color (an ANSI or 256-color value that follows the user's terminal theme), not the CSS truecolor hex.
| Input | v2 | v3 |
|---|---|---|
red |
#ff0000 (truecolor) |
Rich's ANSI red |
orchid |
#da70d6 (truecolor) |
Rich's 256-color orchid |
rebeccapurple |
#663399 |
#663399 (unchanged, Rich rejects it) |
#abc |
#aabbcc |
#aabbcc (unchanged) |
The affected names are those in the CSS map that Rich also accepts, including
black, blue, cyan, green, magenta, orchid, purple, red, tan,
violet, white and yellow.
This order applies to Color.parse only. get_css_map() and the CSSColor helpers
don't consult Rich, so they still return the CSS value (get_css_map()["red"] is
#ff0000).
If you need the exact CSS color, use the hex value directly:
from rich_color_ext import get_css_map
hex_red = get_css_map()["red"] # '#ff0000'
console.print("exact CSS red", style=hex_red)
3-digit hex requires the #¶
09f and abc are no longer parsed, so ordinary words such as bad or add can
never be mistaken for colors. Write #09f and #abc.
is_3digit_hex() and expand_3digit_hex() follow the same rule: they require the
leading #, and expand_3digit_hex("abc") now raises ValueError.
CSS_MAP was removed¶
The import-time CSS_MAP constant is gone. Call get_css_map() instead; it builds
the map on first use and caches it.
# v2
from rich_color_ext import CSS_MAP
# v3
from rich_color_ext import get_css_map
CSS_MAP = get_css_map()
3. Find code that needs changes¶
Search your project for the old patterns:
# bare 3-digit hex without '#', e.g. style="09f" or "[abc]text[/]"
grep -rnE "\[[0-9a-fA-F]{3}\]|\"[0-9a-fA-F]{3}\"" src/
# the removed constant
grep -rn "CSS_MAP" src/
Also review any place you pass the names listed above (red, green, white, ...)
and rely on them being exact CSS truecolors, such as snapshot tests or exported SVG
and HTML.
4. Verify¶
from rich.color import Color, ColorParseError, ColorType
from rich_color_ext import install, uninstall
install()
try:
assert Color.parse("#09F").name == "#0099ff"
assert Color.parse("rebeccapurple").name == "#663399"
assert Color.parse("red").type is ColorType.STANDARD # Rich wins
try:
Color.parse("09f")
except ColorParseError:
print("bare hex rejected, as expected")
finally:
uninstall()
What else is new¶
- Instance calls work.
Color.parse(...)can be called on aColorinstance again; v2 raised aTypeErroronce the patch was installed. - Cached parsing. The patched parser uses
functools.lru_cache, like Rich's own. - Thread-safe install.
install()anduninstall()are serialised with a lock, andis_installed()inspectsColor.parsedirectly. - Lighter import. Importing the package patches nothing, and
Panel,TableandColumnsare only imported when needed. - Exact restore.
uninstall()puts back Rich's originalclassmethod.
Upgrading from v1 or earlier¶
v3 includes everything from v2.0.0: the CLI (rich-color-ext, rich-color) and the
loguru logger were removed, along with the loguru dependency. If you used either,
remove those calls before upgrading. See the
changelog for
the full history.