glom locks a 3.7-era lockfile under a claim of Python 3.14
☄️ Python's nested data operator (and CLI), for all your declarative restructuring needs. Got data? Glom it! ☄️
At a glance
- What is it?
- glom restructures nested data with declarative specs and ships a console entry point for experimenting at a terminal. Its lockfile header says pip-compile with Python 3.7 while the README claims support through 3.14.
- Who is it for?
- glom suits a Python codebase that reaches into nested dictionaries and objects repeatedly and wants a failure to name the path it could not walk. It does not suit a project that needs schema validation or query planning over large datasets, and it is not a faster replacement for code that already indexes cleanly.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 34 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 28, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The error names the path instead of blaming NoneType
The README opens with a contrast that is really the product pitch. Plain indexing on nested data gives you this:
data2 = {'a': {'b': None}}
data2['a']['b']['c']
Traceback (most recent call last):
TypeError: 'NoneType' object is not subscriptableThe same access through a glom spec raises PathAccessError instead, naming the step that failed: could not access 'c', index 2 in path Path('a', 'b', 'c'). That is the whole argument for a path-based accessor in one traceback line, and it is a real difference rather than a stylistic one, because the failure arrives with the path already assembled. The successful case reads the same way, glom(data, 'a.b.c') returning 'd', so the spec is a dotted path rather than a nested block of indexing. The other three features listed alongside this are path-based access itself, declarative transformation specs, and built-in exploration and debugging. The package is pure Python with no compiled extension, and the README claims it is tested on Python 3.7 through 3.14 as well as PyPy3.
The command line is a console_scripts entry point
Installing glom also installs a command, and that is defined in setup.py rather than shipped as a wrapper script. The entry_points section registers console_scripts with glom = glom.cli:console_main, so the executable name and the module function are tied together in package metadata. The README's framing is deliberate: the CLI is for experimenting at the console without limiting you to shell scripts, and anything you can do there translates into Python code when complexity grows. The usage block shows the shape:
Usage: glom [FLAGS] [spec [target]]The flags are worth reading as a map of the library. Input format is chosen with --target-format, which accepts json, python, toml or yaml and defaults to json, and the spec itself has its own --spec-format accepting json, python or python-full, defaulting to python. --target-file and --spec-file take paths when the data or the spec is too large for an argument. --indent controls output and 0 disables pretty-printing. Two flags are aimed at a person rather than a pipeline: --debug interactively debugs any errors that come up, and --inspect interactively explores the data.
pip install glom pulls in boltons, attrs and face
The README gives a single install line:
pip install glomUnderneath, setup.py declares install_requires as boltons>=19.3.0, attrs and face>=20.1.1. Two floors and one unversioned dependency, which is a light footprint for a package with a CLI and a data-transformation core. The package list is explicit too: packages=['glom', 'glom.test'] with zip_safe=False and platforms='any'. Configuration for the optional formats is done through extras_require rather than by default, and that choice matters more than it looks. The toml extra is tomli marked with python_version<3.11, so the set of installed packages differs by interpreter version, while the yaml extra is PyYAML. A separate test extra carries pytest>=6.2.5, PyYAML, coverage and the same tomli marker. Read the extras section before you plan to parse TOML in a project that also supports older interpreters, the marker means the dependency resolves differently per environment, which is worth pinning deliberately.
The lockfile says pip-compile with Python 3.7, not 3.14
requirements.txt carries a header that tells you exactly how it was produced: autogenerated by pip-compile with Python 3.7, from pip-compile requirements.in. The pins inside are a snapshot of that moment, with attrs==24.2.0, boltons==24.1.0 and face==24.0.0, cachetools==5.5.0, coverage==7.2.7, filelock==3.12.2, pytest==7.4.4, pyyaml==6.0.1, tox==4.8.0, virtualenv==20.26.6 and zipp==3.15.0, among others. Put that next to the README claim of support through Python 3.14 and the mismatch is visible in both directions. The lower bound is explained: compiling under the oldest supported interpreter is how pip-compile produces a set that resolves everywhere, and most of those pins carry a via tox comment, meaning they are development and test-time packages rather than runtime dependencies. The consequence for you is that the floors in setup.py, not the pins in requirements.txt, are what your application resolves against, and the header comment dating the compile to Python 3.7 will stay there until somebody regenerates the file with a newer interpreter. Use the requirements file to reproduce the test environment, not to constrain production.
A YY.MM.MICRO version badge and a documentation trail back to 2018
The version badge uses calendar versioning in the YY.MM.MICRO form rather than semantic versioning, so the date is encoded in the number itself. setup.py does not hardcode the version either. It locates glom/_version.py, loads it with importlib.util.spec_from_file_location, and reads __version__ from the loaded module, so the version lives in one place in the package rather than in the build script. The repository carries a SECURITY.md, a codecov.yml, tox.ini and pytest.ini, and the documentation is built from the docs/ directory with a .readthedocs.yaml at the root. For learning the API, the README points at a tutorial and full API documentation on Read the Docs, a CLI page, a frequently asked questions page, the original announcement blog post dated 2018-05-09, a PyCon 2018 lightning talk from 2018-05-11, and glompad, a browser-based playground. The 2018 dates on the announcement and talk are worth noticing: the public narrative about this project has been stable for a long time.
Where glom is the wrong tool
The first wrong case is validation. A dotted-path accessor tells you what it could not reach, and nothing more. It does not check that a field is of the expected type, that a list has the expected length, or that a required key is present at all beyond failing when you touch it. If your requirement is a contract between two systems, glom is not where you enforce it. The second is volume. glom is a pure-Python library walking objects in memory, so it operates on data your process has already loaded; it is not a query engine and does not push anything into a database. Pointing a spec at a large collection and expecting filtering to happen somewhere cheaper will not work out. The third is the CLI as a production tool. It is designed for exploring data and translating what you learn into Python, and the README says as much, so a shell script that depends on it is leaning on the wrong end of its purpose. The fourth is legal sign-off. GitHub cannot categorize the terms in the LICENSE file, so an automated compliance scan will report nothing and someone on your team has to read that file directly.
Specs are strings first and only occasionally code
A detail worth stating plainly, because it decides how you write the specs. The spec in the examples is a plain dotted string, a.b.c, not a nested structure of calls, and the same library documents a heavier python-full form in its CLI flag list alongside json and python. So there are two levels of expressiveness available and the simple one is enough for most extraction. The CLI mirrors the same split through --spec-format, which means a spec that is awkward to write on a command line can be moved into a file and referenced with --spec-file. What the README does not give is a decision rule for when to escalate, which is a fair gap given the tutorial and API pages exist separately at glom.readthedocs.io. Read those before assuming a string spec covers your case.
Editorial conclusion
glom suits a Python codebase that reaches into nested dictionaries and objects repeatedly and wants a failure to name the path it could not walk. It does not suit a project that needs schema validation or query planning over large datasets, and it is not a faster replacement for code that already indexes cleanly. Before adopting, install it with pip install glom, check that face and boltons resolve to versions your Python supports, and decide whether toml and yaml extras are worth the extra imports.
Frequently asked questions
How do I install glom?
Run pip install glom. It is a pure-Python package with no compiled extension, and installing it also puts a glom command on your path through a console_scripts entry point.
What error does glom raise when a nested key is missing?
PathAccessError, naming the path and the index that failed, for example could not access 'c', index 2 in path Path('a', 'b', 'c'). Plain subscript access on the same data raises TypeError instead.
Does glom support TOML and YAML input?
Through the command line, --target-format accepts json, python, toml or yaml. In Python the support is packaged as extras: the toml extra is tomli with a python_version<"3.11" marker and the yaml extra is PyYAML.
What are the runtime dependencies of glom?
setup.py lists boltons>=19.3.0, attrs and face>=20.1.1 as install_requires. Test-only packages such as pytest and coverage live in the test extra, not the runtime set.
How is the glom version determined at build time?
setup.py loads glom/_version.py by file path and reads __version__ from it. The project uses calendar versioning, YY.MM.MICRO, so the release date is visible in the number.