Access python dicts using path strings (mainly just doing this to l2submodule)
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

70 linhas
2.2KB

  1. import yaml
  2. class PathError(Exception):
  3. def __init__(self, path):
  4. self.path = path
  5. super().__init__(self.path)
  6. class PathNotFoundError(PathError):
  7. pass
  8. class MissingRequirementError(PathError):
  9. pass
  10. class NotDictError(PathError):
  11. pass
  12. class Config:
  13. def __init__(self, data, delimiter = "/", defaults = {}, requirements = [], **misc_options):
  14. self.data = yaml.safe_load(open(data)) if type(data) != dict else data
  15. self.delimiter = delimiter
  16. self.strict_subscript = misc_options.get("strict_subscript", False)
  17. self.clobber_subscript = misc_options.get("clobber_subscript", False)
  18. for r in requirements:
  19. if not self.get(r): raise MissingRequirementError(r)
  20. for d in defaults:
  21. if not self.get(d): self.set(d, defaults[d])
  22. def split_path(self, path):
  23. return path.split(self.delimiter)
  24. def get(self, path, fallback = None, strict = False):
  25. elementsAll = self.split_path(path)
  26. def g(elems = elementsAll, obj = self.data):
  27. if not elems or not elems[0] or type(obj) != dict: return obj
  28. head, tail = elems[0], elems[1:]
  29. if strict and head not in obj:
  30. raise PathNotFoundError(path)
  31. return g(tail, obj.get(head, fallback))
  32. return g()
  33. def set(self, path, value, clobber = False):
  34. elementsAll = self.split_path(path)
  35. def s(elems = elementsAll, obj = self.data):
  36. head, tail = elems[0], elems[1:]
  37. # YANDEV MODE ACTIVATE!!!
  38. if not tail:
  39. obj[head] = value
  40. else:
  41. if head not in obj or type(obj[head]) != dict:
  42. if clobber:
  43. obj[head] = {}
  44. else:
  45. raise NotDictError(self.delimiter.join(elementsAll[:-len(tail)]))
  46. s(tail, obj[head])
  47. s()
  48. def __getitem__(self, path):
  49. return self.get(path, self.strict_subscript)
  50. def __setitem__(self, path, value):
  51. self.set(path, value, self.clobber_subscript)