Skip to content

truecell 1.0.0 — the rename release

Choose a tag to compare

@shanikawm shanikawm released this 30 Jul 16:08
· 49 commits to main since this release
25d9180

shanuz is now truecell. Same codebase, renamed and re-verified — the API is the one 0.9.0 shipped. The version moves to 1.0.0 rather than continuing the 0.x line because neither neighbouring number was free on PyPI: shanuz 0.9.0 is the last release under the old name, and truecell 0.9.0 was published from the same code before the rename settled. It is not a maturity claim.

pip install truecell

⚠️ Breaking: there is no compatibility shim

import shanuz will not work, and the top-level class is Truecell, not Shanuz. Every import, skill directory, documentation page and logo asset moved with the name.

shanuz stays on PyPI at 0.9.0 and is not being withdrawn, but it will receive no further releases.

The GitHub repository was renamed in place rather than forked, so stars, forks, issues and pull requests carried over and the old URL redirects — including for git clone and pip install git+…. Existing clones keep working through that redirect, though git remote set-url is worth running.

Fixed

The sdist shipped the tutorial data — and a different amount of it every time. docs/tutorials is a symlink to tutorials/, hatchling follows it, and the tutorials write their intermediates into the directory they live in: BPCells stores, .lazy matrices, R handoff CSVs. .gitignore covers all of those, but an sdist is not built from git, so they were packaged anyway.

The published shanuz 0.9.0 sdist is 23.5 MB against a 0.24 MB wheel for that reason, and a build on a machine that had just run the tutorials produced 63 MB — same version number, different tarball, depending on the disk it was built from. That non-reproducibility was the actual defect; the size was the symptom.

[tool.hatch.build.targets.sdist] now lists its contents explicitly. The sdist is 532 KB. The wheel is unaffected — it was always scoped by packages = ["truecell"]. tests/test_packaging.py builds an sdist and looks inside it, rather than asserting on configuration that would pass just as happily against a broken artifact.

Most figures on the docs site 404'd. MkDocs re-anchors relative paths written in Markdown onto the built page, which under use_directory_urls sits a directory deeper than its source — but it passes raw HTML through untouched, and the vignettes write most figures as <img> inside HTML tables so the R and Python plots sit side by side. 110 of the site's 133 figures were broken, and the ten vignettes built entirely from those tables showed no images at all. A build hook now applies the same rewrite to raw <img src>. The existing figure-existence test only understood Markdown image syntax, so it was blind to 126 of the 149 references it was meant to guard; it now reads both.

The API reference claimed the whole API is exported from the top level. True for eleven of thirteen pages, false for two: 66 of the 73 public generics live only on truecell.generics, so truecell.features(obj) — the call that sentence invites — raises AttributeError.

tutorials/README.md documented only 10 of the 18 tutorials. The eight added in Waves 2 and 3 had no written section. All eight added.

Added

A logo, generated by tools/make_logo.py rather than drawn. The mark is a point cloud whose density traces a lowercase c, for cell — building a picture out of dots is the nod to Georges Seurat, the pointillist the R package is named for. The c is two arcs meeting at the waist in two colours: the two implementations, one shape. It is also the letter the wordmark's own c draws, so the mark is a letter of the name enlarged rather than an ornament beside it.

Ships as a mark, horizontal lockup, wordmark, hex sticker, a simplified single-stroke glyph for sizes below ~48px where the dots silt up, and favicons — each in a light-ground and dark-ground variant.

Agent skills for LLM-assisted work (skills/). Ten skills in the Claude Agent Skills format — plain Markdown with YAML frontmatter, so they work as context for any model. Aimed at the mistakes a model actually makes against this API rather than re-describing the docs: that analysis functions mutate in place and return None (so obj = normalize_data(obj) leaves you holding None), that dims is 0-based, that matrices are features × cells, that the generics are not top-level, and which differences from Seurat are deliberate and must not be "fixed".

Verifying these artifacts

The attached wheel and sdist were rebuilt from the v1.0.0 tag and are byte-identical to the files on PyPI:

Artifact SHA-256
truecell-1.0.0-py3-none-any.whl 58c56e96b09651785a9228295fdd2ba7214bed12d7365fde7622cebd2288a652
truecell-1.0.0.tar.gz 867490a00fdc80eeabf49170cc718f01e5827942ae47a90d900e21c181f14d35

📦 PyPI · 📖 Documentation · 📓 Tutorials · 📝 Full changelog