Repository navigation
v0.4.0 Gradients That Reach the End
v0.4.0 - 2026-10-08 | Gradients that reach the end
Breaking
-
Importing
rich_gradientno longer installs Rich's pretty traceback handler
(it previously replacedsys.excepthookprocess-wide as an import side
effect). Programs run identically; only uncaught-exception formatting
reverts to Python's default unless you opt in.Migration — either call the new helper once at startup:
import rich_gradient rich_gradient.install_tracebacks() # accepts rich.traceback.install kwargs
or set
RICH_GRADIENT_TRACEBACKS=1in the environment to restore the old
automatic behavior with no code changes.
Added
- A
DocsGitHub Actions workflow builds the site with Zensical and deploys it
to GitHub Pages on every push tomain(or on demand).zensical.tomlnow sets
site_urlso canonical links and instant navigation resolve correctly. - CI now runs the test suite on Python 3.11, 3.12, 3.13, and 3.14 (using
uv
with the locked dependencies) and has a separate job that builds the docs. - Docs are now built with Zensical (
zensical.toml),
using the classic theme variant with the Astral light/dark palettes, Inter
and Roboto Mono fonts, and an animated rainbow accent (header title, links,
active navigation, and heading underline). It respects
prefers-reduced-motion. - Guide pages for
Table,Tree,Columns,Pretty, andSyntax(docs/table.md,
tree.md,columns.md,pretty.md,syntax.md), each with runnable examples
and a link to its reference page. They appear under the User Guide. examples/renderables_that_work.pyrenders every rich-gradient renderable,
reports which ones work, and saves a compact summary table to
docs/img/renderables-that-work.svg. It replacesgradient-table.svgin the
Gradient docs.- Test coverage for color parsing precedence (
tests/test_color_parsing.py),
thehuesminimum across every renderable (tests/test_hues.py), the derived
repeat_scale(tests/test_repeat_scale.py), configuration loading and
validation (tests/test_config.py), emptyGradientoutput, andGradient
accepting tuples and generators of renderables.
Changed
-
The documentation moved from MkDocs to Zensical.
mkdocs.ymlis gone;
configuration lives inzensical.toml. Useuv run zensical serveto preview
anduv run zensical build --cleanto build (replacinguv run mkdocs serve
anduv run mkdocs build). Themkdocsandmkdocs-materialdev
dependencies were removed;mkdocstringsis still used for the API
reference.CLAUDE.md, the Copilot instructions, and.readthedocs.yamlwere
updated to match. -
Color strings are now parsed with Rich's own parser first, falling back to
rich-color-ext(CSS names and 3-digit hex) only when Rich rejects them.
Names Rich defines keep Rich's meaning, so"red"is ANSI red (#800000)
rather than CSS red (#ff0000); use"#ff0000"for pure red. CSS-only names
such as"tomato"are unaffected. Requiresrich-color-ext>=3.0.0. -
huesnow has a minimum of 2 everywhere.Gradient(and the renderables built
on it) previously clamped smaller values up to 2 silently, andTextonly
rejected them when it had to auto-generate colors. All of them now raise
ValueErrorforhues < 2, matchingSpectrum. -
Configuration loading is stricter and quieter. Invalid
animatevalues,
uncolorable palette entries, and malformed config files are ignored with a
logged warning instead of raising later (or, forRICH_GRADIENT_ANIMATE,
silently disabling animation on a typo). AcceptedRICH_GRADIENT_ANIMATE
values now include0,false,no, andoff.~in
RICH_GRADIENT_HOME_DIRis expanded. -
The default palette entry
hotpink(#FF00AA) is now namedpink, matching
the fallback palette inspectrum.py. If your config file overrides
hotpink, rename the key topink; otherwise both entries are kept and the
palette grows to 18 colors. -
rich-color-ext>=3.0.0is now required, andzensicaljoins the dev
dependencies. -
The docs stylesheets were cleaned up: a stray
body { background: #000 },
unrelated button-animation rules, and dark-only table rules that applied in
light mode were removed, and code blocks now use the theme's code colors. -
Corrected stale docstrings and documentation:
vertical_justifyaccepts
"middle"(not"center"),Textbackground colors usebg_colors(docs
previously saidbgcolors), and default values inPanel/
AnimatedGradientdocstrings now match their signatures.
Fixed
-
Gradients now reach their first and last colors.
repeat_scaledefaults to
Noneand is derived from the color stops (1.0for two colors,2.0for
three or more, with a background gradient mirrored to share the same period).
PreviouslyGradientdefaulted to2.0, which stopped halfway through a
two-color gradient, andMarkdowndefaulted to4.0, which only reached the
second color. This changes the look of existingGradient,Panel,Rule,
Markdown,Table,Tree,Columns,Pretty, andSyntaxoutput; pass an
explicitrepeat_scaleto keep the old spread. The animated renderables keep
their explicit defaults. -
Gradientnow accepts a tuple or generator of renderables, as documented,
instead of raisingNotRenderableError. Lists, tuples, and iterators are
treated as several renderables; strings and single renderables (including
rich.text.Text) stay whole.AnimatedGradientno longer replaces an empty
renderable with an empty list via a truthiness check. -
Gradient("")(and anyGradientmade only of empty text) now prints a blank
line, exactly likeconsole.print(""), instead of printing nothing. A
Gradientwith no renderables at all still prints nothing, like an empty
RichGroup. -
Ruleonly converts genuine color errors (ColorParseError,TypeError)
intoValueError, with the messageInvalid color for Rule: .... Other
errors, such as an invalidhues, now propagate with their own message
instead of being reported as "Invalid color provided". -
Now requires
rich-color-ext>=3.0.0._color_ext.pyimportsget_css_map,
installandis_installeddirectly and drops the compatibility fallbacks
and thesys.excepthooksnapshot/restore that only older releases needed. -
The duplicated "install if needed" checks in
__init__,configand
spectrumare replaced by a singleensure_installed()helper. -
Color parsing is now Rich-first, matching rich-color-ext 3.0: Rich's own
parser runs first and CSS names / 3-digit hex are only tried when Rich rejects
the input. Names that Rich also defines now resolve to Rich's ANSI palette
instead of the CSS value, for gradient colors andStylestrings alike
(redis#800000, not#ff0000). Ten names are affected:red,blue,
yellow,cyan,magenta,white,purple,violet,orchidandtan;
use a hex code (e.g.#ff0000) for the exact CSS value. A bareabc(no#)
is no longer accepted as hex.
Fixed
-
Gradient color stops (
Text,Gradient,Spectrum) are resolved through
parse_color(), which tries Rich first and then falls back to CSS names and
#abchex itself. CSS names such astomatotherefore keep working if the
patch was removed withrich_color_ext.uninstall(), instead of raising
ColorParseError. -
get_logger(enabled=True)no longer callsloguru.logger.remove(), which
destroyed every handler the host application had configured. It now tracks
and removes only its own sinks, filters them torich_gradientrecords so
application logs cannot leak in, and defaults its log directory to
~/.rich-gradient/logsinstead of creating./logsin the current working
directory. -
Panelno longer crashes whenstyleis passed as arich.style.Style
instance instead of a string. -
Ruleaccepts being constructed with no title (Rule()), matching
AnimatedRuleand Rich's ownRule. -
AnimatedRulenow uses its faster phase speed when animation is enabled via
the global config, not only whenanimate=Trueis passed explicitly. -
Rulereports an accurate error message for out-of-rangethicknessvalues. -
Removed the unused
requestsruntime dependency.