Coverage for /home/runner/work/tket/tket/pytket/pytket/config/pytket_config.py: 93%
57 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-14 11:30 +0000
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-14 11:30 +0000
1# Copyright Quantinuum
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
15import json
16import os
17from abc import ABC, abstractmethod
18from dataclasses import asdict, dataclass
19from pathlib import Path
20from typing import Any, ClassVar, TypeVar
23def get_config_file_path() -> Path:
24 """Get a path to the config file on this machine."""
25 config_dir: Path
26 xdg_conifg_dir = os.environ.get("XDG_CONFIG_HOME")
27 if xdg_conifg_dir is None: 27 ↛ 28line 27 didn't jump to line 28 because the condition on line 27 was never true
28 config_dir = Path.home() / ".config"
29 else:
30 config_dir = Path(xdg_conifg_dir)
32 return config_dir / "pytket" / "config.json"
35class PytketConfig:
36 """PytketConfig represents a loaded config file for
37 pytket and extension packages."""
39 extensions: dict[str, Any]
41 def __init__(
42 self,
43 extensions: dict[str, Any] | None = None,
44 ) -> None:
45 """Construct a PytketConfig object with inital config parameter values.
47 :param extensions: Dictionary holding parameter values for extension packages,
48 defaults to None
49 :type extensions: Optional[Dict[str, Any]], optional
50 """
52 self.extensions = {} if extensions is None else extensions
54 @classmethod
55 def default(cls) -> "PytketConfig":
56 """Construct a default PytketConfig"""
57 return PytketConfig()
59 @classmethod
60 def read_file(cls, config_file_path: Path) -> "PytketConfig":
61 """Construct a PytketConfig from reading a file with a given Path."""
62 with config_file_path.open("r", encoding="utf-8") as config_file:
63 config = json.load(config_file)
64 return PytketConfig(
65 config.get("extensions", dict()),
66 )
68 def write_file(self, config_file_path: Path) -> None:
69 """Write a PytketConfig to a file with a given Path."""
70 config_file_path.parent.mkdir(parents=True, exist_ok=True)
71 with config_file_path.open("w", encoding="utf-8") as config_file:
72 config = {
73 "extensions": self.extensions,
74 }
75 json.dump(config, config_file, indent=2)
78def load_config_file() -> PytketConfig:
79 """Load config from default file path."""
80 return PytketConfig.read_file(get_config_file_path())
83def write_config_file(config: PytketConfig) -> None:
84 """Write config to default file path."""
85 config.write_file(get_config_file_path())
88T = TypeVar("T", bound="PytketExtConfig")
91@dataclass
92class PytketExtConfig(ABC):
93 """Abstract base class for pytket extension config classes."""
95 ext_dict_key: ClassVar[str] = ""
97 @classmethod
98 @abstractmethod
99 def from_extension_dict(cls: type[T], ext_dict: dict[str, Any]) -> T:
100 """Abstract method to build PytketExtConfig from dictionary serialized form."""
101 ...
103 def to_dict(self) -> dict[str, Any]:
104 """Serialize to dictionary."""
105 return asdict(self)
107 @classmethod
108 def from_pytketconfig(cls: type[T], p_config: PytketConfig) -> T:
109 """Build from PytketConfig instance."""
110 if cls.ext_dict_key in p_config.extensions:
111 return cls.from_extension_dict(p_config.extensions[cls.ext_dict_key])
112 return cls.from_extension_dict({})
114 @classmethod
115 def from_default_config_file(cls: type[T]) -> T:
116 """Load from default config file."""
117 return cls.from_pytketconfig(load_config_file())
119 def update_pytket_config(self, pytket_config: PytketConfig) -> None:
120 """Update a PytketConfig instance from this extension config."""
121 pytket_config.extensions.update({self.ext_dict_key: self.to_dict()})
123 def update_default_config_file(self) -> None:
124 """Update default config file with current parameters
125 in this extension config."""
126 config = load_config_file()
127 self.update_pytket_config(config)
128 write_config_file(config)