Coverage for hdl_registers/generator/python/pickle.py: 96%
27 statements
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-28 20:51 +0000
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-28 20:51 +0000
1# --------------------------------------------------------------------------------------------------
2# Copyright (c) Lukas Vik. All rights reserved.
3#
4# This file is part of the hdl-registers project, an HDL register generator fast enough to run
5# in real time.
6# https://hdl-registers.com
7# https://github.com/hdl-registers/hdl-registers
8# --------------------------------------------------------------------------------------------------
10# Standard libraries
11import pickle
12from pathlib import Path
13from typing import Any
15# Third party libraries
16from tsfpga.system_utils import create_directory
18# First party libraries
19from hdl_registers.generator.register_code_generator import RegisterCodeGenerator
20from hdl_registers.register_list import RegisterList
23class PythonPickleGenerator(RegisterCodeGenerator):
24 """
25 Generate a Python pickle of the :class:`.RegisterList` object, along with a Python
26 module to re-create the pickle in a simple way.
28 See the :ref:`generator_python` article for usage details.
29 """
31 __version__ = "1.0.0"
33 SHORT_DESCRIPTION = "Python pickle"
35 COMMENT_START = "#"
37 @property
38 def output_file(self) -> Path:
39 """
40 Result will be placed in this file.
41 """
42 return self.output_folder / f"{self.name}.py"
44 def __init__(self, register_list: RegisterList, output_folder: Path):
45 super().__init__(register_list=register_list, output_folder=output_folder)
47 self.pickle_file = self.output_folder / f"{self.name}.pickle"
49 def create(self, **kwargs: Any) -> Path:
50 """
51 Create the binary pickle also, apart from the class file.
53 Note that this is a little bit hacky, preferably each generator should produce only
54 one file.
55 """
56 # Create directory if it does not exist, but do not delete anything if it does.
57 create_directory(self.output_folder, empty=False)
59 with self.pickle_file.open("wb") as file_handle:
60 pickle.dump(self.register_list, file_handle)
62 return super().create(**kwargs)
64 def get_code(self, **kwargs: Any) -> str:
65 """
66 Save register list object to binary file (pickle) and create a python class
67 that recreates it.
68 """
69 class_name = self.to_pascal_case(self.name)
71 return f'''\
72# Standard libraries
73import pickle
74from pathlib import Path
75from typing import TYPE_CHECKING
77if TYPE_CHECKING:
78 # Third party libraries
79 from hdl_registers.register_list import RegisterList
81THIS_DIR = Path(__file__).parent
82PICKLE_FILE = THIS_DIR / "{self.pickle_file.name}"
85class {class_name}:
86 """
87 Instantiate this class to get the ``RegisterList`` object for the
88 ``{self.name}`` register list.
89 """
91 def __new__(cls):
92 """
93 Recreate the ``RegisterList`` object from binary pickle.
94 """
95 with PICKLE_FILE.open("rb") as file_handle:
96 return pickle.load(file_handle)
99def get_register_list() -> "RegisterList":
100 """
101 Return a ``RegisterList`` object with the registers/constants from the
102 ``{self.name}`` register list.
103 Recreated from a Python pickle file.
104 """
105 with PICKLE_FILE.open("rb") as file_handle:
106 return pickle.load(file_handle)
107'''
109 @property
110 def should_create(self) -> bool:
111 """
112 Since this generator creates two files, where one is binary, it is impossible to do the
113 version/hash check.
114 Hence, set it to "always create".
115 The mechanism "create if needed" should not be used for this generator anyway, since
116 this generator is not designed to run in real-time like e.g. the VHDL generator.
117 """
118 return True