diff --git a/pkgs/development/python-modules/pywbem/default.nix b/pkgs/development/python-modules/pywbem/default.nix index 159e0ce15fb4..90a415060eb8 100644 --- a/pkgs/development/python-modules/pywbem/default.nix +++ b/pkgs/development/python-modules/pywbem/default.nix @@ -1,50 +1,57 @@ -{ stdenv, buildPythonPackage, fetchFromGitHub, libxml2 -, m2crypto, ply, pyyaml, six -, httpretty, lxml, mock, pytest, requests +{ lib, buildPythonPackage, fetchPypi, libxml2 +, m2crypto, ply, pyyaml, six, pbr, pythonOlder, isPy37, python +, httpretty, lxml, mock, pytest, requests, decorator, unittest2 }: buildPythonPackage rec { pname = "pywbem"; - version = "0.10.0"; + version = "0.12.6"; - src = fetchFromGitHub { - owner = "pywbem"; - repo = "pywbem"; - rev = "v${version}"; - sha256 = "0jcwklip03xcni0dvsk9va8ilqz21g4fxwqd5kzvv91slaadfcym"; + # Support added in master https://github.com/pywbem/pywbem/commit/b2f2f1a151a30355bbc6652dca69a7b30bfe941e awaiting release + disabled = isPy37; + + src = fetchPypi { + inherit pname version; + sha256 = "1dc6b745rrys600n05apdf6lb2vv5arlcwv7aiz9whgkbcd9qhki"; }; - patches = [ - # fix timezone handling so the tests pass again. Can go when 0.10.1 is released - # https://github.com/pywbem/pywbem/issues/755#issuecomment-327508681 - ./make_cimdatetime_timezone_aware.patch + propagatedBuildInputs = [ + mock + pbr + ply + pyyaml + six + ] ++ lib.optionals (pythonOlder "3.0") [ m2crypto ]; + + checkInputs = [ + decorator + httpretty + libxml2 + lxml + pytest + requests + unittest2 ]; - propagatedBuildInputs = [ m2crypto ply pyyaml six ]; + postPatch = '' + # Uses deprecated library yamlordereddictloader + rm testsuite/test_client.py - checkInputs = [ httpretty lxml mock pytest requests ]; - - # 1 test fails because it doesn't like running in our sandbox. Deleting the - # whole file is admittedly a little heavy-handed but at least the vast - # majority of tests are run. - checkPhase = '' - rm testsuite/testclient/networkerror.yaml - - substituteInPlace makefile \ - --replace "PYTHONPATH=." "" \ - --replace '--cov $(package_name) --cov-config coveragerc' "" - - for f in testsuite/test_cim_xml.py testsuite/validate.py ; do - substituteInPlace $f --replace "'xmllint" "'${stdenv.lib.getBin libxml2}/bin/xmllint" - done - - make PATH=$PATH:${stdenv.lib.getBin libxml2}/bin test + # Wants `wbemcli` in PATH + rm testsuite/test_wbemcli.py + + # Disables tests that use testfixtures which is currently broken by nonbuilding zope_component + rm testsuite/{test_logging,test_recorder,test_wbemconnection_mock}.* ''; - meta = with stdenv.lib; { - description = "Support for the WBEM standard for systems management."; - homepage = http://pywbem.github.io/pywbem/; - license = licenses.gpl2; + checkPhase = '' + pytest testsuite/ + ''; + + meta = with lib; { + description = "Support for the WBEM standard for systems management"; + homepage = https://pywbem.github.io; + license = licenses.lgpl21Plus; maintainers = with maintainers; [ peterhoeg ]; }; } diff --git a/pkgs/development/python-modules/pywbem/make_cimdatetime_timezone_aware.patch b/pkgs/development/python-modules/pywbem/make_cimdatetime_timezone_aware.patch deleted file mode 100644 index 55fb9bbb12d7..000000000000 --- a/pkgs/development/python-modules/pywbem/make_cimdatetime_timezone_aware.patch +++ /dev/null @@ -1,491 +0,0 @@ -From bb7fa19d636d999bf844d80939e155b8f212ef3e Mon Sep 17 00:00:00 2001 -From: Andreas Maier -Date: Fri, 23 Jun 2017 19:13:51 +0200 -Subject: [PATCH] Made CIMDateTime always timezone-aware, re-enabled - test_cim_types.py - -Details: -- Ensured that 'CIMDateTime' objects for point in time values are - timezone-aware when supplied with a timezone-naive 'datetime' - object. This does not change the behavior, but increases code - clarity. -- Clarified that in the documentation of 'CIMDateTime'. -- Added testcases for CIMDateTime. -- Re-enabled the testing of test_cim_types.py. Since its change - to using pytest it was not run because the test methods were - all static methods which apparently does not work. Not sure - this ever worked. - -Signed-off-by: Andreas Maier ---- - docs/changes.rst | 5 + - pywbem/cim_types.py | 22 +-- - testsuite/test_cim_types.py | 369 +++++++++++++++++++++++--------------------- - 3 files changed, 207 insertions(+), 189 deletions(-) - -diff --git a/docs/changes.rst b/docs/changes.rst -index 272ed30d..6fdfbcf4 100644 ---- a/docs/changes.rst -+++ b/docs/changes.rst -@@ -72,6 +72,11 @@ Enhancements - - * Added unit test for recorder. See issue #676 - -+* Ensured that `CIMDateTime` objects for point in time values are -+ timezone-aware when supplied with a timezone-naive `datetime` object. -+ This does not change the behavior, but increases code clarity. -+ Clarified that in the documentation of `CIMDateTime`. See issue #698. -+ - Bug fixes - ^^^^^^^^^ - -diff --git a/pywbem/cim_types.py b/pywbem/cim_types.py -index 6d1f140c..5ecc7707 100644 ---- a/pywbem/cim_types.py -+++ b/pywbem/cim_types.py -@@ -74,6 +74,7 @@ - import re - import warnings - import six -+import copy - - from . import config - -@@ -294,9 +295,11 @@ def __init__(self, dtarg): - * A :term:`string` object will be - interpreted as CIM datetime format (see :term:`DSP0004`) and - will result in a point in time or a time interval. -- * A :class:`py:datetime.datetime` object must be timezone-aware -- (see :class:`~pywbem.MinutesFromUTC`) and will result in a point -- in time. -+ * A :class:`py:datetime.datetime` object will result in a point -+ in time. If the :class:`py:datetime.datetime` object is -+ timezone-aware (see :class:`~pywbem.MinutesFromUTC`), the -+ specified timezone will be used. Otherwise, a default timezone -+ of UTC will be assumed. - * A :class:`py:datetime.timedelta` object will result in a time - interval. - * Another :class:`~pywbem.CIMDateTime` object will be copied. -@@ -342,14 +345,15 @@ def __init__(self, dtarg): - raise ValueError('dtarg argument "%s" has an invalid CIM ' - 'datetime format' % dtarg) - elif isinstance(dtarg, datetime): -- self.__datetime = dtarg -+ if dtarg.tzinfo is None: -+ self.__datetime = dtarg.replace(tzinfo=MinutesFromUTC(0)) -+ else: -+ self.__datetime = copy.copy(dtarg) - elif isinstance(dtarg, timedelta): -- self.__timedelta = dtarg -+ self.__timedelta = copy.copy(dtarg) - elif isinstance(dtarg, CIMDateTime): -- # pylint: disable=protected-access -- self.__datetime = dtarg.__datetime -- # pylint: disable=protected-access -- self.__timedelta = dtarg.__timedelta -+ self.__datetime = copy.copy(dtarg.datetime) -+ self.__timedelta = copy.copy(dtarg.timedelta) - else: - raise TypeError('dtarg argument "%s" has an invalid type: %s ' - '(expected datetime, timedelta, string, or ' -diff --git a/testsuite/test_cim_types.py b/testsuite/test_cim_types.py -index 4ae354d3..b1f54d06 100755 ---- a/testsuite/test_cim_types.py -+++ b/testsuite/test_cim_types.py -@@ -43,105 +43,99 @@ def integer_tuple(request): - return request.param - - --class TestIntegers: -- """ -- Test CIM integer data type classes. -- """ -- -- @staticmethod -- def test_class_attrs_class(integer_tuple): -- """Test class attrs via class level""" -- obj_type, exp_cimtype, exp_minvalue, exp_maxvalue = integer_tuple -- assert obj_type.cimtype == exp_cimtype -- assert obj_type.minvalue == exp_minvalue -- assert obj_type.maxvalue == exp_maxvalue -- -- @staticmethod -- def test_class_attrs_inst(integer_tuple): -- """Test class attrs via instance level""" -- obj_type, exp_cimtype, exp_minvalue, exp_maxvalue = integer_tuple -- obj = obj_type(42) -- assert obj.cimtype == exp_cimtype -- assert obj.minvalue == exp_minvalue -- assert obj.maxvalue == exp_maxvalue -- -- @staticmethod -- def test_inheritance(integer_tuple): -- """Test inheritance""" -- obj_type = integer_tuple[0] -- obj = obj_type(42) -- assert isinstance(obj, obj_type) -- assert isinstance(obj, CIMType) -- assert isinstance(obj, CIMInt) -- assert not isinstance(obj, CIMFloat) -- -- @staticmethod -- def test_init_int(integer_tuple): -- """Test initialization from integer value""" -- obj_type = integer_tuple[0] -- obj = obj_type(42) -- assert obj == 42 -- -- @staticmethod -- def test_init_str(integer_tuple): -- """Test initialization from string value""" -- obj_type = integer_tuple[0] -- obj = obj_type('42') -- assert obj == 42 -- -- @staticmethod -- def test_init_str_base10(integer_tuple): -- """Test initialization from string value with base 10""" -- obj_type = integer_tuple[0] -- obj = obj_type('42', 10) -- assert obj == 42 -- -- @staticmethod -- def test_init_str_base16(integer_tuple): -- """Test initialization from string value with base 16""" -- obj_type = integer_tuple[0] -- obj = obj_type('2A', 16) -- assert obj == 42 -- -- @staticmethod -- def test_init_minimum(integer_tuple): -- """Test initialization from integer value at minimum""" -- obj_type = integer_tuple[0] -- exp_minvalue = integer_tuple[2] -- obj = obj_type(exp_minvalue) -- assert obj == exp_minvalue -- -- @staticmethod -- def test_init_maximum(integer_tuple): -- """Test initialization from integer value at maximum""" -- obj_type = integer_tuple[0] -- exp_maxvalue = integer_tuple[3] -- obj = obj_type(exp_maxvalue) -- assert obj == exp_maxvalue -- -- @staticmethod -- def test_init_too_low(integer_tuple): -- """Test initialization from integer value below minimum""" -- obj_type = integer_tuple[0] -- exp_minvalue = integer_tuple[2] -- try: -- obj_type(exp_minvalue - 1) -- except ValueError: -- pass -- else: -- raise AssertionError("ValueError was not raised.") -- -- @staticmethod -- def test_init_too_high(integer_tuple): -- """Test initialization from integer value above maximum""" -- obj_type = integer_tuple[0] -- exp_maxvalue = integer_tuple[3] -- try: -- obj_type(exp_maxvalue + 1) -- except ValueError: -- pass -- else: -- raise AssertionError("ValueError was not raised.") -+def test_integer_class_attrs_class(integer_tuple): -+ """Test class attrs via class level""" -+ obj_type, exp_cimtype, exp_minvalue, exp_maxvalue = integer_tuple -+ assert obj_type.cimtype == exp_cimtype -+ assert obj_type.minvalue == exp_minvalue -+ assert obj_type.maxvalue == exp_maxvalue -+ -+ -+def test_integer_class_attrs_inst(integer_tuple): -+ """Test class attrs via instance level""" -+ obj_type, exp_cimtype, exp_minvalue, exp_maxvalue = integer_tuple -+ obj = obj_type(42) -+ assert obj.cimtype == exp_cimtype -+ assert obj.minvalue == exp_minvalue -+ assert obj.maxvalue == exp_maxvalue -+ -+ -+def test_integer_inheritance(integer_tuple): -+ """Test inheritance""" -+ obj_type = integer_tuple[0] -+ obj = obj_type(42) -+ assert isinstance(obj, obj_type) -+ assert isinstance(obj, CIMType) -+ assert isinstance(obj, CIMInt) -+ assert not isinstance(obj, CIMFloat) -+ -+ -+def test_integer_init_int(integer_tuple): -+ """Test initialization from integer value""" -+ obj_type = integer_tuple[0] -+ obj = obj_type(42) -+ assert obj == 42 -+ -+ -+def test_integer_init_str(integer_tuple): -+ """Test initialization from string value""" -+ obj_type = integer_tuple[0] -+ obj = obj_type('42') -+ assert obj == 42 -+ -+ -+def test_integer_init_str_base10(integer_tuple): -+ """Test initialization from string value with base 10""" -+ obj_type = integer_tuple[0] -+ obj = obj_type('42', 10) -+ assert obj == 42 -+ -+ -+def test_integer_init_str_base16(integer_tuple): -+ """Test initialization from string value with base 16""" -+ obj_type = integer_tuple[0] -+ obj = obj_type('2A', 16) -+ assert obj == 42 -+ -+ -+def test_integer_init_minimum(integer_tuple): -+ """Test initialization from integer value at minimum""" -+ obj_type = integer_tuple[0] -+ exp_minvalue = integer_tuple[2] -+ obj = obj_type(exp_minvalue) -+ assert obj == exp_minvalue -+ -+ -+def test_integer_init_maximum(integer_tuple): -+ """Test initialization from integer value at maximum""" -+ obj_type = integer_tuple[0] -+ exp_maxvalue = integer_tuple[3] -+ obj = obj_type(exp_maxvalue) -+ assert obj == exp_maxvalue -+ -+ -+def test_integer_init_too_low(integer_tuple): -+ """Test initialization from integer value below minimum""" -+ obj_type = integer_tuple[0] -+ exp_minvalue = integer_tuple[2] -+ try: -+ obj_type(exp_minvalue - 1) -+ except ValueError: -+ pass -+ else: -+ raise AssertionError("ValueError was not raised.") -+ -+ -+def test_integer_init_too_high(integer_tuple): -+ """Test initialization from integer value above maximum""" -+ obj_type = integer_tuple[0] -+ exp_maxvalue = integer_tuple[3] -+ try: -+ obj_type(exp_maxvalue + 1) -+ except ValueError: -+ pass -+ else: -+ raise AssertionError("ValueError was not raised.") - - - # -@@ -164,47 +158,41 @@ def real_tuple(request): - return request.param - - --class TestReals: -- """ -- Test CIM real data type classes. -- """ -- -- @staticmethod -- def test_class_attrs_class(real_tuple): -- """Test class attrs via class level""" -- obj_type, exp_cimtype = real_tuple -- assert obj_type.cimtype == exp_cimtype -- -- @staticmethod -- def test_class_attrs_inst(real_tuple): -- """Test class attrs via instance level""" -- obj_type, exp_cimtype = real_tuple -- obj = obj_type(42) -- assert obj.cimtype == exp_cimtype -- -- @staticmethod -- def test_inheritance(real_tuple): -- """Test inheritance""" -- obj_type = real_tuple[0] -- obj = obj_type(42) -- assert isinstance(obj, obj_type) -- assert isinstance(obj, CIMType) -- assert isinstance(obj, CIMFloat) -- assert not isinstance(obj, CIMInt) -- -- @staticmethod -- def test_init_float(real_tuple): -- """Test initialization from floating point value""" -- obj_type = real_tuple[0] -- obj = obj_type(42.0) -- assert obj == 42.0 -- -- @staticmethod -- def test_init_str(real_tuple): -- """Test initialization from string value""" -- obj_type = real_tuple[0] -- obj = obj_type('42.0') -- assert obj == 42.0 -+def test_real_class_attrs_class(real_tuple): -+ """Test class attrs via class level""" -+ obj_type, exp_cimtype = real_tuple -+ assert obj_type.cimtype == exp_cimtype -+ -+ -+def test_real_class_attrs_inst(real_tuple): -+ """Test class attrs via instance level""" -+ obj_type, exp_cimtype = real_tuple -+ obj = obj_type(42) -+ assert obj.cimtype == exp_cimtype -+ -+ -+def test_real_inheritance(real_tuple): -+ """Test inheritance""" -+ obj_type = real_tuple[0] -+ obj = obj_type(42) -+ assert isinstance(obj, obj_type) -+ assert isinstance(obj, CIMType) -+ assert isinstance(obj, CIMFloat) -+ assert not isinstance(obj, CIMInt) -+ -+ -+def test_real_init_float(real_tuple): -+ """Test initialization from floating point value""" -+ obj_type = real_tuple[0] -+ obj = obj_type(42.0) -+ assert obj == 42.0 -+ -+ -+def test_real_init_str(real_tuple): -+ """Test initialization from string value""" -+ obj_type = real_tuple[0] -+ obj = obj_type('42.0') -+ assert obj == 42.0 - - - # -@@ -271,6 +259,26 @@ def test_init_str(real_tuple): - '20140924193040.654321+120' - ), - ( -+ datetime(year=2014, month=9, day=24, hour=19, minute=30, second=40, -+ microsecond=654321, tzinfo=MinutesFromUTC(0)), -+ 'timestamp', -+ datetime(year=2014, month=9, day=24, hour=19, minute=30, second=40, -+ microsecond=654321, tzinfo=MinutesFromUTC(0)), -+ None, -+ 0, -+ '20140924193040.654321+000' -+ ), -+ ( -+ datetime(year=2014, month=9, day=24, hour=19, minute=30, second=40, -+ microsecond=654321), -+ 'timestamp', -+ datetime(year=2014, month=9, day=24, hour=19, minute=30, second=40, -+ microsecond=654321, tzinfo=MinutesFromUTC(0)), -+ None, -+ 0, -+ '20140924193040.654321+000' -+ ), -+ ( - '20140924193040.654321+120', - 'timestamp', - datetime(year=2014, month=9, day=24, hour=19, minute=30, second=40, -@@ -325,46 +333,47 @@ def datetime_init_tuple(request): - return request.param - - --class TestDatetime: -- """ -- Test CIM real data type classes. -- """ -- -- @staticmethod -- def test_class_attrs_class(): -- """Test class attrs via class level""" -- assert CIMDateTime.cimtype == 'datetime' -- -- @staticmethod -- def test_class_attrs_inst(): -- """Test class attrs via instance level""" -- obj = CIMDateTime('00000000000000.000000:000') -- assert obj.cimtype == 'datetime' -- -- @staticmethod -- def test_inheritance(): -- """Test inheritance""" -- obj = CIMDateTime('00000000000000.000000:000') -- assert isinstance(obj, CIMDateTime) -- assert isinstance(obj, CIMType) -- assert not isinstance(obj, CIMFloat) -- assert not isinstance(obj, CIMInt) -- -- @staticmethod -- def test_init(datetime_init_tuple): -- """Test initialization from all input types""" -- (dtarg, exp_kind, exp_datetime, exp_timedelta, exp_minutesfromutc, -- exp_str) = datetime_init_tuple -- try: -- obj = CIMDateTime(dtarg) -- except Exception as exc: -- assert isinstance(exc, exp_kind) -- else: -- assert obj.is_interval == (exp_kind == 'interval') -- assert obj.datetime == exp_datetime -- assert obj.timedelta == exp_timedelta -- assert obj.minutes_from_utc == exp_minutesfromutc -- assert str(obj) == exp_str -+def test_datetime_class_attrs_class(): -+ """Test class attrs via class level""" -+ assert CIMDateTime.cimtype == 'datetime' -+ -+ -+def test_datetime_class_attrs_inst(): -+ """Test class attrs via instance level""" -+ obj = CIMDateTime('00000000000000.000000:000') -+ assert obj.cimtype == 'datetime' -+ -+ -+def test_datetime_inheritance(): -+ """Test inheritance""" -+ obj = CIMDateTime('00000000000000.000000:000') -+ assert isinstance(obj, CIMDateTime) -+ assert isinstance(obj, CIMType) -+ assert not isinstance(obj, CIMFloat) -+ assert not isinstance(obj, CIMInt) -+ -+ -+def test_datetime_init(datetime_init_tuple): -+ """Test initialization from all input types""" -+ (dtarg, exp_kind, exp_datetime, exp_timedelta, exp_minutesfromutc, -+ exp_str) = datetime_init_tuple -+ try: -+ obj = CIMDateTime(dtarg) -+ except Exception as exc: -+ assert isinstance(exc, exp_kind) -+ else: -+ assert obj.is_interval == (exp_kind == 'interval') -+ assert obj.datetime == exp_datetime -+ if obj.datetime is not None: -+ assert isinstance(obj.datetime, datetime) -+ # We ensure that the datetime is always timezone-aware: -+ assert obj.datetime.tzinfo is not None -+ assert obj.timedelta == exp_timedelta -+ if obj.timedelta is not None: -+ assert isinstance(obj.timedelta, timedelta) -+ assert obj.minutes_from_utc == exp_minutesfromutc -+ assert str(obj) == exp_str -+ - - # TODO: Add testcases for get_local_utcoffset() - # TODO: Add testcases for now() diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index f17e501e9ded..1812dcad7698 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -4842,8 +4842,7 @@ in { ROPGadget = callPackage ../development/python-modules/ROPGadget { }; # We need "normal" libxml2 and not the python package by the same name. - pywbem = disabledIf isPy36 - (callPackage ../development/python-modules/pywbem { libxml2 = pkgs.libxml2; }); + pywbem = callPackage ../development/python-modules/pywbem { libxml2 = pkgs.libxml2; }; unicorn = callPackage ../development/python-modules/unicorn { };