v6.4.11 — import-cache integrity, OHLC precision, timezone & number-format fixes
What's new
A correctness release. A foreign bytecode recompile can no longer leave a stale, untransformed .pyc that crashes Pyne code at import; high-priced OHLC values keep their mintick-aligned precision instead of collapsing to six significant digits; color.new propagates na and stops mutating shared color constants; the exchange-timezone fallback is no longer cached across runs in the same process; and Pine number-format strings gain sign subpatterns and literal prefix/suffix affixes.
Import & bytecode cache
Stale or foreign .pyc is now detected and healed
Pyne modules are AST-transformed at import time, but a foreign bytecode recompile (pip's post-install compileall, an IDE, or a packaging step) can overwrite the cached .pyc with untransformed bytecode. CPython validates the cache only against source mtime and size, so the stale .pyc was accepted and builtin price series (high, low, ...) stayed raw Source objects, crashing with unsupported operand type(s) for -: 'Source' and 'Source'. A content sentinel (a transform-pipeline hash) is now baked into the transformed AST and marshaled into the .pyc; on load, any Pyne cache whose sentinel is missing or whose pipeline hash differs is dropped and re-transformed. If the stale cache cannot be removed (read-only cache dir), the module is compiled straight from source so the correct bytecode still runs. This replaces the previous mtime-based marker, which could not detect a foreign recompile that landed after a heal. (Reported in #64.)
Data fidelity
OHLC mintick precision preserved for high-priced symbols
The float32 .ohlcv storage adds sub-tick error to OHLC prices, which the runner cleans before a script sees open/high/low/close. The previous clean-up rounded to six significant digits, which for high-priced assets (e.g. BTC around 94000) reaches only one decimal (93898.05 -> 93898.1) and discarded the real mintick-aligned precision, flipping threshold/hysteresis indicators by a bar. Rounding now keeps the finer of six significant digits and the symbol's mintick decimals: large prices recover their exact tick-aligned value, while low prices that carry genuine sub-mintick precision on TradingView are left untouched. The same rounding is applied in request.security() processing.
Time & timezones
Exchange-timezone fallback no longer cached across runs
When a timezone argument is empty, parse_timezone falls back to the exchange timezone (syminfo.timezone), but that result was cached on the empty key. In a process that runs more than one script (e.g. parallel runs, or a long-lived service), the first run's timezone leaked into later runs even after the active symbol changed. Concrete timezone strings are still cached; the exchange-timezone fallback is now resolved fresh on every call.
Library
color.new propagates na and no longer mutates its input
color.new now returns an na color when either the source color or the transparency is na, matching Pine's behavior during warmup. For valid inputs it builds a fresh color, so passing a color constant (or any caller-owned Color) no longer mutates that object when only the transparency should change.
Number-format patterns support sign subpatterns and affixes
Pine number patterns follow Java DecimalFormat. The formatter now parses an optional negative subpattern after ; and preserves literal prefix/suffix affixes (e.g. $, +, R) around the digit pattern, with sign handling kept separate from zero padding — so patterns like "$#,##0.00" or one with a distinct negative subpattern format as they do on TradingView.