You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
# Enabling Flexible Deserialization with Unknown Types in PyGlove
We're introducing the option to use `pg.from_json(..., convert_unknown=True)` to allow deserialization to proceed even when the original Python class, function, or method definitions are not available at runtime.
## Motivation: the problem of missing type definitions
When serializing and deserializing complex objects with PyGlove, an issue often arises when the code defining parts of the object (like a specific class `A` or a function `foo` from the example code below) is inaccessible in the deserializing environment (e.g., in a different process or a service that only handles data). By default, PyGlove would raise an error.
## Solution: `UnknownSymbol` objects
With `convert_unknown=True`, PyGlove no longer fails. Instead, it converts these missing types into specialized, dictionary-like `UnknownSymbol` objects, which bypass PyGlove type checking:
For unknown typed objects: An instance of a missing class (e.g., `A(x=1)`) is deserialized as a `pg.symbolic.UnknownTypedObject`. This object behaves like a dictionary, allowing access to the serialized attributes (e.g., `x` and `y`). Crucially, its original class name is preserved and accessible via its `type_name` property.
For unknown types, functions, and methods: Similarly, PyGlove converts these missing definitions into their respective symbolic representations:
* `pg.symbolic.UnknownType`
* `pg.symbolic.UnknownFunction`
* `pg.symbolic.UnknownMethod`
This mechanism allows you to load configuration files or serialized objects without requiring a full definition of every single dependency, treating the missing parts as plain data while retaining essential metadata about their original type.
## Example
Process 1: Serialization (Definitions are present)
```python
import pyglove as pg
class A(pg.Object):
x: int
y: str
def foo(t):
return t + 1
# Save the complex object and function to a file.
pg.save(dict(a=A(x=1, y='hello'), b=foo), '/path/to/data.json')
```
Process 2: Deserialization (Definitions for A and foo are missing)
```python
import pyglove as pg
# Class A and function foo are NOT defined in this environment.
# Load the data, allowing conversion of unknown types.
v = pg.load('/path/to/data.json', convert_unknown=True)
# The instance of A is loaded as an UnknownTypedObject.
print(v.a.type_name)
# Output: '__main__.A'
print(v.a.x)
# Output: 1
# The function foo is loaded as an UnknownFunction.
print(v.b.name)
# Output: '__main__.foo'
# Verification of types:
assert isinstance(v.a, pg.symbolic.UnknownTypedObject)
assert isinstance(v.b, pg.symbolic.UnknownFunction)
```
PiperOrigin-RevId: 833908094
0 commit comments