|
4 | 4 |
|
5 | 5 | from __future__ import annotations |
6 | 6 |
|
| 7 | +import copyreg |
7 | 8 | import sys |
8 | 9 | import types |
9 | 10 | import warnings |
10 | | -from typing import Type, overload |
| 11 | +from typing import Any, Dict, Tuple, Type, overload |
11 | 12 |
|
12 | 13 | from typing_extensions import Literal |
13 | 14 |
|
|
18 | 19 | from ..typing import PolyLike |
19 | 20 | from ._array import FieldArray |
20 | 21 | from ._gf2 import GF2 |
| 22 | +from ._meta import FieldArrayMeta |
21 | 23 | from ._primitive_element import is_primitive_element, primitive_element |
22 | 24 | from ._ufunc import UFuncMixin_2_m, UFuncMixin_p_1, UFuncMixin_p_m |
23 | 25 |
|
@@ -531,3 +533,46 @@ def _GF_extension( |
531 | 533 |
|
532 | 534 |
|
533 | 535 | _GF_extension._classes = {} |
| 536 | + |
| 537 | + |
| 538 | +def _reconstruct_field_class(args: Tuple, kwargs: Dict[str, Any]): |
| 539 | + """ |
| 540 | + Reconstruct a field class via `galois.GF(...)`. |
| 541 | +
|
| 542 | + Pickle's reduce protocol passes positional args only, so we wrap keyword arguments |
| 543 | + in a dict and unpack them here. |
| 544 | + """ |
| 545 | + return GF(*args, **kwargs) |
| 546 | + |
| 547 | + |
| 548 | +def _reduce_field_class(field_cls) -> Tuple[object, Tuple[Dict[str, Any]]]: |
| 549 | + """ |
| 550 | + Pickle reducer for dynamically-created field classes (FieldArray subclasses). |
| 551 | +
|
| 552 | + We serialize the minimal set of constructor kwargs needed to reconstruct the same |
| 553 | + field class via the GF factory on unpickle. |
| 554 | + """ |
| 555 | + args = ( |
| 556 | + int(field_cls.characteristic), |
| 557 | + int(field_cls.degree), |
| 558 | + ) |
| 559 | + |
| 560 | + kwargs: Dict[str, Any] = { |
| 561 | + "primitive_element": int(field_cls.primitive_element), |
| 562 | + "verify": False, |
| 563 | + "compile": field_cls.ufunc_mode, # Restore the field's current ufunc mode on reconstruction |
| 564 | + "repr": field_cls.element_repr, |
| 565 | + } |
| 566 | + |
| 567 | + # Only extension fields have an irreducible polynomial. Encode as a string to avoid |
| 568 | + # formatting / parsing issues. |
| 569 | + if field_cls.degree > 1: |
| 570 | + kwargs["irreducible_poly"] = str(field_cls.irreducible_poly) |
| 571 | + |
| 572 | + # Return (callable, args) where args is a tuple of positional args; we pass kwargs as one arg. |
| 573 | + return (_reconstruct_field_class, (args, kwargs)) |
| 574 | + |
| 575 | + |
| 576 | +# Register pickling for the metaclass used by field classes. |
| 577 | +# FieldArrayMeta is your metaclass (import it appropriately here). |
| 578 | +copyreg.pickle(FieldArrayMeta, _reduce_field_class) |
0 commit comments