PyGlove: Manipulating Python Programs with a Symbolic Object Model
Manipulating Python Programs
At a glance
- What is it?
- PyGlove turns ordinary Python objects into symbolic ones that can be rebound, enumerated and searched. It is built for AutoML and evolutionary computing, but its search API assumes you already have a program worth searching over.
- Who is it for?
- Adopt PyGlove if you already have a Python program with tunable structure and want search or enumeration over it without rewriting the code into a separate configuration language. Do not adopt it if your parameters are a flat list of numbers, or if you need a stable API surface: v0.4.4 to v0.4.5 took roughly eighteen months, and the README carries an explicit disclaimer that this is not an officially supported Google product.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 2 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 October 1, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What PyGlove Solves for AutoML and Evolutionary Search
Most hyperparameter tools ask you to describe a search space separately from the code that uses it. You write a config schema, then write code that reads the config, and the two drift apart. PyGlove takes the opposite route: the objects themselves carry the search space. The README describes it as "a general-purpose library for Python object manipulation" that "introduces symbolic object-oriented programming to Python." The listed use cases are automated machine learning, evolutionary computing, machine learning for large teams, and what the README calls daily programming tasks with "advanced binding capabilities, mutability."
The intended user is not someone tuning three learning rates. It is someone whose search space has structure: a model architecture where the number of layers is itself a choice, or a symbolic program whose control flow can be mutated. PyGlove was published at NeurIPS 2020 and the README states it is used within Alphabet, including Google Research, Google Cloud, Youtube and Waymo. That is a statement about internal adoption, not about the maturity of the public API.
How Symbolic Rebinding and pg.iter Actually Work
The mechanism is a decorator plus a mutating method. Marking a class with pg.symbolize makes its instances symbolic: they keep their identity but their fields become replaceable. The README's Hello example stores the greeting in __init__ and exposes greet(). Calling hello.rebind(subject='PyGlove') replaces the constructor argument and the next greet() prints the new string. Nothing exotic there.
The interesting part is what happens when the rebound value is not a constant but a search primitive. The README passes pg.oneof(['World', 'PyGlove']) as the subject, then iterates the object with pg.iter(hello). The loop yields two concrete Hello instances and prints both greetings. So pg.iter is the bridge between a symbolic object that contains unresolved choices and the concrete objects a training loop can consume. The README also lists a set of "powerful search primitives for defining the search space," a library of ready-to-use search algorithms, and an API for interfacing with any distributed infrastructure, naming Open Source Vizier as one backend.
That layering matters when you read the code. The symbolic object model is independent of the search algorithms. You can use pg.symbolize and rebind purely as a configuration mechanism and never touch the search side, which is why the README lists daily programming tasks alongside AutoML.
Installing PyGlove and Running the Hello Example
Installation is a single pip command. The README gives no virtualenv instructions, no build step and no system dependencies, which is consistent with its claim that PyGlove is "lightweight and has very few dependencies beyond the Python interpreter." The requirements file backs that up: docstring-parser and termcolor are the only base requirements, with fsspec listed under an extras group named io.
pip install pygloveThe README also documents a nightly channel, which installs a pre-release build rather than the latest stable release:
pip install pyglove --preFor a first real use, copy the README's Hello class verbatim. The decorator is what makes rebind available.
import pyglove as pg
@pg.symbolize
class Hello:
def __init__(self, subject):
self._greeting = f'Hello, {subject}!'
def greet(self):
print(self._greeting)Running hello = Hello('World') followed by hello.greet() prints "Hello, World!" according to the README. Now rebind with a search primitive instead of a string, and iterate:
hello.rebind(subject=pg.oneof(['World', 'PyGlove']))
for h in pg.iter(hello):
h.greet()The README shows two lines of output, "Hello, World!" and "Hello, PyGlove!", one per candidate. If you see that, the symbolic layer is working. If pg.iter yields nothing, the usual cause is that no search primitive is present in the object graph: with a plain string subject there is exactly one configuration, and iterating it is not meaningful.
Where PyGlove Is the Wrong Tool
PyGlove's cost is conceptual, and it is paid up front. To search over a value, that value has to live on a symbolized object and be rebound through PyGlove's API. Wrapping a class in @pg.symbolize changes how it behaves: constructor arguments become symbolically replaceable, which is a real change to the semantics of your class, not a decorator that only adds metadata. Code that mutates fields directly, bypasses the constructor, or relies on __init__ side effects can conflict with that model. The README does not document a migration path for existing classes, nor does it describe rollback if a symbolized class misbehaves in production.
The second boundary is scale of ambition. If your tuning problem is a handful of continuous hyperparameters, the search primitives and the symbolic object model are more machinery than the problem needs, and a plain configuration dict plus a sampler will be easier to debug. PyGlove pays off when the thing being searched is structure: architecture choices, program fragments, control flow. The examples directory reflects this, with separate folders for automl, evolution, ml and python rather than a single hyperparameter-tuning demo.
The third boundary is support. The README ends with an explicit disclaimer that this is not an officially supported Google product. Treat it as a research-grade library that happens to be widely used internally.
PyGlove and Vizier: Two Different Kinds of Search
The obvious comparison is Open Source Vizier, which the README names as a backend that PyGlove can interface with. The difference is where the search space lives. Vizier is a service-oriented black-box optimizer: you define a study, the service proposes trials, your code evaluates them and reports the objective back. The search space is a specification handed to the optimizer, and the optimizer owns the state of the study.
PyGlove inverts that. The search space is embedded in your Python objects, and the algorithm runs in-process against those objects. pg.iter materializes candidates locally; a search algorithm explores the symbolic space directly. The README describes the distributed path as "an API to interface with any distributed infrastructure," with Vizier given as one example, so the two are designed to compose rather than compete: PyGlove defines and mutates the space, Vizier can supply proposals at scale.
That distinction is the practical one. If your search space is naturally expressed as a declarative spec and you want a managed service holding the trial history, Vizier alone is a better fit. If the space is entangled with Python code structure and you want to enumerate or mutate it in the same process, PyGlove is the layer that expresses it. Choosing wrong in either direction means either re-encoding your program as a config, or running an optimizer in-process when you needed a service.
Release Cadence, Licence and Upgrade Cost
The version history is uneven. v0.4.3 landed on 2023-09-13, v0.4.4 on 2024-01-04, and v0.4.5 on 2025-07-15. That is roughly four months between the first two and about eighteen months before the third. The repository is not archived and the last push was on 2026-09-09, so work continues on main, but a stable release is not a frequent event. Pin your version and read the release notes before moving, because the gap between releases means a lot of change can accumulate behind a single version bump.
Nightly builds are available through pip install pyglove --pre, and setup.py shows how they are produced: passing --nightly appends a .dev timestamp built from the current date and time to the version string. That is a build-time detail rather than a versioning policy, but it tells you nightlies are timestamped snapshots, not curated releases.
Licensing is Apache-2.0, with the standard header reproduced at the top of setup.py and the LICENSE file at the repository root. Apache-2.0 includes an express patent grant and requires that you retain notices and state significant changes when redistributing. That is a summary of what the licence text contains, not legal advice; if you are embedding PyGlove in a distributed product, have counsel read the actual terms. The disclaimer in the README, that this is not an officially supported Google product, is separate from the licence and affects what kind of support you can expect, not what you are permitted to do.
Editorial conclusion
Adopt PyGlove if you already have a Python program with tunable structure and want search or enumeration over it without rewriting the code into a separate configuration language. Do not adopt it if your parameters are a flat list of numbers, or if you need a stable API surface: v0.4.4 to v0.4.5 took roughly eighteen months, and the README carries an explicit disclaimer that this is not an officially supported Google product. Before committing, verify what pg.iter does on your own object graph, and check that the search primitives you need exist in the version you pin.
Frequently asked questions
How do I install PyGlove?
The README gives a single command, pip install pyglove. A pre-release build is available with pip install pyglove --pre. There is no build step or system dependency documented.
What does rebind do on a PyGlove symbolic object?
It replaces a constructor argument on a class marked with @pg.symbolize and returns the object with the new value, so subsequent method calls use it. In the README's Hello example, rebind(subject='PyGlove') changes the greeting printed by greet().
What is PyGlove used for?
The README lists automated machine learning, evolutionary computing, machine learning for large teams, and daily programming tasks in Python. It describes itself as a general-purpose library for Python object manipulation.
Is PyGlove an officially supported Google product?
No. The README ends with an explicit disclaimer stating that this is not an officially supported Google product, even though the library is used within Alphabet.
What licence does PyGlove use?
It is Apache-2.0, with the LICENSE file at the repository root and the standard header in setup.py. The README's support disclaimer is separate from the licence terms.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/google-pyglove)