diff --git a/ncclient-0.6.16.tar.gz b/ncclient-0.6.16.tar.gz deleted file mode 100644 index 21546f0..0000000 --- a/ncclient-0.6.16.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:893b3d6dd9dfc76af0344e1e27ecaaad8ebc2b81f0c2d06f66984824108daf35 -size 142880 diff --git a/ncclient-0.6.19.tar.gz b/ncclient-0.6.19.tar.gz new file mode 100644 index 0000000..3970b60 --- /dev/null +++ b/ncclient-0.6.19.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9c016d3e9d213cd02451e4b81f3dd5b318e19088f842d2605d1cb13e0d3b8320 +size 142506 diff --git a/python-ncclient-no-python2.patch b/python-ncclient-no-python2.patch deleted file mode 100644 index d14347a..0000000 --- a/python-ncclient-no-python2.patch +++ /dev/null @@ -1,963 +0,0 @@ -diff --git a/examples/base/nc08.py b/examples/base/nc08.py -index 40eab7f2..df3deec4 100644 ---- a/examples/base/nc08.py -+++ b/examples/base/nc08.py -@@ -5,7 +5,7 @@ - # - # $ ./nc08.py Paulo Seguel - --import sys, os, warnings -+import sys, warnings - warnings.simplefilter("ignore", DeprecationWarning) - import datetime - from ncclient import manager -diff --git a/examples/vendor/cisco/nxosapi.py b/examples/vendor/cisco/nxosapi.py -index c423163b..55cb58b1 100644 ---- a/examples/vendor/cisco/nxosapi.py -+++ b/examples/vendor/cisco/nxosapi.py -@@ -116,13 +116,13 @@ def enable_vlan(mgr, vlanid, vlanname): - def enable_vlan_on_trunk_int(mgr, interface, vlanid): - confstr = cmd_vlan_int_snippet % (interface, vlanid) - confstr = exec_conf_prefix + confstr + exec_conf_postfix -- print confstr -+ print(confstr) - mgr.edit_config(target='running', config=confstr) - - - def disable_vlan_on_trunk_int(mgr, interface, vlanid): - confstr = cmd_no_vlan_int_snippet % (interface, vlanid) -- print confstr -+ print(confstr) - mgr.edit_config(target='running', config=confstr) - - -diff --git a/ncclient/__init__.py b/ncclient/__init__.py -index 50e7991d..17de7dce 100644 ---- a/ncclient/__init__.py -+++ b/ncclient/__init__.py -@@ -16,8 +16,8 @@ - - import sys - --if sys.version_info < (2, 7): -- raise RuntimeError('You need Python 2.7+ for this module.') -+if sys.version_info < (3, 5): -+ raise RuntimeError('You need Python 3.5+ for this module.') - - class NCClientError(Exception): - "Base type for all NCClient errors" -diff --git a/ncclient/capabilities.py b/ncclient/capabilities.py -index 5d6eabeb..14fe6dbd 100644 ---- a/ncclient/capabilities.py -+++ b/ncclient/capabilities.py -@@ -13,7 +13,6 @@ - # limitations under the License. - - import logging --import six - - - logger = logging.getLogger("ncclient.capabilities") -@@ -39,7 +38,7 @@ def schemes(url_uri): - "Given a URI that has a *scheme* query string (i.e. `:url` capability URI), will return a list of supported schemes." - return url_uri.partition("?scheme=")[2].split(",") - --class Capabilities(object): -+class Capabilities: - - "Represents the set of capabilities available to a NETCONF client or server. It is initialized with a list of capability URI's." - -@@ -60,7 +59,7 @@ def __getitem__(self, key): - try: - return self._dict[key] - except KeyError: -- for capability in six.itervalues(self._dict): -+ for capability in self._dict.values(): - if key in capability.get_abbreviations(): - return capability - -@@ -69,12 +68,11 @@ def __getitem__(self, key): - def __len__(self): - return len(self._dict) - -- # python 2 and 3 compatible - def __iter__(self): -- return six.iterkeys(self._dict) -+ return self._dict.keys() - - def __repr__(self): -- return repr(six.iterkeys(self._dict)) -+ return repr(self._dict.keys()) - - def add(self, uri): - "Add a capability." -@@ -86,7 +84,7 @@ def remove(self, uri): - del self._dict[uri] - - --class Capability(object): -+class Capability: - - """Represents a single capability""" - -@@ -135,7 +133,7 @@ def _parse_parameter_string(string, uri): - ) - - --class _Parameter(object): -+class _Parameter: - - """Represents a parameter to a capability""" - -diff --git a/ncclient/devices/default.py b/ncclient/devices/default.py -index 675859cb..acd68079 100644 ---- a/ncclient/devices/default.py -+++ b/ncclient/devices/default.py -@@ -25,12 +25,8 @@ - - from ncclient.transport.parser import DefaultXMLParser - --import sys --if sys.version >= '3': -- xrange = range - -- --class DefaultDeviceHandler(object): -+class DefaultDeviceHandler: - """ - Default handler for device specific information. - -@@ -68,7 +64,7 @@ def __init__(self, device_params=None): - self._exempt_errors_startwith_wildcard_match = [] - self._exempt_errors_endwith_wildcard_match = [] - self._exempt_errors_full_wildcard_match = [] -- for i in xrange(len(self._EXEMPT_ERRORS)): -+ for i in range(len(self._EXEMPT_ERRORS)): - e = self._EXEMPT_ERRORS[i].lower() - if e.startswith("*"): - if e.endswith("*"): -diff --git a/ncclient/devices/junos.py b/ncclient/devices/junos.py -index d7515608..5d293e4d 100644 ---- a/ncclient/devices/junos.py -+++ b/ncclient/devices/junos.py -@@ -122,11 +122,7 @@ def transform_reply(self): - - - ''' -- import sys -- if sys.version < '3': -- return reply -- else: -- return reply.encode('UTF-8') -+ return reply.encode('UTF-8') - - def get_xml_parser(self, session): - # use_filter in device_params can be used to enabled using SAX parsing -diff --git a/ncclient/manager.py b/ncclient/manager.py -index 12fe7c0c..a0cc9758 100644 ---- a/ncclient/manager.py -+++ b/ncclient/manager.py -@@ -212,7 +212,7 @@ def call_home(*args, **kwds): - kwds['sock'] = sock - return connect_ssh(*args, **kwds) - --class Manager(object): -+class Manager: - - """ - For details on the expected behavior of the operations and their -diff --git a/ncclient/operations/lock.py b/ncclient/operations/lock.py -index 06738847..87c1473f 100644 ---- a/ncclient/operations/lock.py -+++ b/ncclient/operations/lock.py -@@ -49,7 +49,7 @@ def request(self, target="candidate"): - return self._request(node) - - --class LockContext(object): -+class LockContext: - - """A context manager for the :class:`Lock` / :class:`Unlock` pair of RPC's. - -diff --git a/ncclient/operations/rpc.py b/ncclient/operations/rpc.py -index 2511b6f3..fa6af9cc 100644 ---- a/ncclient/operations/rpc.py -+++ b/ncclient/operations/rpc.py -@@ -44,7 +44,7 @@ def __init__(self, raw, errs=None): - if errs is None: - # Single RPCError - self._errlist = None -- for attr in six.itervalues(RPCError.tag_to_attr): -+ for attr in RPCError.tag_to_attr.values(): - setattr(self, attr, None) - for subele in raw: - attr = RPCError.tag_to_attr.get(subele.tag, None) -@@ -79,7 +79,7 @@ def __init__(self, raw, errs=None): - OperationError.__init__(self, self.message) - - def to_dict(self): -- return dict([ (attr[1:], getattr(self, attr)) for attr in six.itervalues(RPCError.tag_to_attr) ]) -+ return dict([ (attr[1:], getattr(self, attr)) for attr in RPCError.tag_to_attr.values() ]) - - @property - def xml(self): -@@ -128,7 +128,7 @@ def errlist(self): - return self._errlist - - --class RPCReply(object): -+class RPCReply: - - """Represents an *rpc-reply*. Only concerns itself with whether the operation was successful. - -@@ -173,8 +173,7 @@ def parse(self): - except Exception as e: - if self._parsing_error_transform is None: - # re-raise as we have no workaround -- exc_type, exc_value, exc_traceback = sys.exc_info() -- six.reraise(exc_type, exc_value, exc_traceback) -+ raise e - - # Apply device specific workaround and try again - self._parsing_error_transform(root) -@@ -263,13 +262,13 @@ def callback(self, root, raw): - - def errback(self, err): - try: -- for rpc in six.itervalues(self._id2rpc): -+ for rpc in self._id2rpc.values(): - rpc.deliver_error(err) - finally: - self._id2rpc.clear() - - --class RaiseMode(object): -+class RaiseMode: - """ - Define how errors indicated by RPC should be handled. - -@@ -288,7 +287,7 @@ class RaiseMode(object): - "Don't look at the `error-type`, always raise." - - --class RPC(object): -+class RPC: - - """Base class for all operations, directly corresponding to *rpc* requests. Handles making the request, and taking delivery of the reply.""" - -diff --git a/ncclient/transport/notify.py b/ncclient/transport/notify.py -index 85490312..1d240639 100644 ---- a/ncclient/transport/notify.py -+++ b/ncclient/transport/notify.py -@@ -14,7 +14,7 @@ - - from ncclient.xml_ import to_ele - --class Notification(object): -+class Notification: - def __init__(self, raw): - self._raw = raw - self._root_ele = to_ele(raw) -diff --git a/ncclient/transport/parser.py b/ncclient/transport/parser.py -index cb5b071c..4b68ddc5 100644 ---- a/ncclient/transport/parser.py -+++ b/ncclient/transport/parser.py -@@ -22,6 +22,7 @@ - except ImportError: - import selectors2 as selectors - -+from io import BytesIO as StringIO - from xml.sax.handler import ContentHandler - - from ncclient.transport.errors import NetconfFramingError -@@ -33,11 +34,6 @@ - import logging - logger = logging.getLogger("ncclient.transport.parser") - --if sys.version < '3': -- from six import StringIO --else: -- from io import BytesIO as StringIO -- - - PORT_NETCONF_DEFAULT = 830 - PORT_SSH_DEFAULT = 22 -@@ -61,12 +57,8 @@ - # - RE_NC11_DELIM = re.compile(r'\n(?:#([0-9]+)|(##))\n') - --if sys.version < '3': -- def textify(buf): -- return buf --else: -- def textify(buf): -- return buf.decode('UTF-8') -+def textify(buf): -+ return buf.decode('UTF-8') - - - class SAXParserHandler(SessionListener): -@@ -90,7 +82,7 @@ def __str__(self): - return "SAX filter input xml not provided for listener: %s" % self._listener - - --class DefaultXMLParser(object): -+class DefaultXMLParser: - - def __init__(self, session): - """ -@@ -131,10 +123,7 @@ def _parse10(self): - buf.seek(0) - msg, _, remaining = buf.read().decode('UTF-8').partition(MSG_DELIM) - msg = msg.strip() -- if sys.version < '3': -- self._session._dispatch_message(msg.encode()) -- else: -- self._session._dispatch_message(msg) -+ self._session._dispatch_message(msg) - self._session._buffer = StringIO() - self._parsing_pos10 = 0 - if len(remaining.strip()) > 0: -diff --git a/ncclient/transport/session.py b/ncclient/transport/session.py -index 5e933756..6ebe96e8 100644 ---- a/ncclient/transport/session.py -+++ b/ncclient/transport/session.py -@@ -16,10 +16,8 @@ - - import logging - from threading import Thread, Lock, Event --try: -- from Queue import Queue, Empty --except ImportError: -- from queue import Queue, Empty -+from queue import Queue, Empty -+ - try: - import selectors - except ImportError: -@@ -42,7 +40,7 @@ - TICK = 0.1 - - --class NetconfBase(object): -+class NetconfBase: - '''Netconf Base protocol version''' - BASE_10 = 1 - BASE_11 = 2 -@@ -292,7 +290,7 @@ def id(self): - return self._id - - --class SessionListener(object): -+class SessionListener: - - """Base class for :class:`Session` listeners, which are notified when a new - NETCONF message is received or an error occurs. -@@ -349,11 +347,7 @@ def build(capabilities, device_handler): - hello = new_ele("hello", **xml_namespace_kwargs) - caps = sub_ele(hello, "capabilities") - def fun(uri): sub_ele(caps, "capability").text = uri -- #python3 changes -- if sys.version < '3': -- map(fun, capabilities) -- else: -- list(map(fun, capabilities)) -+ list(map(fun, capabilities)) - return to_xml(hello) - - @staticmethod -diff --git a/ncclient/transport/ssh.py b/ncclient/transport/ssh.py -index d1796807..79e9ba66 100644 ---- a/ncclient/transport/ssh.py -+++ b/ncclient/transport/ssh.py -@@ -17,11 +17,11 @@ - import getpass - import os - import re --import six - import sys - import socket - import threading - from binascii import hexlify -+from io import BytesIO as StringIO - - try: - import selectors -@@ -77,12 +77,6 @@ def _colonify(fp): - return finga - - --if sys.version < '3': -- from six import StringIO --else: -- from io import BytesIO as StringIO -- -- - class SSHSession(Session): - - "Implements a :rfc:`4742` NETCONF session over SSH." -@@ -263,7 +257,7 @@ def connect( - proxycommand = config.get("proxycommand") - if proxycommand: - self.logger.debug("Configuring Proxy. %s", proxycommand) -- if not isinstance(proxycommand, six.string_types): -+ if not isinstance(proxycommand, str): - proxycommand = [os.path.expanduser(elem) for elem in proxycommand] - else: - proxycommand = os.path.expanduser(proxycommand) -@@ -287,11 +281,7 @@ def connect( - else: - raise SSHError("Could not open socket to %s:%s" % (host, port)) - elif sock is None: -- if sys.version_info[0] < 3: -- s = socket.fromfd(int(sock_fd), socket.AF_INET, socket.SOCK_STREAM) -- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, _sock=s) -- else: -- sock = socket.fromfd(int(sock_fd), socket.AF_INET, socket.SOCK_STREAM) -+ sock = socket.fromfd(int(sock_fd), socket.AF_INET, socket.SOCK_STREAM) - sock.settimeout(timeout) - - self._transport = paramiko.Transport(sock) -diff --git a/ncclient/transport/third_party/junos/ioproc.py b/ncclient/transport/third_party/junos/ioproc.py -index e1e63afd..60f83ff4 100644 ---- a/ncclient/transport/third_party/junos/ioproc.py -+++ b/ncclient/transport/third_party/junos/ioproc.py -@@ -1,20 +1,12 @@ - import sys - import re --import six -- --if sys.version < '3': -- from cStringIO import StringIO --else: -- from io import BytesIO as StringIO --if sys.version>='2.7': -- from subprocess import Popen, check_output, PIPE, STDOUT --else: -- from subprocess import Popen, PIPE, STDOUT -+from io import BytesIO as StringIO -+from subprocess import Popen, check_output, PIPE, STDOUT - - from ncclient.transport.errors import SessionCloseError, TransportError, PermissionError - from ncclient.transport.ssh import SSHSession - --MSG_DELIM = six.b("]]>]]>") -+MSG_DELIM = b"]]>]]>" - NETCONF_SHELL = 'netconf' - - -diff --git a/ncclient/transport/tls.py b/ncclient/transport/tls.py -index b7443f9c..27298098 100644 ---- a/ncclient/transport/tls.py -+++ b/ncclient/transport/tls.py -@@ -17,14 +17,10 @@ - import sys - import threading - -+from io import BytesIO as StringIO - from socket import AF_INET, SOCK_STREAM - from ssl import CERT_REQUIRED, SSLContext, SSLError - --if sys.version < '3': -- from six import StringIO --else: -- from io import BytesIO as StringIO -- - from ncclient.capabilities import Capabilities - from ncclient.logging_ import SessionLoggerAdapter - from ncclient.transport.errors import TLSError -diff --git a/ncclient/xml_.py b/ncclient/xml_.py -index 8f58b35a..f46ec025 100644 ---- a/ncclient/xml_.py -+++ b/ncclient/xml_.py -@@ -17,11 +17,9 @@ - - - import io --import sys --import six - import types --from six import StringIO --from io import BytesIO -+from io import BytesIO, StringIO -+ - from lxml import etree - - # In case issues come up with XML generation/parsing -@@ -91,7 +89,7 @@ def register_namespace(prefix, uri): - # cElementTree uses ElementTree's _namespace_map, so that's ok - ElementTree._namespace_map[uri] = prefix - --for (ns, pre) in six.iteritems({ -+for (ns, pre) in { - BASE_NS_1_0: 'nc', - NETCONF_MONITORING_NS: 'ncm', - NXOS_1_0: 'nxos', -@@ -101,7 +99,7 @@ def register_namespace(prefix, uri): - CISCO_CPI_1_0: 'cpi', - FLOWMON_1_0: 'fm', - JUNIPER_1_1: 'junos', --}): -+}.items(): - register_namespace(pre, ns) - - qualify = lambda tag, ns=BASE_NS_1_0: tag if ns is None else "{%s}%s" % (ns, tag) -@@ -111,11 +109,8 @@ def register_namespace(prefix, uri): - def to_xml(ele, encoding="UTF-8", pretty_print=False): - "Convert and return the XML for an *ele* (:class:`~xml.etree.ElementTree.Element`) with specified *encoding*." - xml = etree.tostring(ele, encoding=encoding, pretty_print=pretty_print) -- if sys.version < '3': -- return xml if xml.startswith('%s' % (encoding, xml) -- else: -- return xml.decode('UTF-8') if xml.startswith(b'%s' % (encoding, xml.decode('UTF-8')) -+ return xml.decode('UTF-8') if xml.startswith(b'%s' % (encoding, xml.decode('UTF-8')) - - - def to_ele(x, huge_tree=False): -@@ -123,18 +118,12 @@ def to_ele(x, huge_tree=False): - - *huge_tree*: parse XML with very deep trees and very long text content - """ -- if sys.version < '3': -- return x if etree.iselement(x) else etree.fromstring(x, parser=_get_parser(huge_tree)) -- else: -- return x if etree.iselement(x) else etree.fromstring(x.encode('UTF-8'), parser=_get_parser(huge_tree)) -+ return x if etree.iselement(x) else etree.fromstring(x.encode('UTF-8'), parser=_get_parser(huge_tree)) - - - def parse_root(raw): - "Efficiently parses the root element of a *raw* XML document, returning a tuple of its qualified name and attribute dictionary." -- if sys.version < '3': -- fp = StringIO(raw) -- else: -- fp = BytesIO(raw.encode('UTF-8')) -+ fp = BytesIO(raw.encode('UTF-8')) - for event, element in etree.iterparse(fp, events=('start',)): - return (element.tag, element.attrib) - -@@ -168,7 +157,7 @@ def validated_element(x, tags=None, attrs=None): - } - - --class NCElement(object): -+class NCElement: - def __init__(self, result, transform_reply, huge_tree=False): - self.__result = result - self.__transform_reply = transform_reply -@@ -213,10 +202,7 @@ def findall(self, expression): - - def __str__(self): - """syntactic sugar for str() - alias to tostring""" -- if sys.version < '3': -- return self.tostring -- else: -- return self.tostring.decode('UTF-8') -+ return self.tostring.decode('UTF-8') - - @property - def tostring(self): -diff --git a/requirements.txt b/requirements.txt -index 64cf505d..3363b16e 100644 ---- a/requirements.txt -+++ b/requirements.txt -@@ -1,5 +1,3 @@ - setuptools>0.6 - paramiko>=1.15.0 - lxml>=3.3.0 --selectors2>=2.0.1; python_version <= '3.4' --six -diff --git a/setup.py b/setup.py -index 68e00412..32ad3b91 100644 ---- a/setup.py -+++ b/setup.py -@@ -18,7 +18,6 @@ - from distutils.command.install import install as _install - - import sys --import platform - import codecs - import versioneer - -@@ -26,8 +25,8 @@ - __author_email__ = "shikhar@schmizz.net, lpoulopoulos@verisign.com, exa@dscp.org, einarnn@gmail.com" - __licence__ = "Apache 2.0" - --if sys.version_info.major == 2 and sys.version_info.minor < 7: -- print ("Sorry, Python < 2.7 is not supported") -+if sys.version_info.major == 2 or sys.version_info.minor < 5: -+ print ("Sorry, Python < 3.5 is not supported") - exit() - - #parse requirements -@@ -55,10 +54,9 @@ - license=__licence__, - platforms=["Posix; OS X; Windows"], - keywords=['NETCONF', 'NETCONF Python client', 'Juniper Optimization', 'Cisco NXOS Optimization'], -- python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*', -+ python_requires='>=3.5', - classifiers=[ - 'Development Status :: 5 - Production/Stable', -- 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', -diff --git a/test/unit/devices/test_junos.py b/test/unit/devices/test_junos.py -index 97ac9ccf..50bc6d42 100644 ---- a/test/unit/devices/test_junos.py -+++ b/test/unit/devices/test_junos.py -@@ -1,12 +1,10 @@ - import unittest -+from unittest.mock import patch -+ -+import paramiko -+ - from ncclient.devices.junos import * - import ncclient.transport --try: -- from unittest.mock import patch # Python 3.4 and later --except ImportError: -- from mock import patch --import paramiko --import sys - - xml = ''' - -@@ -93,10 +91,7 @@ def test_additional_operations(self): - self.assertEqual(dict, self.obj.add_additional_operations()) - - def test_transform_reply(self): -- if sys.version >= '3': -- reply = xml.encode('utf-8') -- else: -- reply = xml -+ reply = xml.encode('utf-8') - self.assertEqual(self.obj.transform_reply(), reply) - - def test_perform_quality_check(self): -diff --git a/test/unit/operations/test_retrieve.py b/test/unit/operations/test_retrieve.py -index 21fa3092..d1b51104 100644 ---- a/test/unit/operations/test_retrieve.py -+++ b/test/unit/operations/test_retrieve.py -@@ -1,9 +1,11 @@ --from ncclient.operations.retrieve import * -+import copy - import unittest --try: -- from unittest.mock import patch # Python 3.4 and later --except ImportError: -- from mock import patch -+from unittest.mock import patch -+ -+from xml.etree import ElementTree -+from lxml import etree -+ -+from ncclient.operations.retrieve import * - from ncclient import manager - import ncclient.manager - import ncclient.transport -@@ -11,10 +13,6 @@ - from ncclient.xml_ import * - from ncclient.operations import RaiseMode - from ncclient.operations.errors import MissingCapabilityError --from xml.etree import ElementTree --from lxml import etree --import copy --import six - - - class TestRetrieve(unittest.TestCase): -@@ -96,8 +94,7 @@ def test_get_with_defaults_not_supported(self, mock_request): - "Invalid 'with-defaults' mode 'report-all-tagged'; the server " - "only supports the following: explicit, report-all, trim" - ) -- six.assertRaisesRegex( -- self, -+ self.assertRaisesRegex( - WithDefaultsError, - expected_error, - obj.request, -diff --git a/test/unit/operations/test_rpc.py b/test/unit/operations/test_rpc.py -index 8d60700d..47767b0e 100644 ---- a/test/unit/operations/test_rpc.py -+++ b/test/unit/operations/test_rpc.py -@@ -1,9 +1,7 @@ --from ncclient.operations.rpc import * - import unittest --try: -- from unittest.mock import patch # Python 3.4 and later --except ImportError: -- from mock import patch -+from unittest.mock import patch -+ -+from ncclient.operations.rpc import * - from ncclient import manager - import ncclient.manager - import ncclient.transport -@@ -11,12 +9,8 @@ - from ncclient.operations import RaiseMode - from ncclient.capabilities import Capabilities - from xml.sax.saxutils import escape --import sys - --if sys.version >= '3': -- patch_str = 'ncclient.operations.rpc.Event.is_set' --else: -- patch_str = 'threading._Event.is_set' -+patch_str = 'ncclient.operations.rpc.Event.is_set' - - xml1 = """ - -diff --git a/test/unit/test_xml_.py b/test/unit/test_xml_.py -index 9e8c55a6..28d10113 100644 ---- a/test/unit/test_xml_.py -+++ b/test/unit/test_xml_.py -@@ -1,8 +1,9 @@ --from ncclient import manager --from ncclient.xml_ import * - import unittest - import os - import sys -+ -+from ncclient import manager -+from ncclient.xml_ import * - file_path = os.path.join(os.getcwd(), "test", "unit", "reply1") - - -@@ -18,8 +19,7 @@ def test_ncelement_reply_001(self): - transform_reply = device_handler.transform_reply() - result = NCElement(reply, transform_reply) - result_str = result.tostring -- if sys.version >= '3': -- result_str = result_str.decode('UTF-8') -+ result_str = result_str.decode('UTF-8') - self.assertEqual(str(result), result_str) - #data_xml != tostring - self.assertNotEqual(result_str, result.data_xml) -diff --git a/test/unit/transport/test_parser.py b/test/unit/transport/test_parser.py -index d06d2cb9..abe4a3d9 100644 ---- a/test/unit/transport/test_parser.py -+++ b/test/unit/transport/test_parser.py -@@ -1,10 +1,7 @@ - import os -- - import unittest --try: -- from unittest.mock import patch # Python 3.4 and later --except ImportError: -- from mock import patch -+from unittest.mock import patch -+ - import paramiko - - from ncclient import manager -@@ -21,7 +18,6 @@ - - class TestSession(unittest.TestCase): - -- @unittest.skipIf(sys.version_info.major == 2, "test not supported < Python3") - @patch('ncclient.transport.SSHSession.connected') - @patch('paramiko.channel.Channel.send_ready') - @patch('paramiko.channel.Channel.send') -@@ -50,7 +46,6 @@ def test_filter_xml_sax_on(self, mock_uuid4, mock_select, mock_session, mock_rec - # as filter_xml is not having software-information, response wont contain it - self.assertEqual(len(resp.xpath('multi-routing-engine-item/software-information')), 0) - -- @unittest.skipIf(sys.version_info.major == 2, "test not supported < Python3") - @patch('ncclient.transport.SSHSession.connected') - @patch('paramiko.channel.Channel.send_ready') - @patch('paramiko.channel.Channel.send') -@@ -81,7 +76,6 @@ def test_filter_xml_sax_on_junos_rfc_compliant(self, mock_uuid4, mock_select, mo - # as filter_xml is not having software-information, response wont contain it - self.assertEqual(len(resp.xpath('multi-routing-engine-item/software-information')), 0) - -- @unittest.skipIf(sys.version_info.major == 2, "test not supported < Python3") - @patch('ncclient.transport.SSHSession.connected') - @patch('paramiko.channel.Channel.send_ready') - @patch('paramiko.channel.Channel.send') -@@ -111,7 +105,6 @@ def test_filter_xml_delimiter_rpc_reply(self, mock_uuid4, mock_select, - self.assertEqual(len(resp.xpath('multi-routing-engine-item/re-name')), 2) - self.assertEqual(len(resp.xpath('multi-routing-engine-item/software-information')), 0) - -- @unittest.skipIf(sys.version_info.major == 2, "test not supported < Python3") - @patch('ncclient.transport.SSHSession.connected') - @patch('paramiko.channel.Channel.send_ready') - @patch('paramiko.channel.Channel.send') -@@ -143,7 +136,6 @@ def test_filter_xml_delimiter_multiple_rpc_reply(self, mock_uuid4, mock_select, - self.assertEqual(len(resp.xpath('multi-routing-engine-item/re-name')), 2) - self.assertEqual(len(resp.xpath('multi-routing-engine-item/software-information')), 0) - -- @unittest.skipIf(sys.version_info.major == 2, "test not supported < Python3") - @patch('ncclient.transport.SSHSession.connected') - @patch('paramiko.channel.Channel.send_ready') - @patch('paramiko.channel.Channel.send') -@@ -229,7 +221,6 @@ def test_filter_xml_delimiter_multiple_rpc_in_parallel(self, mock_uuid4, mock_se - resp = obj.request(rpc)._NCElement__doc[0] - self.assertEqual(len(resp.xpath('pfe-traffic-statistics')), 1) - -- @unittest.skipIf(sys.version_info.major == 2, "test not supported < Python3") - @patch('ncclient.transport.SSHSession.connected') - @patch('paramiko.channel.Channel.send_ready') - @patch('paramiko.channel.Channel.send') -@@ -261,7 +252,6 @@ def test_filter_xml_delimiter_splited_rpc_reply(self, mock_uuid4, mock_select, - self.assertEqual(len(resp.xpath('multi-routing-engine-item/re-name')), 2) - self.assertEqual(len(resp.xpath('multi-routing-engine-item/software-information')), 0) - -- @unittest.skipIf(sys.version_info.major == 2, "test not supported < Python3") - @patch('ncclient.transport.SSHSession.connected') - @patch('paramiko.channel.Channel.send_ready') - @patch('paramiko.channel.Channel.send') -@@ -292,7 +282,6 @@ def test_use_filter_xml_without_sax_input(self, mock_uuid4, mock_select, - self.assertEqual(len(resp.xpath('multi-routing-engine-item/re-name')), 2) - self.assertEqual(len(resp.xpath('multi-routing-engine-item/software-information')), 2) - -- @unittest.skipIf(sys.version_info.major == 2, "test not supported < Python3") - @patch('ncclient.transport.SSHSession.connected') - @patch('paramiko.channel.Channel.send_ready') - @patch('paramiko.channel.Channel.send') -diff --git a/test/unit/transport/test_ssh.py b/test/unit/transport/test_ssh.py -index 73a82be5..4d66130f 100644 ---- a/test/unit/transport/test_ssh.py -+++ b/test/unit/transport/test_ssh.py -@@ -1,14 +1,11 @@ - # -*- coding: utf-8 -*- - import unittest --try: -- from unittest.mock import MagicMock, patch, call # Python 3.4 and later --except ImportError: -- from mock import MagicMock, patch, call -+from unittest.mock import MagicMock, patch, call -+ - from ncclient.transport.ssh import SSHSession - from ncclient.transport import AuthenticationError, SessionCloseError, NetconfBase - import paramiko - from ncclient.devices.junos import JunosDeviceHandler --import sys - - try: - import selectors -@@ -79,12 +76,8 @@ def _test_parsemethod(self, mock_dispatch, parsemethod, reply, ok_chunk, - expected_messages): - device_handler = JunosDeviceHandler({'name': 'junos'}) - obj = SSHSession(device_handler) -- if sys.version >= "3.0": -- obj._buffer.write(bytes(reply, "utf-8")) -- remainder = bytes(ok_chunk, "utf-8") -- else: -- obj._buffer.write(reply) -- remainder = ok_chunk -+ obj._buffer.write(bytes(reply, "utf-8")) -+ remainder = bytes(ok_chunk, "utf-8") - parsemethod(obj) - - for i in range(0, len(expected_messages)): -@@ -102,12 +95,8 @@ def test_parse(self, mock_dispatch): - def test_parse11(self, mock_dispatch): - device_handler = JunosDeviceHandler({'name': 'junos'}) - obj = SSHSession(device_handler) -- if sys.version >= "3.0": -- obj._buffer.write(bytes(rpc_reply11, "utf-8")) -- remainder = bytes(reply_ok_partial_chunk, "utf-8") -- else: -- obj._buffer.write(rpc_reply11) -- remainder = reply_ok_partial_chunk -+ obj._buffer.write(bytes(rpc_reply11, "utf-8")) -+ remainder = bytes(reply_ok_partial_chunk, "utf-8") - obj.parser._parse11() - - expected_messages = [reply_data, reply_ok] -@@ -121,22 +110,14 @@ def test_parse11(self, mock_dispatch): - def test_parse_incomplete_delimiter(self, mock_dispatch): - device_handler = JunosDeviceHandler({'name': 'junos'}) - obj = SSHSession(device_handler) -- if sys.version >= "3.0": -- b = bytes(rpc_reply_part_1, "utf-8") -- obj._buffer.write(b) -- obj._parse() -- self.assertFalse(mock_dispatch.called) -- b = bytes(rpc_reply_part_2, "utf-8") -- obj._buffer.write(b) -- obj._parse() -- self.assertTrue(mock_dispatch.called) -- else: -- obj._buffer.write(rpc_reply_part_1) -- obj._parse() -- self.assertFalse(mock_dispatch.called) -- obj._buffer.write(rpc_reply_part_2) -- obj._parse() -- self.assertTrue(mock_dispatch.called) -+ b = bytes(rpc_reply_part_1, "utf-8") -+ obj._buffer.write(b) -+ obj._parse() -+ self.assertFalse(mock_dispatch.called) -+ b = bytes(rpc_reply_part_2, "utf-8") -+ obj._buffer.write(b) -+ obj._parse() -+ self.assertTrue(mock_dispatch.called) - - @patch('paramiko.transport.Transport.auth_publickey') - @patch('paramiko.agent.AgentSSH.get_keys') -@@ -321,7 +302,6 @@ def test_ssh_known_hosts_2(self, mock_auth, mock_pc, - hk_inst.load.assert_called_once_with('file_name') - mock_os.mock_calls == [call('~/.ssh/config'), call('known_hosts_file')] - -- @unittest.skipIf(sys.version_info.major == 2, "test not supported < Python3") - @patch('ncclient.transport.ssh.SSHSession.close') - @patch('paramiko.channel.Channel.recv') - @patch('selectors.DefaultSelector.select') -@@ -338,12 +318,10 @@ def test_run_receive_py3(self, mock_error, mock_selector, mock_recv, mock_close) - mock_error.call_args_list[0][0][0], - SessionCloseError)) - -- @unittest.skipIf(sys.version_info.major == 2, "test not supported < Python3") - def test_run_send_py3_10(self): - self._test_run_send_py3(NetconfBase.BASE_10, - lambda msg: msg.encode() + b"]]>]]>") - -- @unittest.skipIf(sys.version_info.major == 2, "test not supported < Python3") - def test_run_send_py3_11(self): - def chunker(msg): - encmsg = msg.encode() -@@ -374,23 +352,6 @@ def _test_run_send_py3(self, base, chunker, mock_error, mock_selector, - mock_error.call_args_list[0][0][0], - SessionCloseError)) - -- @unittest.skipIf(sys.version_info.major >= 3, "test not supported >= Python3") -- @patch('ncclient.transport.ssh.SSHSession.close') -- @patch('paramiko.channel.Channel.recv') -- @patch('selectors2.DefaultSelector') -- @patch('ncclient.transport.ssh.Session._dispatch_error') -- def test_run_receive_py2(self, mock_error, mock_selector, mock_recv, mock_close): -- mock_selector.select.return_value = True -- mock_recv.return_value = 0 -- device_handler = JunosDeviceHandler({'name': 'junos'}) -- obj = SSHSession(device_handler) -- obj._channel = paramiko.Channel("c100") -- obj.run() -- self.assertTrue( -- isinstance( -- mock_error.call_args_list[0][0][0], -- SessionCloseError)) -- - @unittest.skip("test currently non-functional") - @patch('ncclient.transport.ssh.SSHSession.close') - @patch('paramiko.channel.Channel.send_ready') -diff --git a/test/unit/transport/test_tls.py b/test/unit/transport/test_tls.py -index e1530171..d6bdb4ca 100644 ---- a/test/unit/transport/test_tls.py -+++ b/test/unit/transport/test_tls.py -@@ -16,11 +16,7 @@ - import sys - import unittest - import socket -- --try: -- from unittest.mock import MagicMock, patch, call --except ImportError: -- from mock import MagicMock, patch, call -+from unittest.mock import MagicMock, patch, call - - try: - from ssl import PROTOCOL_TLS_CLIENT - diff --git a/python-ncclient.changes b/python-ncclient.changes index 3a1b79e..2588e5a 100644 --- a/python-ncclient.changes +++ b/python-ncclient.changes @@ -1,3 +1,28 @@ +------------------------------------------------------------------- +Sun Mar 2 22:26:20 UTC 2025 - Martin Hauke + +- Update to version 0.6.19 + * fixed broken manifest. + +------------------------------------------------------------------- +Sat Mar 1 16:26:35 UTC 2025 - Martin Hauke + +- Update to version 0.6.18 + * Fix connect using ssh using keyfile without password. +- Update to version 0.6.17 + * Remove hardcoded values in example. + * Use Paramiko's PKey class for loading public keys instead of + instantiating key subclasses directly. + * Remove Python2 support. + * Only import UnixSocketSession if the platform is not Windows. + * Remove setuptools from runtime requirements; list in build + requirements. + * Adding error handling parameters for RPC replies. + * Drop the pytest-runner dependency. + * Fix for broken iterator. +- Drop patch + * python-ncclient-no-python2.patch (included upstream) + ------------------------------------------------------------------- Tue Jan 14 14:54:22 UTC 2025 - pgajdos@suse.com diff --git a/python-ncclient.spec b/python-ncclient.spec index baa0912..5c6cc74 100644 --- a/python-ncclient.spec +++ b/python-ncclient.spec @@ -17,7 +17,7 @@ Name: python-ncclient -Version: 0.6.16 +Version: 0.6.19 Release: 0 Summary: Python library for NETCONF clients License: Apache-2.0 @@ -29,14 +29,11 @@ Patch0: allow_old_sphinx.patch # PATCH-FIX-UPSTREAM intersphinx-mapping.patch gh#ncclient/ncclient#604 mcepl@suse.com # use conditionally new form of intersphinx_mapping Patch1: intersphinx-mapping.patch -# https://github.com/ncclient/ncclient/commit/59ccaac8e01e63f776fb4bf3b68a02e33d24bb20 -Patch2: python-ncclient-no-python2.patch BuildRequires: %{python_module setuptools} BuildRequires: fdupes BuildRequires: python-rpm-macros Requires: python-lxml >= 3.3.0 Requires: python-paramiko >= 1.15.0 -Requires: python-setuptools > 0.6 BuildArch: noarch BuildRequires: %{python_module lxml >= 3.3.0} BuildRequires: %{python_module paramiko >= 1.15.0} @@ -64,7 +61,6 @@ This package contains documentation files for %{name}. %patch -p 1 -P 0 %endif %patch -p 1 -P 1 -%patch -p 1 -P 2 find examples/ -name "*.py" -exec sed -i 's|#!/usr/bin/env python$|#!/usr/bin/python|g' {} \; # drop shebang