Skip to content

Commit f5af8a7

Browse files
committedSep 25, 2017
pywbem: hash keeps changing - why? Embed the patch
(cherry picked from commit 23ef826)
1 parent 6a1978f commit f5af8a7

File tree

2 files changed

+493
-5
lines changed

2 files changed

+493
-5
lines changed
 

Diff for: ‎pkgs/development/python-modules/pywbem/default.nix

+2-5
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,9 @@ buildPythonPackage rec {
1515
};
1616

1717
patches = [
18-
# fix timezone handling so the tests pass again. Can go when 0.11.0 is released
18+
# fix timezone handling so the tests pass again. Can go when 0.10.1 is released
1919
# https://github.com/pywbem/pywbem/issues/755#issuecomment-327508681
20-
(fetchpatch {
21-
url = "https://github.com/pywbem/pywbem/commit/bb7fa19d636d999bf844d80939e155b8f212ef3e.patch";
22-
sha256 = "1zd5f9qrb8rnaahmazkjnf3hqsc4f7n63z44k0wcwhz7fskpqza0";
23-
})
20+
./make_cimdatetime_timezone_aware.patch
2421
];
2522

2623
propagatedBuildInputs = [ m2crypto ply pyyaml six ];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,491 @@
1+
From bb7fa19d636d999bf844d80939e155b8f212ef3e Mon Sep 17 00:00:00 2001
2+
From: Andreas Maier <maiera@de.ibm.com>
3+
Date: Fri, 23 Jun 2017 19:13:51 +0200
4+
Subject: [PATCH] Made CIMDateTime always timezone-aware, re-enabled
5+
test_cim_types.py
6+
7+
Details:
8+
- Ensured that 'CIMDateTime' objects for point in time values are
9+
timezone-aware when supplied with a timezone-naive 'datetime'
10+
object. This does not change the behavior, but increases code
11+
clarity.
12+
- Clarified that in the documentation of 'CIMDateTime'.
13+
- Added testcases for CIMDateTime.
14+
- Re-enabled the testing of test_cim_types.py. Since its change
15+
to using pytest it was not run because the test methods were
16+
all static methods which apparently does not work. Not sure
17+
this ever worked.
18+
19+
Signed-off-by: Andreas Maier <maiera@de.ibm.com>
20+
---
21+
docs/changes.rst | 5 +
22+
pywbem/cim_types.py | 22 +--
23+
testsuite/test_cim_types.py | 369 +++++++++++++++++++++++---------------------
24+
3 files changed, 207 insertions(+), 189 deletions(-)
25+
26+
diff --git a/docs/changes.rst b/docs/changes.rst
27+
index 272ed30d..6fdfbcf4 100644
28+
--- a/docs/changes.rst
29+
+++ b/docs/changes.rst
30+
@@ -72,6 +72,11 @@ Enhancements
31+
32+
* Added unit test for recorder. See issue #676
33+
34+
+* Ensured that `CIMDateTime` objects for point in time values are
35+
+ timezone-aware when supplied with a timezone-naive `datetime` object.
36+
+ This does not change the behavior, but increases code clarity.
37+
+ Clarified that in the documentation of `CIMDateTime`. See issue #698.
38+
+
39+
Bug fixes
40+
^^^^^^^^^
41+
42+
diff --git a/pywbem/cim_types.py b/pywbem/cim_types.py
43+
index 6d1f140c..5ecc7707 100644
44+
--- a/pywbem/cim_types.py
45+
+++ b/pywbem/cim_types.py
46+
@@ -74,6 +74,7 @@
47+
import re
48+
import warnings
49+
import six
50+
+import copy
51+
52+
from . import config
53+
54+
@@ -294,9 +295,11 @@ def __init__(self, dtarg):
55+
* A :term:`string` object will be
56+
interpreted as CIM datetime format (see :term:`DSP0004`) and
57+
will result in a point in time or a time interval.
58+
- * A :class:`py:datetime.datetime` object must be timezone-aware
59+
- (see :class:`~pywbem.MinutesFromUTC`) and will result in a point
60+
- in time.
61+
+ * A :class:`py:datetime.datetime` object will result in a point
62+
+ in time. If the :class:`py:datetime.datetime` object is
63+
+ timezone-aware (see :class:`~pywbem.MinutesFromUTC`), the
64+
+ specified timezone will be used. Otherwise, a default timezone
65+
+ of UTC will be assumed.
66+
* A :class:`py:datetime.timedelta` object will result in a time
67+
interval.
68+
* Another :class:`~pywbem.CIMDateTime` object will be copied.
69+
@@ -342,14 +345,15 @@ def __init__(self, dtarg):
70+
raise ValueError('dtarg argument "%s" has an invalid CIM '
71+
'datetime format' % dtarg)
72+
elif isinstance(dtarg, datetime):
73+
- self.__datetime = dtarg
74+
+ if dtarg.tzinfo is None:
75+
+ self.__datetime = dtarg.replace(tzinfo=MinutesFromUTC(0))
76+
+ else:
77+
+ self.__datetime = copy.copy(dtarg)
78+
elif isinstance(dtarg, timedelta):
79+
- self.__timedelta = dtarg
80+
+ self.__timedelta = copy.copy(dtarg)
81+
elif isinstance(dtarg, CIMDateTime):
82+
- # pylint: disable=protected-access
83+
- self.__datetime = dtarg.__datetime
84+
- # pylint: disable=protected-access
85+
- self.__timedelta = dtarg.__timedelta
86+
+ self.__datetime = copy.copy(dtarg.datetime)
87+
+ self.__timedelta = copy.copy(dtarg.timedelta)
88+
else:
89+
raise TypeError('dtarg argument "%s" has an invalid type: %s '
90+
'(expected datetime, timedelta, string, or '
91+
diff --git a/testsuite/test_cim_types.py b/testsuite/test_cim_types.py
92+
index 4ae354d3..b1f54d06 100755
93+
--- a/testsuite/test_cim_types.py
94+
+++ b/testsuite/test_cim_types.py
95+
@@ -43,105 +43,99 @@ def integer_tuple(request):
96+
return request.param
97+
98+
99+
-class TestIntegers:
100+
- """
101+
- Test CIM integer data type classes.
102+
- """
103+
-
104+
- @staticmethod
105+
- def test_class_attrs_class(integer_tuple):
106+
- """Test class attrs via class level"""
107+
- obj_type, exp_cimtype, exp_minvalue, exp_maxvalue = integer_tuple
108+
- assert obj_type.cimtype == exp_cimtype
109+
- assert obj_type.minvalue == exp_minvalue
110+
- assert obj_type.maxvalue == exp_maxvalue
111+
-
112+
- @staticmethod
113+
- def test_class_attrs_inst(integer_tuple):
114+
- """Test class attrs via instance level"""
115+
- obj_type, exp_cimtype, exp_minvalue, exp_maxvalue = integer_tuple
116+
- obj = obj_type(42)
117+
- assert obj.cimtype == exp_cimtype
118+
- assert obj.minvalue == exp_minvalue
119+
- assert obj.maxvalue == exp_maxvalue
120+
-
121+
- @staticmethod
122+
- def test_inheritance(integer_tuple):
123+
- """Test inheritance"""
124+
- obj_type = integer_tuple[0]
125+
- obj = obj_type(42)
126+
- assert isinstance(obj, obj_type)
127+
- assert isinstance(obj, CIMType)
128+
- assert isinstance(obj, CIMInt)
129+
- assert not isinstance(obj, CIMFloat)
130+
-
131+
- @staticmethod
132+
- def test_init_int(integer_tuple):
133+
- """Test initialization from integer value"""
134+
- obj_type = integer_tuple[0]
135+
- obj = obj_type(42)
136+
- assert obj == 42
137+
-
138+
- @staticmethod
139+
- def test_init_str(integer_tuple):
140+
- """Test initialization from string value"""
141+
- obj_type = integer_tuple[0]
142+
- obj = obj_type('42')
143+
- assert obj == 42
144+
-
145+
- @staticmethod
146+
- def test_init_str_base10(integer_tuple):
147+
- """Test initialization from string value with base 10"""
148+
- obj_type = integer_tuple[0]
149+
- obj = obj_type('42', 10)
150+
- assert obj == 42
151+
-
152+
- @staticmethod
153+
- def test_init_str_base16(integer_tuple):
154+
- """Test initialization from string value with base 16"""
155+
- obj_type = integer_tuple[0]
156+
- obj = obj_type('2A', 16)
157+
- assert obj == 42
158+
-
159+
- @staticmethod
160+
- def test_init_minimum(integer_tuple):
161+
- """Test initialization from integer value at minimum"""
162+
- obj_type = integer_tuple[0]
163+
- exp_minvalue = integer_tuple[2]
164+
- obj = obj_type(exp_minvalue)
165+
- assert obj == exp_minvalue
166+
-
167+
- @staticmethod
168+
- def test_init_maximum(integer_tuple):
169+
- """Test initialization from integer value at maximum"""
170+
- obj_type = integer_tuple[0]
171+
- exp_maxvalue = integer_tuple[3]
172+
- obj = obj_type(exp_maxvalue)
173+
- assert obj == exp_maxvalue
174+
-
175+
- @staticmethod
176+
- def test_init_too_low(integer_tuple):
177+
- """Test initialization from integer value below minimum"""
178+
- obj_type = integer_tuple[0]
179+
- exp_minvalue = integer_tuple[2]
180+
- try:
181+
- obj_type(exp_minvalue - 1)
182+
- except ValueError:
183+
- pass
184+
- else:
185+
- raise AssertionError("ValueError was not raised.")
186+
-
187+
- @staticmethod
188+
- def test_init_too_high(integer_tuple):
189+
- """Test initialization from integer value above maximum"""
190+
- obj_type = integer_tuple[0]
191+
- exp_maxvalue = integer_tuple[3]
192+
- try:
193+
- obj_type(exp_maxvalue + 1)
194+
- except ValueError:
195+
- pass
196+
- else:
197+
- raise AssertionError("ValueError was not raised.")
198+
+def test_integer_class_attrs_class(integer_tuple):
199+
+ """Test class attrs via class level"""
200+
+ obj_type, exp_cimtype, exp_minvalue, exp_maxvalue = integer_tuple
201+
+ assert obj_type.cimtype == exp_cimtype
202+
+ assert obj_type.minvalue == exp_minvalue
203+
+ assert obj_type.maxvalue == exp_maxvalue
204+
+
205+
+
206+
+def test_integer_class_attrs_inst(integer_tuple):
207+
+ """Test class attrs via instance level"""
208+
+ obj_type, exp_cimtype, exp_minvalue, exp_maxvalue = integer_tuple
209+
+ obj = obj_type(42)
210+
+ assert obj.cimtype == exp_cimtype
211+
+ assert obj.minvalue == exp_minvalue
212+
+ assert obj.maxvalue == exp_maxvalue
213+
+
214+
+
215+
+def test_integer_inheritance(integer_tuple):
216+
+ """Test inheritance"""
217+
+ obj_type = integer_tuple[0]
218+
+ obj = obj_type(42)
219+
+ assert isinstance(obj, obj_type)
220+
+ assert isinstance(obj, CIMType)
221+
+ assert isinstance(obj, CIMInt)
222+
+ assert not isinstance(obj, CIMFloat)
223+
+
224+
+
225+
+def test_integer_init_int(integer_tuple):
226+
+ """Test initialization from integer value"""
227+
+ obj_type = integer_tuple[0]
228+
+ obj = obj_type(42)
229+
+ assert obj == 42
230+
+
231+
+
232+
+def test_integer_init_str(integer_tuple):
233+
+ """Test initialization from string value"""
234+
+ obj_type = integer_tuple[0]
235+
+ obj = obj_type('42')
236+
+ assert obj == 42
237+
+
238+
+
239+
+def test_integer_init_str_base10(integer_tuple):
240+
+ """Test initialization from string value with base 10"""
241+
+ obj_type = integer_tuple[0]
242+
+ obj = obj_type('42', 10)
243+
+ assert obj == 42
244+
+
245+
+
246+
+def test_integer_init_str_base16(integer_tuple):
247+
+ """Test initialization from string value with base 16"""
248+
+ obj_type = integer_tuple[0]
249+
+ obj = obj_type('2A', 16)
250+
+ assert obj == 42
251+
+
252+
+
253+
+def test_integer_init_minimum(integer_tuple):
254+
+ """Test initialization from integer value at minimum"""
255+
+ obj_type = integer_tuple[0]
256+
+ exp_minvalue = integer_tuple[2]
257+
+ obj = obj_type(exp_minvalue)
258+
+ assert obj == exp_minvalue
259+
+
260+
+
261+
+def test_integer_init_maximum(integer_tuple):
262+
+ """Test initialization from integer value at maximum"""
263+
+ obj_type = integer_tuple[0]
264+
+ exp_maxvalue = integer_tuple[3]
265+
+ obj = obj_type(exp_maxvalue)
266+
+ assert obj == exp_maxvalue
267+
+
268+
+
269+
+def test_integer_init_too_low(integer_tuple):
270+
+ """Test initialization from integer value below minimum"""
271+
+ obj_type = integer_tuple[0]
272+
+ exp_minvalue = integer_tuple[2]
273+
+ try:
274+
+ obj_type(exp_minvalue - 1)
275+
+ except ValueError:
276+
+ pass
277+
+ else:
278+
+ raise AssertionError("ValueError was not raised.")
279+
+
280+
+
281+
+def test_integer_init_too_high(integer_tuple):
282+
+ """Test initialization from integer value above maximum"""
283+
+ obj_type = integer_tuple[0]
284+
+ exp_maxvalue = integer_tuple[3]
285+
+ try:
286+
+ obj_type(exp_maxvalue + 1)
287+
+ except ValueError:
288+
+ pass
289+
+ else:
290+
+ raise AssertionError("ValueError was not raised.")
291+
292+
293+
#
294+
@@ -164,47 +158,41 @@ def real_tuple(request):
295+
return request.param
296+
297+
298+
-class TestReals:
299+
- """
300+
- Test CIM real data type classes.
301+
- """
302+
-
303+
- @staticmethod
304+
- def test_class_attrs_class(real_tuple):
305+
- """Test class attrs via class level"""
306+
- obj_type, exp_cimtype = real_tuple
307+
- assert obj_type.cimtype == exp_cimtype
308+
-
309+
- @staticmethod
310+
- def test_class_attrs_inst(real_tuple):
311+
- """Test class attrs via instance level"""
312+
- obj_type, exp_cimtype = real_tuple
313+
- obj = obj_type(42)
314+
- assert obj.cimtype == exp_cimtype
315+
-
316+
- @staticmethod
317+
- def test_inheritance(real_tuple):
318+
- """Test inheritance"""
319+
- obj_type = real_tuple[0]
320+
- obj = obj_type(42)
321+
- assert isinstance(obj, obj_type)
322+
- assert isinstance(obj, CIMType)
323+
- assert isinstance(obj, CIMFloat)
324+
- assert not isinstance(obj, CIMInt)
325+
-
326+
- @staticmethod
327+
- def test_init_float(real_tuple):
328+
- """Test initialization from floating point value"""
329+
- obj_type = real_tuple[0]
330+
- obj = obj_type(42.0)
331+
- assert obj == 42.0
332+
-
333+
- @staticmethod
334+
- def test_init_str(real_tuple):
335+
- """Test initialization from string value"""
336+
- obj_type = real_tuple[0]
337+
- obj = obj_type('42.0')
338+
- assert obj == 42.0
339+
+def test_real_class_attrs_class(real_tuple):
340+
+ """Test class attrs via class level"""
341+
+ obj_type, exp_cimtype = real_tuple
342+
+ assert obj_type.cimtype == exp_cimtype
343+
+
344+
+
345+
+def test_real_class_attrs_inst(real_tuple):
346+
+ """Test class attrs via instance level"""
347+
+ obj_type, exp_cimtype = real_tuple
348+
+ obj = obj_type(42)
349+
+ assert obj.cimtype == exp_cimtype
350+
+
351+
+
352+
+def test_real_inheritance(real_tuple):
353+
+ """Test inheritance"""
354+
+ obj_type = real_tuple[0]
355+
+ obj = obj_type(42)
356+
+ assert isinstance(obj, obj_type)
357+
+ assert isinstance(obj, CIMType)
358+
+ assert isinstance(obj, CIMFloat)
359+
+ assert not isinstance(obj, CIMInt)
360+
+
361+
+
362+
+def test_real_init_float(real_tuple):
363+
+ """Test initialization from floating point value"""
364+
+ obj_type = real_tuple[0]
365+
+ obj = obj_type(42.0)
366+
+ assert obj == 42.0
367+
+
368+
+
369+
+def test_real_init_str(real_tuple):
370+
+ """Test initialization from string value"""
371+
+ obj_type = real_tuple[0]
372+
+ obj = obj_type('42.0')
373+
+ assert obj == 42.0
374+
375+
376+
#
377+
@@ -271,6 +259,26 @@ def test_init_str(real_tuple):
378+
'20140924193040.654321+120'
379+
),
380+
(
381+
+ datetime(year=2014, month=9, day=24, hour=19, minute=30, second=40,
382+
+ microsecond=654321, tzinfo=MinutesFromUTC(0)),
383+
+ 'timestamp',
384+
+ datetime(year=2014, month=9, day=24, hour=19, minute=30, second=40,
385+
+ microsecond=654321, tzinfo=MinutesFromUTC(0)),
386+
+ None,
387+
+ 0,
388+
+ '20140924193040.654321+000'
389+
+ ),
390+
+ (
391+
+ datetime(year=2014, month=9, day=24, hour=19, minute=30, second=40,
392+
+ microsecond=654321),
393+
+ 'timestamp',
394+
+ datetime(year=2014, month=9, day=24, hour=19, minute=30, second=40,
395+
+ microsecond=654321, tzinfo=MinutesFromUTC(0)),
396+
+ None,
397+
+ 0,
398+
+ '20140924193040.654321+000'
399+
+ ),
400+
+ (
401+
'20140924193040.654321+120',
402+
'timestamp',
403+
datetime(year=2014, month=9, day=24, hour=19, minute=30, second=40,
404+
@@ -325,46 +333,47 @@ def datetime_init_tuple(request):
405+
return request.param
406+
407+
408+
-class TestDatetime:
409+
- """
410+
- Test CIM real data type classes.
411+
- """
412+
-
413+
- @staticmethod
414+
- def test_class_attrs_class():
415+
- """Test class attrs via class level"""
416+
- assert CIMDateTime.cimtype == 'datetime'
417+
-
418+
- @staticmethod
419+
- def test_class_attrs_inst():
420+
- """Test class attrs via instance level"""
421+
- obj = CIMDateTime('00000000000000.000000:000')
422+
- assert obj.cimtype == 'datetime'
423+
-
424+
- @staticmethod
425+
- def test_inheritance():
426+
- """Test inheritance"""
427+
- obj = CIMDateTime('00000000000000.000000:000')
428+
- assert isinstance(obj, CIMDateTime)
429+
- assert isinstance(obj, CIMType)
430+
- assert not isinstance(obj, CIMFloat)
431+
- assert not isinstance(obj, CIMInt)
432+
-
433+
- @staticmethod
434+
- def test_init(datetime_init_tuple):
435+
- """Test initialization from all input types"""
436+
- (dtarg, exp_kind, exp_datetime, exp_timedelta, exp_minutesfromutc,
437+
- exp_str) = datetime_init_tuple
438+
- try:
439+
- obj = CIMDateTime(dtarg)
440+
- except Exception as exc:
441+
- assert isinstance(exc, exp_kind)
442+
- else:
443+
- assert obj.is_interval == (exp_kind == 'interval')
444+
- assert obj.datetime == exp_datetime
445+
- assert obj.timedelta == exp_timedelta
446+
- assert obj.minutes_from_utc == exp_minutesfromutc
447+
- assert str(obj) == exp_str
448+
+def test_datetime_class_attrs_class():
449+
+ """Test class attrs via class level"""
450+
+ assert CIMDateTime.cimtype == 'datetime'
451+
+
452+
+
453+
+def test_datetime_class_attrs_inst():
454+
+ """Test class attrs via instance level"""
455+
+ obj = CIMDateTime('00000000000000.000000:000')
456+
+ assert obj.cimtype == 'datetime'
457+
+
458+
+
459+
+def test_datetime_inheritance():
460+
+ """Test inheritance"""
461+
+ obj = CIMDateTime('00000000000000.000000:000')
462+
+ assert isinstance(obj, CIMDateTime)
463+
+ assert isinstance(obj, CIMType)
464+
+ assert not isinstance(obj, CIMFloat)
465+
+ assert not isinstance(obj, CIMInt)
466+
+
467+
+
468+
+def test_datetime_init(datetime_init_tuple):
469+
+ """Test initialization from all input types"""
470+
+ (dtarg, exp_kind, exp_datetime, exp_timedelta, exp_minutesfromutc,
471+
+ exp_str) = datetime_init_tuple
472+
+ try:
473+
+ obj = CIMDateTime(dtarg)
474+
+ except Exception as exc:
475+
+ assert isinstance(exc, exp_kind)
476+
+ else:
477+
+ assert obj.is_interval == (exp_kind == 'interval')
478+
+ assert obj.datetime == exp_datetime
479+
+ if obj.datetime is not None:
480+
+ assert isinstance(obj.datetime, datetime)
481+
+ # We ensure that the datetime is always timezone-aware:
482+
+ assert obj.datetime.tzinfo is not None
483+
+ assert obj.timedelta == exp_timedelta
484+
+ if obj.timedelta is not None:
485+
+ assert isinstance(obj.timedelta, timedelta)
486+
+ assert obj.minutes_from_utc == exp_minutesfromutc
487+
+ assert str(obj) == exp_str
488+
+
489+
490+
# TODO: Add testcases for get_local_utcoffset()
491+
# TODO: Add testcases for now()

0 commit comments

Comments
 (0)
Please sign in to comment.