From 229aa53df23ee8e24a8d4ff42092e240213387e9 Mon Sep 17 00:00:00 2001 From: Rupert Swarbrick Date: Thu, 2 Apr 2026 17:42:31 +0100 Subject: [PATCH] Make the typing clearer in Deploy._process_exports Firstly, the stricter return type is needed because the CovMerge constructor updates self.exports (which is generated with that function). We also know the key and value types, so we may as well give them as well. The rest of the change is more complicated and a little ugly (we're confusing Pyright on purpose!). The trick is to pass the value that we wrote to self.exports from the hjson file as an argument to _process_exports. Doing it like this avoids Pyright trying to check that the field is both a list of dictionaries and a merged dictionary. Signed-off-by: Rupert Swarbrick --- src/dvsim/job/deploy.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/dvsim/job/deploy.py b/src/dvsim/job/deploy.py index 71247b85..54cf84a5 100644 --- a/src/dvsim/job/deploy.py +++ b/src/dvsim/job/deploy.py @@ -98,8 +98,16 @@ def __init__(self, sim_cfg: "SimCfg") -> None: # Do variable substitutions. self._subst_vars() - # List of vars required to be exported to sub-shell, as a dict. - self.exports = self._process_exports() + # List of vars required to be exported to sub-shell, as a dict. This + # has been loaded from the hjson as a list of dicts and we want to + # flatten it to a single dictionary. + # + # The slightly odd dance with the variables is to convince Pyright + # about the types we end up with. + exports_list: object = self.exports + if not isinstance(exports_list, list): + raise TypeError("Loaded exports value should be a list of dicts.") + self.exports: dict[str, str] = self._process_exports(exports_list) # Construct the job's command. self.cmd = self._construct_cmd() @@ -276,7 +284,7 @@ def _subst_vars(self, ignored_subst_vars=None) -> None: ignore_error=False, ) - def _process_exports(self) -> Mapping: + def _process_exports(self, exports_list: list[dict[str, str]]) -> dict[str, str]: """Convert 'exports' as a list of dicts in the HJson to a dict. Exports is a list of key-value pairs that are to be exported to the @@ -286,7 +294,7 @@ def _process_exports(self) -> Mapping: into a dict variable, which makes it easy to merge the list of exports with the subprocess' env where the ASIC tool is invoked. """ - return {k: str(v) for item in self.exports for k, v in item.items()} + return {k: str(v) for item in exports_list for k, v in item.items()} def _construct_cmd(self) -> str: """Construct the command that will eventually be launched."""