Guidance for working in this repository.
HuggingFaceDatasets.jl is a (non-official) Julia wrapper around the Python
datasets library from Hugging Face.
It exposes Hugging Face datasets to Julia by wrapping the Python objects with
PythonCall.jl and adding Julia
conveniences (1-based indexing, copyless array conversion, a "julia" format
that lazily converts observations to Julia types).
src/HuggingFaceDatasets.jl— module entry point. Holds the lazily-imported Python module handles (datasets,PIL,np,copy,pickle), initialized in__init__viaPythonCall.pycopy!. Python modules must be imported there, not at module top level (PythonCall restriction — see the comment in the file).src/dataset.jl—Dataset, the wrapper overdatasets.Dataset. 1-based indexing, format/transform machinery (with_format,set_format!,with_jltransform,set_jltransform!,reset_format!).src/datasetdict.jl—DatasetDict, a dict ofDatasets.src/iterabledataset.jl—IterableDataset, the lazy streaming counterpart ofDataset(wrapsdatasets.IterableDataset). Consumed byBase.iterate, not indexing (no length / no random access); returned byload_dataset(...; streaming=true)with asplit.src/iterabledatasetdict.jl—IterableDatasetDict, a dict ofIterableDatasets (wrapsdatasets.IterableDatasetDict); returned by streamingload_datasetwithout asplit.src/column.jl—Column, a lazy 1-basedAbstractVectorview over a single dataset column (wraps thedatasets.Columnreturned bydataset[name]on datasets ≥ 4), converting elements withpy2jlon access.src/load_dataset.jl—load_dataset, thin wrapper overdatasets.load_datasetreturning aDataset/DatasetDict(or, withstreaming=true, anIterableDataset/IterableDatasetDict).src/toplevel.jl— Julia wrappers for module-leveldatasetsfunctions (concatenate_datasets,interleave_datasets,load_from_disk, andfrom_csv/from_json/from_parquet) that re-wrap results in the default"julia"format.src/transforms.jl—py2jl/numpy2jl/jl2numpy/jl2py.py2jlrecursively converts Python containers, numpy arrays (copyless, zero-copy), and PIL images into Julia types;jl2pyis the write-path dual. The"julia"format is numpy-backed, so numeric array columns decode to real N-D Julia arrays and image columns decode to raw numeric arrays (notColorantcolorviews).src/features.jl—Py-backed views over a dataset's schema:Features(anAbstractDictreturned byds.features), and theClassLabel/Valueleaves it wraps, each forwarding attribute/method access to Python (cl.names,cl.int2str,v.dtype). Handled at the access site (a:featuresbranch inDataset'sgetproperty), never in thepy2jlbatch hot path. Also the Julian label-decoding helpersclass_names/int2str/str2int((ds, col, …)), andjl2pyoverloads so a Julia-built schema round-trips into afeatures=argument. Everything here is public but unexported; the Pythonic idioms are primary.src/serialization.jl—Serialization.serialize/deserializeforDataset, so it can cross a process boundary (process-parallel data loaders). Never serializes the wrappedPydirectly; instead usesdatasets' own pickle (on-disk datasets pickle by reference to their mmapped Arrowcache_files; in-memory ones are materialized to a temp Arrow dir once, fingerprint-cached).src/callable.jl— small helper for method forwarding to the wrapped Python object. Thegetobs/numobsobservation interface comes fromMLCore(≥ 1.1);getobs(::Py, ::Integer)is provided by MLCore'sPythonCallextension, so the package no longer carries its own (pirate) method for it.
Managed by CondaPkg.jl via
CondaPkg.toml (conda-forge channel): datasets, numpy, pillow.
datasetsis pinned to>=4.0, <5. Do not lower the floor below 4.0 (the lazyColumncolumn-access path depends on datasets ≥ 4).pythonis pinned to<3.14to avoid conda-forge's free-threaded (no-GIL) CPython, which deadlocks PythonCall while importingdatasets' C extensions.
Use the Julia MCP server (julia_eval) rather than the julia CLI, with
env_path set to the repo root:
using Pkg; Pkg.test()- Test deps live in
test/Project.toml(Test,ImageCore,PythonCall); the root project declares[workspace] projects = ["test", "docs"]. test/runtests.jlrunstransforms.jl,dataset.jl,datasetdict.jl,iterabledataset.jl, anditerabledatasetdict.jlalways (the last two stay offline, building streams from in-memory data), andno_ci.jl(larger downloads: cifar10, beans, cppe-5) only whenCIis not"true". SetENV["CI"]="true"to mimic CI and skip those.- The first run downloads datasets and provisions the conda env, so it is slow.
PRs should update CHANGELOG.md. It follows
Keep a Changelog; the project uses
Semantic Versioning.
- Any user-visible change (bug fix; added, changed, deprecated, or removed method or
behavior) must add a bullet under the
## [Unreleased]heading, in the matching category:Added,Changed,Deprecated,Removed,Fixed, orSecurity. Purely internal changes (refactors, tests, CI, doc typos) don't need an entry. - Write entries for users, in the present tense, describing the effect rather than the code change.
- On release: rename
## [Unreleased]to## [X.Y.Z] - YYYY-MM-DD, add a fresh empty## [Unreleased]above it, bumpversioninProject.tomlper SemVer (new feature → minor, bug fix → patch; for0.x, breaking → minor), and update the compare links at the bottom of the file.