MatchField.oxm_field()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 5
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
nop 1
crap 1
1
"""Base classes for Match Fields."""
2
3 1
from abc import ABC, abstractmethod
4
5
6 1
class MatchField(ABC):
7
    """Base class for match fields. Abstract OXM TLVs of python-openflow.
8
9
    Just extend this class and you will be forced to define the required
10
    low-level attributes and methods below:
11
12
    * "name" attribute (field name to be displayed in JSON);
13
    * "oxm_field" attribute (``OxmOfbMatchField`` enum);
14
    * Method to return a pyof OxmTLV;
15
    * Method to create an instance from an OxmTLV.
16
    """
17
18 1
    def __init__(self, value):
19
        """Define match field value."""
20 1
        self.value = value
21
22 1
    @property
23 1
    @classmethod
24 1
    @abstractmethod
25
    def name(cls):
26
        """Define a name to be displayed in JSON.
27
28
        It can be overriden just by a class attibute.
29
        """
30
31 1
    @property
32 1
    @classmethod
33 1
    @abstractmethod
34
    def oxm_field(cls):
35
        """Define this subclass ``OxmOfbMatchField`` value.
36
37
        It can be overriden just by as a class attibute.
38
        """
39
40 1
    @abstractmethod
41
    def as_of_tlv(self):
42
        """Return a pyof OXM TLV instance."""
43
44 1
    @classmethod
45 1
    @abstractmethod
46
    def from_of_tlv(cls, tlv):
47
        """Return an instance from a pyof OXM TLV."""
48
49 1
    def __eq__(self, other):
50
        """Two objects are equal if their values are the same.
51
52
        The oxm_field equality is checked indirectly when comparing whether
53
        the objects are instances of the same class.
54
        """
55
        return isinstance(other, self.__class__) and other.value == self.value
56
57
58 1
class MatchFieldFactory(ABC):
59
    """Create the correct MatchField subclass instance.
60
61
    As OF 1.3 has many match fields and there are many ways to (un)pack their
62
    OxmTLV.oxm_value, this class does all the work of finding the correct
63
    MatchField class and instantiating the corresponding object.
64
    """
65
66 1
    __classes = {}
67
68 1
    @classmethod
69
    def from_name(cls, name, value):
70
        """Return the proper object from name and value."""
71 1
        field_class = cls._get_class(name)
72 1
        if field_class:
73 1
            return field_class(value)
74
        return None
75
76 1
    @classmethod
77
    def from_of_tlv(cls, tlv):
78
        """Return the proper object from a pyof OXM TLV."""
79
        field_class = cls._get_class(tlv.oxm_field)
80
        if field_class:
81
            return field_class.from_of_tlv(tlv)
82
        return None
83
84 1
    @classmethod
85
    def _get_class(cls, name_or_field):
86
        """Return the proper object from field name or OxmTLV.oxm_field."""
87 1
        if not cls.__classes:
88 1
            cls._index_classes()
89 1
        return cls.__classes.get(name_or_field)
90
91 1
    @classmethod
92
    def _index_classes(cls):
93 1
        for subclass in MatchField.__subclasses__():
94 1
            cls.__classes[subclass.name] = subclass
95
            cls.__classes[subclass.oxm_field] = subclass
96