port: pycountry==26.2.16#177
Conversation
Add pycountry under '# Runtime and typing helpers' in requirements/site-packages-extra.txt, list it in doc/packages.md under a new '### Locale and ISO data' sub-section, and back-fill the missing pluggy row under the existing Base sub-section. New tests/func/test_110_pycountry.py exercises three independent ISO JSON databases (countries, currencies, languages). Closes #111
There was a problem hiding this comment.
Pull request overview
Ports pycountry into the Nanvix CPython distribution as an extra pure-Python package, adds a functional smoke test to validate bundled ISO databases are readable at runtime, and updates the package documentation (including back-filling the missing pluggy entry).
Changes:
- Add
pycountry==26.2.16torequirements/site-packages-extra.txt. - Add
tests/func/test_110_pycountry.pysmoke test covering country/currency/language lookups. - Update
doc/packages.mdto documentpycountryunder a new “Locale and ISO data” subsection and add the missingpluggy 1.6.0row.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
requirements/site-packages-extra.txt |
Adds pycountry==26.2.16 to the extra runtime helper set. |
tests/func/test_110_pycountry.py |
Adds a smoke test validating pycountry lookups (countries/currencies/languages). |
doc/packages.md |
Documents pycountry under a new extra subsection and adds a pluggy row to Base Packages. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Making this a draft and tagging this as "wontfix" because it bloats the ramfs image way more than we can affort. |
|
Closing as wontfix per maintainer feedback: ramfs bloat (~30 MiB / +37 %) exceeds image budget. The bundled tree (~19 MiB of |
|
@ada-x64 keep it open so the branch stays around. |
Closes #111.
What
Adds the
pycountry(26.2.16)ISO country / language / currency / script database wrapper to the
Nanvix CPython port:
pycountry==26.2.16torequirements/site-packages-extra.txtunder the existing Runtime and typing helpers section,
alphabetically between
platformdirsandpython-dotenv.tests/func/test_110_pycountry.py— a single-file smoke test inthe canonical
test_NNN_<pkg>.pyshape (cf.tests/func/test_020_click.py). Three lookups, one per independentdatabase file (
countries.get(alpha_2='US'),currencies.get(alpha_3='EUR'),languages.get(alpha_3='eng')), so amissing or unreadable JSON surfaces as a specific FAIL rather than a
generic import error.
### Locale and ISO datasub-section todoc/packages.mdunder
## Extra Packages(sentence-case, mirroring the existingextra-side heading style); pycountry is the inaugural row.
pluggy 1.6.0row indoc/packages.mdunder## Base Packages→### Core utilities.pluggywas added torequirements/site-packages-base.txtin pluggy: add pluggy==1.6.0 to site-packages-base + smoke test #176 but the documentationrow never landed and the table is meant to be exhaustive.
Four-path diff: one
requirements/line, one new test file, onedoc/packages.mdedit (new sub-section + pluggy back-fill row). Noedits to
.nanvix/,patches/,Modules/Setup.local, or any othermanifest.
Why
pycountryis upstream Tier-2: pure Python (~40 KiB of source, noruntime dependencies,
py3-none-anywheel), but it ships ~20 MiB ofbundled package data (1.4 MiB of ISO JSON databases plus 18.6 MiB of
Debian
iso-codes.motranslation catalogs). Its stdlib surface isjson/os.path/importlib.resources/importlib.metadata/unicodedata/threading/logging— all enabled on Nanvix CPython.The unusual axis is
importlib.resources.files(). pycountry computesLOCALES_DIRandDATABASE_DIRat import time viastr(_importlib_resources.files("pycountry") / "<subdir>")and thenfeeds the resulting path to plain
open(). That assumes theTraversablereturned byfiles()is filesystem-backed; for aMultiplexedPathorZipPaththe cast would yield a stringopen()cannot resolve. Pre-implementation verification across
standalone(ramfs, bytecode-only, dist-info trimmed) and
single-process(Linux-backed VFS) modes confirmed the cast resolves to a real
PosixPathin both — pycountry is a regular package, not a namespacepackage — and that all 7 JSON databases plus all 614
.mofilessurvive
_create_stripped_sysrootand_precompile_pyc. No stdlibgap, no patch, no shim.
Decisions
(
requirements/site-packages-{base,extra}.txt) plus the host-sidepip install --targetstep in.nanvix/z.py. No new.nanvix/pycountry.py, nopatches/pycountry/, no vendored copy.-basevs-extrabucket. Unlike the prior pure-Python siblings(
srt,iniconfig,schedule,pluggy— all <1 MiB and all-base.txt), pycountry ships ~20 MiB of bundled package data. Thatclears the "heavyweight or optional" bar for
-extra.txt.tests/func/test_NNN_<pkg>.pyconvention. pycountry's upstreamtests/suite is intentionally not invoked from here — it testsPython semantics, not the Nanvix port.
NNN = 110chosen asmax+1overtests/func/(previous high watermark:
test_109_pluggy.py).doc/packages.md. New### Locale and ISO datasub-section isthe first locale/ISO-data grouping; pycountry would otherwise have to
squat under an awkwardly-named existing heading. The pluggy row is
back-filled in the same edit because the table is meant to be
exhaustive and the omission was a drift, not a deliberate exclusion.
Caveat: ramfs delta and the bundled locales tree
This is the largest single-package delta in the pure-Python porting
series so far: image grows from 81.1 MiB to 111.2 MiB, a +30.07 MiB /
+37.07 % step. The dominant contribution is the ~19 MB
pycountry/locales/tree (~22 MB upstream wheel; 18.6 MiB on thestaged sysroot after install-time pruning), which ships intact and
deliberate as part of this PR rather than being stripped by a
port-specific carve-out in
.nanvix/z.py.Rationale:
gettextor touches.mofiles; the catalogs are shipped for downstream consumers that want
translated ISO names.
.nanvix/z.pyfor per-package datastripping; introducing one here would set a load-bearing convention
for every subsequent data-bearing port.
the locales tree is unacceptable, a follow-up PR can add a targeted
strip — either as a wholesale
pycountry/locales/removal or as aconfigurable subset. Happy to do that here instead if the reviewer
prefers; flagging the carve-out option explicitly so the decision is
visible rather than implicit.
Test plan
Local verification per
AGENTS.md, all three deployment modes, onthis branch's tip:
(Single-process aggregate captured during a clean-state retry after a
runner-side no-output flake on the first sweep; standalone and
multi-process passed first try without the per-mode aggregate
transcribed.) CI exercises the full platform matrix per
doc/contributing.mdstep 5.Diff scope
requirements/site-packages-extra.txt— +1 line.tests/func/test_110_pycountry.py— new file, ~20 lines.doc/packages.md— new### Locale and ISO datasub-section under## Extra Packageswith the pycountry row; one back-fill row forpluggy 1.6.0under## Base Packages→### Core utilities.No other paths touched.
Ramfs size increase
Measured on a clean tree (standalone mode) via the commit-then-measure
protocol: build at
HEAD~1(baseline, pre-pycountry) then build atHEAD(withpycountrylanded),./z distclean; ./z clean; NANVIX_DEPLOYMENT_MODE=standalone ./z setup; ./z buildbetween each.pycountrynanvix_rootfs.img)Per-tree breakdown of the new payload (
du -sbagainst.nanvix/sysroot/lib/python3.12/site-packages/pycountry/):pycountry/locales/pycountry/databases/pycountry/total installNew ramfs paths (non-locales; the 614
pycountry/locales/<lang>/LC_MESSAGES/iso*.moentries are elided forbrevity):
lib/python3.12/site-packages/pycountry-26.2.16.dist-info/METADATAlib/python3.12/site-packages/pycountry/COPYRIGHT.txtlib/python3.12/site-packages/pycountry/__init__.pyclib/python3.12/site-packages/pycountry/db.pyclib/python3.12/site-packages/pycountry/databases/iso15924.jsonlib/python3.12/site-packages/pycountry/databases/iso3166-1.jsonlib/python3.12/site-packages/pycountry/databases/iso3166-2.jsonlib/python3.12/site-packages/pycountry/databases/iso3166-3.jsonlib/python3.12/site-packages/pycountry/databases/iso4217.jsonlib/python3.12/site-packages/pycountry/databases/iso639-3.jsonlib/python3.12/site-packages/pycountry/databases/iso639-5.jsonpycountry's actual payload is ~20 MiB on disk; the gap to +30 MiB onthe image is
mkramfsblock-alignment overhead, consistent with priordata-bearing ports. Net: +30.07 MiB on a now-111.2 MiB image
(+37.07 % of the previous image, +27.05 % of the new one).
Checklist
Files changedtabletest_NNN_<pkg>.pyconventionpycountry: PASSverified locally in standalone, single-process,and multi-process modes
.nanvix//patches//Modules/Setup.localeditsdoc/packages.mdupdated (new sub-section + pluggy back-fill)