Coverage for hdl_registers/generator/python/pickle.py: 96%
27 statements
« prev ^ index » next coverage.py v7.6.1, created at 2024-09-07 20:51 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2024-09-07 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{self.header}
73# Standard libraries
74import pickle
75from pathlib import Path
76from typing import TYPE_CHECKING
78if TYPE_CHECKING:
79 # Third party libraries
80 from hdl_registers.register_list import RegisterList
82THIS_DIR = Path(__file__).parent
83PICKLE_FILE = THIS_DIR / "{self.pickle_file.name}"
86class {class_name}:
87 """
88 Instantiate this class to get the ``RegisterList`` object for the
89 ``{self.name}`` register list.
90 """
92 def __new__(cls):
93 """
94 Recreate the ``RegisterList`` object from binary pickle.
95 """
96 with PICKLE_FILE.open("rb") as file_handle:
97 return pickle.load(file_handle)
100def get_register_list() -> "RegisterList":
101 """
102 Return a ``RegisterList`` object with the registers/constants from the
103 ``{self.name}`` register list.
104 Recreated from a Python pickle file.
105 """
106 with PICKLE_FILE.open("rb") as file_handle:
107 return pickle.load(file_handle)
108'''
110 @property
111 def should_create(self) -> bool:
112 """
113 Since this generator creates two files, where one is binary, it is impossible to do the
114 version/hash check.
115 Hence, set it to "always create".
116 The mechanism "create if needed" should not be used for this generator anyway, since
117 this generator is not designed to run in real-time like e.g. the VHDL generator.
118 """
119 return True