File: mixins.py

package info (click to toggle)
python-prance 25.4.8.0%2Bds1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,140 kB
  • sloc: python: 3,381; makefile: 205
file content (90 lines) | stat: -rw-r--r-- 2,405 bytes parent folder | download
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)