Skip to content

Commit c16f989

Browse files
authored
Merge pull request #264 from mpsonntag/refid
dtype handling and setting id LGTM
2 parents 4a10c2c + 4d956da commit c16f989

8 files changed

Lines changed: 181 additions & 23 deletions

File tree

odml/doc.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,18 @@ def id(self):
4848
"""
4949
return self._id
5050

51+
def new_id(self, id=None):
52+
"""
53+
new_id sets the id of the current object to a RFC 4122 compliant UUID.
54+
If an id was provided, it is assigned if it is RFC 4122 UUID format compliant.
55+
If no id was provided, a new UUID is generated and assigned.
56+
:param id: UUID string as specified in RFC 4122.
57+
"""
58+
if id is not None:
59+
self._id = str(uuid.UUID(id))
60+
else:
61+
self._id = str(uuid.uuid4())
62+
5163
@property
5264
def author(self):
5365
"""

odml/dtypes.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
import sys
21
import datetime as dt
2+
import re
3+
import sys
4+
35
from enum import Enum
6+
47
self = sys.modules[__name__].__dict__
58

69
"""
@@ -76,14 +79,24 @@ def infer_dtype(value):
7679

7780
def valid_type(dtype):
7881
"""
79-
Checks if *dtype* is a valid type
82+
Checks if *dtype* is a valid odML value data type.
8083
"""
84+
if dtype is None:
85+
return True
86+
87+
if not isinstance(dtype, str) and not isinstance(dtype, unicode):
88+
return False
89+
8190
dtype = dtype.lower()
8291
if dtype in _dtype_map:
8392
dtype = _dtype_map[dtype]
93+
8494
if hasattr(DType, dtype):
8595
return True
86-
if dtype is None:
96+
97+
# Check odML tuple dtype.
98+
rexp = re.compile("^[1-9][0-9]*-tuple$")
99+
if len(rexp.findall(dtype)) == 1:
87100
return True
88101

89102
return False

odml/property.py

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,23 +58,42 @@ def __init__(self, name, value=None, parent=None, unit=None,
5858
print(e)
5959
self._id = str(uuid.uuid4())
6060
self._name = name
61-
self._parent = None
62-
self._value = []
6361
self._value_origin = value_origin
6462
self._unit = unit
6563
self._uncertainty = uncertainty
6664
self._reference = reference
6765
self._definition = definition
6866
self._dependency = dependency
6967
self._dependency_value = dependency_value
70-
self._dtype = dtype
68+
69+
self._dtype = None
70+
if dtypes.valid_type(dtype):
71+
self._dtype = dtype
72+
else:
73+
print("Warning: Unknown dtype '%s'." % dtype)
74+
75+
self._value = []
7176
self.value = value
77+
78+
self._parent = None
7279
self.parent = parent
7380

7481
@property
7582
def id(self):
7683
return self._id
7784

85+
def new_id(self, id=None):
86+
"""
87+
new_id sets the id of the current object to a RFC 4122 compliant UUID.
88+
If an id was provided, it is assigned if it is RFC 4122 UUID format compliant.
89+
If no id was provided, a new UUID is generated and assigned.
90+
:param id: UUID string as specified in RFC 4122.
91+
"""
92+
if id is not None:
93+
self._id = str(uuid.UUID(id))
94+
else:
95+
self._id = str(uuid.uuid4())
96+
7897
@property
7998
def name(self):
8099
return self._name

odml/section.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,18 @@ def __repr__(self):
6161
def id(self):
6262
return self._id
6363

64+
def new_id(self, id=None):
65+
"""
66+
new_id sets the id of the current object to a RFC 4122 compliant UUID.
67+
If an id was provided, it is assigned if it is RFC 4122 UUID format compliant.
68+
If no id was provided, a new UUID is generated and assigned.
69+
:param id: UUID string as specified in RFC 4122.
70+
"""
71+
if id is not None:
72+
self._id = str(uuid.UUID(id))
73+
else:
74+
self._id = str(uuid.uuid4())
75+
6476
@property
6577
def name(self):
6678
return self._name

test/test_doc.py

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,34 @@ class TestSection(unittest.TestCase):
77
def setUp(self):
88
pass
99

10-
def test_set_id(self):
11-
d = Document("D", id="79b613eb-a256-46bf-84f6-207df465b8f7")
12-
self.assertEqual(d.id, "79b613eb-a256-46bf-84f6-207df465b8f7")
10+
def test_id(self):
11+
doc = Document()
12+
self.assertIsNotNone(doc.id)
1313

14-
Document("D", id="id")
15-
self.assertNotEqual(d.id, "id")
14+
doc = Document("D", id="79b613eb-a256-46bf-84f6-207df465b8f7")
15+
self.assertEqual(doc.id, "79b613eb-a256-46bf-84f6-207df465b8f7")
16+
17+
doc = Document("D", id="id")
18+
self.assertNotEqual(doc.id, "id")
19+
20+
# Make sure id cannot be reset programmatically.
21+
with self.assertRaises(AttributeError):
22+
doc.id = "someId"
23+
24+
def test_new_id(self):
25+
doc = Document()
26+
old_id = doc.id
27+
28+
# Test assign new generated id.
29+
doc.new_id()
30+
self.assertNotEqual(old_id, doc.id)
31+
32+
# Test assign new custom id.
33+
old_id = doc.id
34+
doc.new_id("79b613eb-a256-46bf-84f6-207df465b8f7")
35+
self.assertNotEqual(old_id, doc.id)
36+
self.assertEqual("79b613eb-a256-46bf-84f6-207df465b8f7", doc.id)
37+
38+
# Test invalid custom id exception.
39+
with self.assertRaises(ValueError):
40+
doc.new_id("crash and burn")

test/test_dtypes.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,28 @@ class TestTypes(unittest.TestCase):
99
def setUp(self):
1010
pass
1111

12+
def test_valid_type(self):
13+
# Test None
14+
self.assertTrue(typ.valid_type(None))
15+
16+
# Test that all DTypes classify as valid dtypes.
17+
for curr_type in typ.DType:
18+
self.assertTrue(typ.valid_type(curr_type), "Invalid DType %s" % curr_type)
19+
20+
# Test that provided shorthand dtypes return as valid dtypes.
21+
for curr_shorthand in typ._dtype_map.keys():
22+
self.assertTrue(typ.valid_type(curr_shorthand),
23+
"Invalid dtype shorthand %s" % curr_shorthand)
24+
25+
# Test valid tuple dtype
26+
self.assertTrue(typ.valid_type("2-tuple"))
27+
self.assertTrue(typ.valid_type("293939-tuple"))
28+
29+
# Test invalid dtypes
30+
self.assertFalse(typ.valid_type(1))
31+
self.assertFalse(typ.valid_type("unsupported"))
32+
self.assertFalse(typ.valid_type("x-tuple"))
33+
1234
def test_date(self):
1335
self.assertIsInstance(typ.date_get(None), datetime.date)
1436
self.assertIsInstance(typ.date_get(""), datetime.date)

test/test_property.py

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ def test_value(self):
7070
p5.extend("[a, b, c]")
7171
self.assertEqual(len(p5), 5)
7272

73-
p6 = Property("test", {"name": "Marie", "name":"Johanna"})
73+
p6 = Property("test", {"name": "Marie", "name": "Johanna"})
7474
self.assertEqual(len(p6), 1)
7575

7676
# Test tuple dtype value.
@@ -83,14 +83,6 @@ def test_value(self):
8383
with self.assertRaises(ValueError):
8484
_ = Property(name="Public-Key", value='(5689; 1254; 687)', dtype='2-tuple')
8585

86-
# Test missing tuple length.
87-
with self.assertRaises(ValueError):
88-
_ = Property(name="Public-Key", value='(5689; 1254; 687)', dtype='-tuple')
89-
90-
# Test invalid tuple format.
91-
with self.assertRaises(ValueError):
92-
_ = Property(name="Public-Key", value='5689; 1254; 687', dtype='3-tuple')
93-
9486
def test_get_set_value(self):
9587
values = [1, 2, 3, 4, 5]
9688
p = Property("property", value=values)
@@ -185,7 +177,34 @@ def test_parent(self):
185177
Property("property_doc", parent=Document())
186178

187179
def test_dtype(self):
188-
pass
180+
prop = Property(name="prop")
181+
182+
# Test assignment of all supported dtypes.
183+
for curr_type in DType:
184+
prop.dtype = curr_type
185+
self.assertEqual(prop.dtype, curr_type)
186+
187+
# Test assignment of dtype alias.
188+
prop.dtype = "bool"
189+
self.assertEqual(prop.dtype, "bool")
190+
prop.dtype = "str"
191+
self.assertEqual(prop.dtype, "str")
192+
193+
# Test assignment of tuple.
194+
prop.dtype = "2-tuple"
195+
self.assertEqual(prop.dtype, "2-tuple")
196+
197+
# Test set None
198+
prop.dtype = None
199+
self.assertIsNone(prop.dtype)
200+
201+
# Test assignment fails.
202+
with self.assertRaises(AttributeError):
203+
prop.dtype = 1
204+
with self.assertRaises(AttributeError):
205+
prop.dtype = "crash and burn"
206+
with self.assertRaises(AttributeError):
207+
prop.dtype = "x-tuple"
189208

190209
def test_get_path(self):
191210
doc = Document()
@@ -207,7 +226,7 @@ def test_value_origin(self):
207226
p.value_origin = ""
208227
self.assertEqual(p.value_origin, None)
209228

210-
def test_set_id(self):
229+
def test_id(self):
211230
p = Property(name="P")
212231
self.assertIsNotNone(p.id)
213232

@@ -221,6 +240,24 @@ def test_set_id(self):
221240
with self.assertRaises(AttributeError):
222241
p.id = "someId"
223242

243+
def test_new_id(self):
244+
prop = Property(name="prop")
245+
old_id = prop.id
246+
247+
# Test assign new generated id.
248+
prop.new_id()
249+
self.assertNotEqual(old_id, prop.id)
250+
251+
# Test assign new custom id.
252+
old_id = prop.id
253+
prop.new_id("79b613eb-a256-46bf-84f6-207df465b8f7")
254+
self.assertNotEqual(old_id, prop.id)
255+
self.assertEqual("79b613eb-a256-46bf-84f6-207df465b8f7", prop.id)
256+
257+
# Test invalid custom id exception.
258+
with self.assertRaises(ValueError):
259+
prop.new_id("crash and burn")
260+
224261
def test_merge(self):
225262
p_dst = Property("p1", value=[1, 2, 3], unit="Hz", definition="Freude\t schoener\nGoetterfunken\n",
226263
reference="portal.g-node.org", uncertainty=0.0)

test/test_section.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def test_dtype(self):
5656
def test_path(self):
5757
pass
5858

59-
def test_set_id(self):
59+
def test_id(self):
6060
s = Section(name="S")
6161
self.assertIsNotNone(s.id)
6262

@@ -70,6 +70,24 @@ def test_set_id(self):
7070
with self.assertRaises(AttributeError):
7171
s.id = "someId"
7272

73+
def test_new_id(self):
74+
sec = Section(name="sec")
75+
old_id = sec.id
76+
77+
# Test assign new generated id.
78+
sec.new_id()
79+
self.assertNotEqual(old_id, sec.id)
80+
81+
# Test assign new custom id.
82+
old_id = sec.id
83+
sec.new_id("79b613eb-a256-46bf-84f6-207df465b8f7")
84+
self.assertNotEqual(old_id, sec.id)
85+
self.assertEqual("79b613eb-a256-46bf-84f6-207df465b8f7", sec.id)
86+
87+
# Test invalid custom id exception.
88+
with self.assertRaises(ValueError):
89+
sec.new_id("crash and burn")
90+
7391
def test_clone(self):
7492
# Check parent removal in clone.
7593
psec = Section(name="parent")

0 commit comments

Comments
 (0)