1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
|
"""
Defines Mixins for parsers.
The Mixins are here mostly for separation of concerns.
"""
__author__ = "Jens Finkhaeuser"
__copyright__ = "Copyright (c) 2016-2018 Jens Finkhaeuser"
__license__ = "MIT"
__all__ = ()
class CacheSpecsMixin:
"""
CacheSpecsMixin helps determine if self.specification changed.
It does so by caching a shallow copy on-demand.
"""
__CACHED_SPECS = "__cached_specs"
def specs_updated(self):
"""
Test if self.specficiation changed.
:return: Whether the specs changed.
:rtype: bool
"""
# Cache specs and return true if no specs have been cached
if not getattr(self, self.__CACHED_SPECS, None):
setattr(self, self.__CACHED_SPECS, self.specification.copy())
return True
# If specs have been cached, compare them to the current
# specs.
cached = getattr(self, self.__CACHED_SPECS)
if cached != self.specification:
setattr(self, self.__CACHED_SPECS, self.specification.copy())
return True
# Return false if they're the same
return False
class YAMLMixin(CacheSpecsMixin):
"""
YAMLMixin returns a YAML representation of the specification.
It uses :py:class:`CacheSpecsMixin` for lazy evaluation.
"""
__YAML = "__yaml"
def yaml(self):
"""
Return a YAML representation of the specifications.
:return: YAML representation.
:rtype: dict
"""
# Query specs_updated first to start caching
if self.specs_updated() or not getattr(self, self.__YAML, None):
import yaml
setattr(self, self.__YAML, yaml.dump(self.specification))
return getattr(self, self.__YAML)
class JSONMixin(CacheSpecsMixin):
"""
JSONMixin returns a JSON representation of the specification.
It uses :py:class:`CacheSpecsMixin` for lazy evaluation.
"""
__JSON = "__json"
def json(self):
"""
Return a JSON representation of the specifications.
:return: JSON representation.
:rtype: dict
"""
# Query specs_updated first to start caching
if self.specs_updated() or not getattr(self, self.__JSON, None):
import json
setattr(self, self.__JSON, json.dumps(self.specification))
return getattr(self, self.__JSON)
|