# Copyright 2019-2024 Cambridge Quantum Computing## Licensed under the Apache License, Version 2.0 (the "License");# you may not use this file except in compliance with the License.# You may obtain a copy of the License at## http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an "AS IS" BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.importjsonimportosfromabcimportABC,abstractmethodfromdataclassesimportasdict,dataclassfrompathlibimportPathfromtypingimportAny,ClassVar,TypeVar
[docs]defget_config_file_path()->Path:"""Get a path to the config file on this machine."""config_dir:Pathxdg_conifg_dir=os.environ.get("XDG_CONFIG_HOME")ifxdg_conifg_dirisNone:config_dir=Path.home()/".config"else:config_dir=Path(xdg_conifg_dir)returnconfig_dir/"pytket"/"config.json"
[docs]classPytketConfig:"""PytketConfig represents a loaded config file for pytket and extension packages."""extensions:dict[str,Any]
[docs]def__init__(self,extensions:dict[str,Any]|None=None,)->None:"""Construct a PytketConfig object with inital config parameter values. :param extensions: Dictionary holding parameter values for extension packages, defaults to None :type extensions: Optional[Dict[str, Any]], optional """self.extensions={}ifextensionsisNoneelseextensions
[docs]@classmethoddefdefault(cls)->"PytketConfig":"""Construct a default PytketConfig"""returnPytketConfig()
[docs]@classmethoddefread_file(cls,config_file_path:Path)->"PytketConfig":"""Construct a PytketConfig from reading a file with a given Path."""withconfig_file_path.open("r",encoding="utf-8")asconfig_file:config=json.load(config_file)returnPytketConfig(config.get("extensions",dict()),)
[docs]defwrite_file(self,config_file_path:Path)->None:"""Write a PytketConfig to a file with a given Path."""config_file_path.parent.mkdir(parents=True,exist_ok=True)withconfig_file_path.open("w",encoding="utf-8")asconfig_file:config={"extensions":self.extensions,}json.dump(config,config_file,indent=2)
[docs]defload_config_file()->PytketConfig:"""Load config from default file path."""returnPytketConfig.read_file(get_config_file_path())
[docs]defwrite_config_file(config:PytketConfig)->None:"""Write config to default file path."""config.write_file(get_config_file_path())
T=TypeVar("T",bound="PytketExtConfig")
[docs]@dataclassclassPytketExtConfig(ABC):"""Abstract base class for pytket extension config classes."""ext_dict_key:ClassVar[str]=""
[docs]@classmethod@abstractmethoddeffrom_extension_dict(cls:type[T],ext_dict:dict[str,Any])->T:"""Abstract method to build PytketExtConfig from dictionary serialized form."""...
[docs]defto_dict(self)->dict[str,Any]:"""Serialize to dictionary."""returnasdict(self)
[docs]@classmethoddeffrom_pytketconfig(cls:type[T],p_config:PytketConfig)->T:"""Build from PytketConfig instance."""ifcls.ext_dict_keyinp_config.extensions:returncls.from_extension_dict(p_config.extensions[cls.ext_dict_key])returncls.from_extension_dict({})
[docs]@classmethoddeffrom_default_config_file(cls:type[T])->T:"""Load from default config file."""returncls.from_pytketconfig(load_config_file())
[docs]defupdate_pytket_config(self,pytket_config:PytketConfig)->None:"""Update a PytketConfig instance from this extension config."""pytket_config.extensions.update({self.ext_dict_key:self.to_dict()})
[docs]defupdate_default_config_file(self)->None:"""Update default config file with current parameters in this extension config."""config=load_config_file()self.update_pytket_config(config)write_config_file(config)