Skip to content

Commit 19afa8c

Browse files
authored
Deprecate types that have moved to fprime-gds repo (nasa#296)
* Allow StringType to use configurable SizeStore type * Migrate types away and import for backwards compatibility * Move fprime_gds imports to try/catch blocks * remove TimeBase import * Remove tests from deprecated types * remove unused DATA_ENCODING constant
1 parent dda4e06 commit 19afa8c

File tree

13 files changed

+178
-2254
lines changed

13 files changed

+178
-2254
lines changed
Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,7 @@
1-
"""Python implementations of built-in fprime types
1+
import warnings
22

3-
This package provides the modules necessary for the representation of fprime types (Fw/Types) package in a Python
4-
context. These standard types are represented as Python classes representing each individual type.
5-
6-
Example:
7-
U32 is represented by fprime.common.modules.serialize.numerical_types.U32Type
8-
9-
Special autocoded types are represented by configurable classes: ArrayType, SerializableType, and EnumType. These
10-
represent a generic version of these classes whose designed properties are set as dynamic properties on the python
11-
class itself.
12-
13-
Example:
14-
Serializables are represented by fprime.common.modules.serialize.serializable_type.SerializableType
15-
SerializableType(typename="MySerializable") is used to specify the Ai serializable's name
16-
"""
3+
warnings.warn(
4+
"Ground type system has been migrated to the fprime-gds package, in fprime_gds.common.models.serialize. Change your imports accordingly.",
5+
DeprecationWarning,
6+
stacklevel=2,
7+
)

src/fprime/common/models/serialize/array_type.py

Lines changed: 15 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -4,133 +4,20 @@
44
@author: jishii
55
"""
66

7-
from .type_base import DictionaryType
8-
from .type_exceptions import (
9-
ArrayLengthException,
10-
NotInitializedException,
11-
TypeMismatchException,
12-
DeserializeException,
13-
)
14-
15-
16-
class ArrayType(DictionaryType):
17-
"""Generic fixed-size array type representation.
18-
19-
Represents a custom named type of a fixed number of like members, each of which are other types in the system.
20-
"""
21-
22-
@classmethod
23-
def construct_type(cls, name, member_type, length, format):
24-
"""Constructs a sub-array type
25-
26-
Constructs a new sub-type of array to represent an array of the given name, member type, length, and format
27-
string.
28-
29-
Args:
30-
name: name of the array subtype
31-
member_type: type of the members of the array subtype
32-
length: length of the array subtype
33-
format: format string for members of the array subtype
34-
"""
35-
return DictionaryType.construct_type(
36-
cls, name, MEMBER_TYPE=member_type, LENGTH=length, FORMAT=format
37-
)
38-
39-
@classmethod
40-
def validate(cls, val):
41-
"""Validates the values of the array"""
42-
if not isinstance(val, (tuple, list)):
43-
raise TypeMismatchException(list, type(val))
44-
if len(val) != cls.LENGTH:
45-
raise ArrayLengthException(cls.MEMBER_TYPE, cls.LENGTH, len(val))
46-
for i in range(cls.LENGTH):
47-
cls.MEMBER_TYPE.validate(val[i])
48-
49-
@property
50-
def val(self) -> list:
51-
"""
52-
The .val property typically returns the python-native type. This the python native type closes to a serializable
53-
without generating full classes would be a dictionary (anonymous object). This returns such an object.
7+
import warnings
548

55-
:return dictionary of member names to python values of member keys
56-
"""
57-
return None if self._val is None else [item.val for item in self._val]
58-
59-
@property
60-
def formatted_val(self) -> list:
61-
"""
62-
Format all the elements of array according to the arr_format.
63-
Note 1: All elements will be cast to str
64-
Note 2: If a member is a serializable will call serializable formatted_val
65-
:return a formatted array
66-
"""
67-
result = []
68-
for item in self._val:
69-
if hasattr(item, "formatted_val"):
70-
result.append(item.formatted_val)
71-
else:
72-
result.append(self.FORMAT.format(item.val))
73-
return result
74-
75-
@val.setter
76-
def val(self, val: list):
77-
"""
78-
The .val property typically returns the python-native type. This the python native type closes to a serializable
79-
without generating full classes would be a dictionary (anonymous object). This takes such an object and sets the
80-
member val list from it.
81-
82-
:param val: dictionary containing python types to key names. This
83-
"""
84-
self.validate(val)
85-
items = [self.MEMBER_TYPE(item) for item in val]
86-
self._val = items
87-
88-
def to_jsonable(self):
89-
"""
90-
JSONable array object format
91-
"""
92-
return {
93-
"name": self.__class__.__name__,
94-
"type": self.__class__.__name__,
95-
"size": self.LENGTH,
96-
"format": self.FORMAT,
97-
"values": (
98-
None
99-
if self._val is None
100-
else [member.to_jsonable() for member in self._val]
101-
),
102-
}
103-
104-
def serialize(self):
105-
"""Serialize the array by serializing the elements one by one"""
106-
if self.val is None:
107-
raise NotInitializedException(type(self))
108-
return b"".join([item.serialize() for item in self._val])
109-
110-
def deserialize(self, data, offset):
111-
"""Deserialize the members of the array"""
112-
values = []
113-
for field_index in range(self.LENGTH):
114-
try:
115-
item = self.MEMBER_TYPE()
116-
item.deserialize(data, offset)
117-
offset += item.getSize()
118-
values.append(item)
119-
except Exception as exc:
120-
raise DeserializeException(
121-
f"Array index {field_index} failed to deserialize: {exc}"
122-
)
123-
self._val = values
124-
125-
def getSize(self):
126-
"""Return the size in bytes of the array"""
127-
return sum(item.getSize() for item in self._val)
128-
129-
@classmethod
130-
def getMaxSize(cls):
131-
"""Return the maximum size in bytes of the array"""
132-
return cls.MEMBER_TYPE.getMaxSize() * cls.LENGTH
9+
warnings.warn(
10+
"ArrayType is defined in fprime_gds.common.models.serialize.array_type. Change your imports accordingly.",
11+
DeprecationWarning,
12+
stacklevel=2,
13+
)
13314

134-
def __iter__(self):
135-
"""Allow the array object to be iterated"""
136-
return iter(self._val)
15+
# Import from new location for backward compatibility - may be removed in future versions
16+
try:
17+
from fprime_gds.common.models.serialize.array_type import ArrayType
18+
except ImportError as e:
19+
raise ImportError(
20+
"ArrayType has been moved to the fprime-gds package. "
21+
"Please install fprime-gds and update your imports to use "
22+
"`from fprime_gds.common.models.serialize.array_type import ArrayType`"
23+
) from e

src/fprime/common/models/serialize/bool_type.py

Lines changed: 14 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -3,53 +3,20 @@
33
@author: tcanham, reder
44
"""
55

6-
import struct
6+
import warnings
77

8-
from .type_base import ValueType
9-
from .type_exceptions import (
10-
DeserializeException,
11-
NotInitializedException,
12-
TypeMismatchException,
13-
TypeRangeException,
8+
warnings.warn(
9+
"BoolType is defined in fprime_gds.common.models.serialize.bool_type. Change your imports accordingly.",
10+
DeprecationWarning,
11+
stacklevel=2,
1412
)
1513

16-
17-
class BoolType(ValueType):
18-
"""
19-
Representation of a boolean type that will be stored for F prime. True values are stored as a U8 of 0xFF and False
20-
is stored as a U8 of 0x00.
21-
"""
22-
23-
TRUE = 0xFF
24-
FALSE = 0x00
25-
26-
@classmethod
27-
def validate(cls, val):
28-
"""Validate the given class"""
29-
if not isinstance(val, bool):
30-
raise TypeMismatchException(bool, type(val))
31-
32-
def serialize(self):
33-
"""Serialize a boolean value"""
34-
if self._val is None:
35-
raise NotInitializedException(type(self))
36-
return struct.pack("B", self.TRUE if self._val else self.FALSE)
37-
38-
def deserialize(self, data, offset):
39-
"""Deserialize boolean value"""
40-
try:
41-
int_val = struct.unpack_from("B", data, offset)[0]
42-
if int_val not in [self.TRUE, self.FALSE]:
43-
raise TypeRangeException(int_val)
44-
self._val = int_val == self.TRUE
45-
except struct.error:
46-
raise DeserializeException("Not enough bytes to deserialize bool.")
47-
48-
@classmethod
49-
def getSize(cls):
50-
return struct.calcsize("B")
51-
52-
@classmethod
53-
def getMaxSize(cls):
54-
"""Maximum size of type"""
55-
return cls.getSize() # Always the same as getSize
14+
# Import from new location for backward compatibility - may be removed in future versions
15+
try:
16+
from fprime_gds.common.models.serialize.bool_type import BoolType
17+
except ImportError as e:
18+
raise ImportError(
19+
"BoolType has been moved to the fprime-gds package. "
20+
"Please install fprime-gds and update your imports to use "
21+
"`from fprime_gds.common.models.serialize.bool_type import BoolType`"
22+
) from e

src/fprime/common/models/serialize/enum_type.py

Lines changed: 17 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -3,130 +3,23 @@
33
@author: tcanham, reder
44
"""
55

6-
import struct
6+
import warnings
77

8-
from .type_base import DictionaryType
9-
from .type_exceptions import (
10-
DeserializeException,
11-
EnumMismatchException,
12-
NotInitializedException,
13-
TypeMismatchException,
14-
TypeRangeException,
15-
InvalidRepresentationTypeException,
16-
RepresentationTypeRangeException,
8+
warnings.warn(
9+
"EnumType is defined in fprime_gds.common.models.serialize.enum_type. Change your imports accordingly.",
10+
DeprecationWarning,
11+
stacklevel=2,
1712
)
18-
from .numerical_types import IntegerType
1913

20-
REPRESENTATION_TYPE_MAP = {
21-
cls.get_canonical_name(): cls for cls in IntegerType.__subclasses__()
22-
}
23-
24-
25-
class EnumType(DictionaryType):
26-
"""
27-
Representation of the ENUM type.
28-
29-
The enumeration takes a dictionary that stores the enumeration members
30-
and current value as a string. The member values will have to be computed
31-
containing code based on C enum rules
32-
"""
33-
34-
@classmethod
35-
def construct_type(cls, name, enum_dict, rep_type="I32"):
36-
"""Construct the custom enum type
37-
38-
Constructs the custom enumeration type, with the supplied enumeration dictionary.
39-
40-
Args:
41-
name: name of the enumeration type
42-
enum_dict: enumeration: value dictionary defining the enumeration
43-
rep_type: representation type (standard Fprime integer types)
44-
"""
45-
if not isinstance(enum_dict, dict):
46-
raise TypeMismatchException(dict, type(enum_dict))
47-
for member in enum_dict.keys():
48-
if not isinstance(member, str):
49-
raise TypeMismatchException(str, type(member))
50-
if not isinstance(enum_dict[member], int):
51-
raise TypeMismatchException(int, enum_dict[member])
52-
53-
if rep_type not in REPRESENTATION_TYPE_MAP.keys():
54-
raise InvalidRepresentationTypeException(
55-
rep_type, REPRESENTATION_TYPE_MAP.keys()
56-
)
57-
58-
for member in enum_dict.keys():
59-
type_range = REPRESENTATION_TYPE_MAP[rep_type].range()
60-
if enum_dict[member] < type_range[0] or enum_dict[member] > type_range[1]:
61-
raise RepresentationTypeRangeException(
62-
member, enum_dict[member], rep_type, type_range
63-
)
64-
65-
return DictionaryType.construct_type(
66-
cls, name, ENUM_DICT=enum_dict, REP_TYPE=rep_type
67-
)
68-
69-
@classmethod
70-
def validate(cls, val):
71-
"""Validate the value passed into the enumeration"""
72-
if not isinstance(val, str):
73-
raise TypeMismatchException(str, type(val))
74-
if val not in cls.keys():
75-
raise EnumMismatchException(cls.__class__.__name__, val)
76-
77-
@classmethod
78-
def keys(cls):
79-
"""
80-
Return all the enum key values.
81-
"""
82-
return list(cls.ENUM_DICT.keys())
83-
84-
def serialize(self):
85-
"""
86-
Serialize the enumeration type using an int type
87-
"""
88-
# for enums, take the string value and convert it to
89-
# the numeric equivalent
90-
if self._val is None or (
91-
self._val == "UNDEFINED" and "UNDEFINED" not in self.ENUM_DICT
92-
):
93-
raise NotInitializedException(type(self))
94-
return struct.pack(
95-
REPRESENTATION_TYPE_MAP[self.REP_TYPE].get_serialize_format(),
96-
self.ENUM_DICT[self._val],
97-
)
98-
99-
def deserialize(self, data, offset):
100-
"""
101-
Deserialize the enumeration using an int type
102-
"""
103-
try:
104-
int_val = struct.unpack_from(
105-
REPRESENTATION_TYPE_MAP[self.REP_TYPE].get_serialize_format(),
106-
data,
107-
offset,
108-
)[0]
109-
110-
except struct.error:
111-
msg = f"Could not deserialize enum value. Needed: {self.getSize()} bytes Found: {len(data[offset:])}"
112-
raise DeserializeException(msg)
113-
for key, val in self.ENUM_DICT.items():
114-
if int_val == val:
115-
self._val = key
116-
break
117-
# Value not found, invalid enumeration value
118-
else:
119-
raise TypeRangeException(int_val)
120-
121-
def getSize(self):
122-
"""Calculates the size based on the size of an integer used to store it"""
123-
return struct.calcsize(
124-
REPRESENTATION_TYPE_MAP[self.REP_TYPE].get_serialize_format()
125-
)
126-
127-
@classmethod
128-
def getMaxSize(cls):
129-
"""Maximum size of type"""
130-
return struct.calcsize(
131-
REPRESENTATION_TYPE_MAP[cls.REP_TYPE].get_serialize_format()
132-
)
14+
# Import from new location for backward compatibility - may be removed in future versions
15+
try:
16+
from fprime_gds.common.models.serialize.enum_type import (
17+
EnumType,
18+
REPRESENTATION_TYPE_MAP,
19+
)
20+
except ImportError as e:
21+
raise ImportError(
22+
"EnumType has been moved to the fprime-gds package. "
23+
"Please install fprime-gds and update your imports to use "
24+
"`from fprime_gds.common.models.serialize.enum_type import EnumType`"
25+
) from e

0 commit comments

Comments
 (0)