Skip to content

Commit

Permalink
remove ufoLib2.serde.pickle, doesn't add anything
Browse files Browse the repository at this point in the history
Doing font.pickle_dumps() is exactly the same as doing pickle.dumps(font), same for Font.pickle_loads(s) vs pickle.loads(s), we don't use cattrs for pickling. So it's better to simply remove the extra code, pickling still works out of the box (even with lazy objects now).
  • Loading branch information
anthrotype committed Nov 3, 2022
1 parent 30f639f commit 0ac647b
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 85 deletions.
43 changes: 33 additions & 10 deletions src/ufoLib2/serde/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from ufoLib2.typing import PathLike, T

_SERDE_FORMATS_ = ("json", "msgpack", "pickle")
_SERDE_FORMATS_ = ("json", "msgpack")


def _loads(
Expand Down Expand Up @@ -53,19 +53,42 @@ def _dump(
def serde(cls: Type[T]) -> Type[T]:
"""Decorator to add serialization support to a ufoLib2 class.
Currently JSON, MessagePack (msgpack) and Pickle are the supported formats,
but other formats may be added in the future.
This adds f"{format}_loads" / f"{format}_dumps" (from/to bytes) methods, and
f"{format}_load" / f"{format}_dump" (for file or path) methods to all ufoLib2
objects, not just Font.
Pickle works out of the box, whereas the others require additional extras
to be installed: e.g. ufoLib2[json,msgpack]. If required, this will install
the `cattrs` library for structuring/unstructuring custom objects from/to
serializable data structures (also available with ufoLib2[converters] extra).
Currently the supported formats are JSON and MessagePack (msgpack), but other
formats may be added in the future.
If any of the optional dependencies fails to be imported, this decorator will
raise an ImportError when any of the related methods are called.
E.g.::
from ufoLib2 import Font
font = Font.open("MyFont.ufo")
font.json_dump("MyFont.json")
font2 = Font.json_load("MyFont.json")
font3 = Font.json_loads(font2.json_dumps())
font3.msgpack_dump("MyFont.msgpack")
font4 = Font.msgpack_load("MyFont.msgpack")
# etc.
Note this requires additional extras to be installed: e.g. ufoLib2[json,msgpack].
In additions to the respective serialization library, these installs the `cattrs`
library for structuring/unstructuring custom objects from/to serializable data
structures (also available separately as ufoLib2[converters] extra).
If any of the optional dependencies fails to be imported, the methods will raise
an ImportError when called.
If the faster `orjson` library is present, it will be used in place of the
built-in `json` library.
built-in `json` library on CPython. On PyPy, the `orjson` library is not available,
so the built-in `json` library will be used (though it's pretty fast anyway).
If you want a serialization format that works out of the box with all ufoLib2
objects (but it's mostly limited to Python) you can use the built-in pickle module,
which doesn't require to use the `cattrs` converters.
"""

supported_formats = []
Expand Down
16 changes: 0 additions & 16 deletions src/ufoLib2/serde/pickle.py

This file was deleted.

34 changes: 34 additions & 0 deletions tests/objects/test_font.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
from __future__ import annotations

import pickle
from pathlib import Path
from typing import Optional

import pytest

from ufoLib2.objects import Font, Glyph, Guideline

Expand Down Expand Up @@ -101,3 +105,33 @@ def test_data_images_init() -> None:
assert font.data["bbb/c"] == b"456"
assert font.images["a.png"] == b"\x89PNG\r\n\x1a\n"
assert font.images["b.png"] == b"\x89PNG\r\n\x1a\n"


@pytest.mark.parametrize(
"lazy", [None, False, True], ids=["lazy-unset", "non-lazy", "lazy"]
)
def test_pickle_lazy_font(datadir: Path, lazy: Optional[bool]) -> None:
if lazy is not None:
font = Font.open(datadir / "UbuTestData.ufo", lazy=lazy)
else:
font = Font()

assert lazy is font._lazy

data = pickle.dumps(font)

assert isinstance(data, bytes) and len(data) > 0

# picklying unlazifies
if lazy:
assert font._lazy is False
else:
assert font._lazy is lazy

font2 = pickle.loads(data)

assert isinstance(font2, Font)
assert font == font2
# unpickling doesn't initialize the lazy flag or a reader, which reset to default
assert font2._lazy is None
assert font2._reader is None
59 changes: 0 additions & 59 deletions tests/serde/test_pickle.py

This file was deleted.

0 comments on commit 0ac647b

Please sign in to comment.