from typing import Tuple, Union, List, Any from PyTeX.format.enums import NamingScheme from PyTeX.format.generic_text import GenericText def generate_properties(props): props = [x if isinstance(x, Tuple) else (x, None) for x in props] out = [] for [prop, default] in props: out.append( " @property\n" " def {prop}(self) -> {type}:\n" " if self._{prop} is None:\n" " return {default}\n" " else:\n" " return self._{prop}\n".format( prop=prop, type=type(default).__name__, default=str(default) ) ) return '\n'.join(out) if __name__ == "__main__": out = generate_properties( [ ("naming_scheme", NamingScheme.prepend_author), ("license", []), ("include_extra_header", False), ("include_build_time", False), ("include_pytex_version", False), ("include_pytex_info_text", False), ("include_repo_version", False), ("include_repo_info_text", False), ("extra_header", []), ("author", "MISSING AUTHOR"), ("licenses", GenericText([])), ("version", "0.0.0"), ("extra_header_file", GenericText([])), ("pytex_version", "0.0.0"), ("extra_header_file", GenericText([])), "pytex_version", ("pytex_info_text", GenericText([])), "repo_version", ("repo_info_text", GenericText([])), ("include_drv", False), ("include_ins", False), ("use_docstrip_guards", []) ] ) out2 = generate_properties( [ ("recursive", True), ("overwrite_existing_files", False), ("clean_old_files", False), ("allow_dirty", False) ] ) print(out2) def generate_properties(attributes: List[Union[str, Tuple[str, Any]]]): attributes = [ x if isinstance(x, Tuple) else (x, None) for x in attributes ] def decorator(cls): for [attribute, default_value] in attributes: def get_attr(self, attribute=attribute, default_value=default_value): if getattr(self, "_" + attribute) is not None: return getattr(self, "_" + attribute) else: return default_value prop = property(get_attr) setattr(cls, attribute, prop) return cls return decorator