Hello community,

here is the log from the commit of package python-ncclient for openSUSE:Factory 
checked in at 2020-08-10 15:05:21
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-ncclient (Old)
 and      /work/SRC/openSUSE:Factory/.python-ncclient.new.3399 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-ncclient"

Mon Aug 10 15:05:21 2020 rev:12 rq:825318 version:0.6.9

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-ncclient/python-ncclient.changes  
2020-02-19 12:41:31.311737996 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-ncclient.new.3399/python-ncclient.changes    
    2020-08-10 15:06:00.600254285 +0200
@@ -1,0 +2,12 @@
+Sun Aug  9 14:03:46 UTC 2020 - Martin Hauke <mar...@gmx.de>
+
+- Update to version 0.6.9
+  * Fix for breaking API change
+- Update to version 0.6.8
+  * Support for namespace prefixes for XPath queries
+  * edit-config parameter validation
+  * Support for multiple RPC errors
+  * API to get supported device types
+  * Support for subtree filters with multiple top-level tags
+
+-------------------------------------------------------------------

Old:
----
  ncclient-0.6.7.tar.gz

New:
----
  ncclient-0.6.9.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-ncclient.spec ++++++
--- /var/tmp/diff_new_pack.Z0w8Bd/_old  2020-08-10 15:06:01.608254818 +0200
+++ /var/tmp/diff_new_pack.Z0w8Bd/_new  2020-08-10 15:06:01.608254818 +0200
@@ -18,7 +18,7 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-ncclient
-Version:        0.6.7
+Version:        0.6.9
 Release:        0
 Summary:        Python library for NETCONF clients
 License:        Apache-2.0
@@ -83,6 +83,6 @@
 %{python_sitelib}/*
 
 %files -n python-ncclient-doc
-%doc README README.rst examples docs/build/html
+%doc README.md README.rst examples docs/build/html
 
 %changelog

++++++ ncclient-0.6.7.tar.gz -> ncclient-0.6.9.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/Changelog new/ncclient-0.6.9/Changelog
--- old/ncclient-0.6.7/Changelog        2019-12-21 20:16:07.000000000 +0100
+++ new/ncclient-0.6.9/Changelog        2020-08-09 00:09:16.000000000 +0200
@@ -1,3 +1,74 @@
+version 0.6.9
+-------------
+
+* Resiolved breaking API change
+
+version 0.6.8
+-------------
+
+* Variety of small updates and bugfixes, but of note:
+  - Support for namespace prefixes for XPath queries
+  - `edit-config` parameter validation
+  - Support for multiple RPC errors
+  - API to get supported device types
+  - Support for subtree filters with multiple top-level tags
+* Thanks to all contributors!
+* Pulled due to avccidental breaking API change
+
+version 0.6.7
+-------------
+
+* Variety of bugfixes from a variety of contributors since 0.6.6 (see commit 
history)
+
+
+version 0.6.6
+-------------
+
+* Read ssh timeout from config file if not specified in method call
+* Tox support
+* Huge XML tree parser support
+* Adding optional bind address to connect
+
+
+version 0.6.5
+-------------
+
+* Updated README for 0.6.5 release
+
+
+version 0.6.4
+-------------
+
+* Pin selectors2 to Python versions <= 3.4
+* Fix config examples to actually use the nc namespace
+* Fix: correctly set port for paramiko when using ssh_config file
+* Test: add test to check ProxyCommand uses correct port
+* Update commits for py3
+* Enhance Alcatel-Lucent-support
+* Juniper RPC: allow specifying format in CompareConfiguration
+* Parsing of NETCONF 1.1 frames no longer decodes each chunk of bytes
+* Fix filter in create_subscription
+* Validate 'with-defaults' mode based on supported modes advertised in 
capability URI
+
+
+version 0.6.3
+-------------
+
+* Fix homepage link registered with PyPi
+* SSH Host Key checking
+* Updated junos.py to resolve RestrictedUser error
+* Close the channel when closing SSH session
+* Invoke self.parse() to ensure errors, if any, have been detected before 
check in ok()
+
+
+version 0.6.2
+-------------
+
+* Migration to user selectors instead of select, allowing higher scale 
operations
+* Improved netconf:base:1.1 parsing
+* Graceful exit on session close
+
+
 version 0.6.0
 -------------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/README new/ncclient-0.6.9/README
--- old/ncclient-0.6.7/README   2019-12-21 20:16:07.000000000 +0100
+++ new/ncclient-0.6.9/README   1970-01-01 01:00:00.000000000 +0100
@@ -1,90 +0,0 @@
-[![Build 
Status](https://travis-ci.org/einarnn/ncclient.svg?branch=master)](https://travis-ci.org/einarnn/ncclient)
-
-ncclient: Python library for NETCONF clients
---------------------------------------------
-
-ncclient is a Python library that facilitates client-side scripting
-and application development around the NETCONF protocol. `ncclient` was
-developed by [Shikar Bhushan](http://schmizz.net). It is now maintained
-by [Leonidas Poulopoulos (@leopoul)](http://ncclient.org/ncclient/)
-
-**Docs**: [http://ncclient.readthedocs.org](http://ncclient.readthedocs.org)
-
-**PyPI**: 
[https://pypi.python.org/pypi/ncclient](https://pypi.python.org/pypi/ncclient)
-
-#### Requirements:
-* Python 2.7 or Python 3.4+
-* setuptools 0.6+
-* Paramiko 1.7+
-* lxml 3.3.0+
-* libxml2
-* libxslt
-
-If you are on Debian/Ubuntu install the following libs (via aptitude or 
apt-get):
-* libxml2-dev
-* libxslt1-dev
-
-#### Installation:
-
-    [ncclient] $ sudo python setup.py install
-    
-or via pip:
-
-    pip install ncclient
-
-#### Examples:
-
-    [ncclient] $ python examples/juniper/*.py
-
-### Usage
-####Get device running config
-Use either an interactive Python console (ipython)
-or integrate the following in your code:
-
-    from ncclient import manager
-
-    with manager.connect(host=host, port=830, username=user, 
hostkey_verify=False) as m:
-        c = m.get_config(source='running').data_xml
-        with open("%s.xml" % host, 'w') as f:
-            f.write(c)
-
-As of 0.4.1 ncclient integrates Juniper's and Cisco's forks, lots of new 
concepts
-have been introduced that ease management of Juniper and Cisco devices 
respectively.
-The biggest change is the introduction of device handlers in connection 
paramms.
-For example to invoke Juniper's functions annd params one has to re-write the 
above with ***device_params={'name':'junos'}***:
-
-    from ncclient import manager
-
-    with manager.connect(host=host, port=830, username=user, 
hostkey_verify=False, device_params={'name':'junos'}) as m:
-        c = m.get_config(source='running').data_xml
-        with open("%s.xml" % host, 'w') as f:
-            f.write(c)
-
-Device handlers are easy to implement and prove to be futureproof.
-
-####Supported device handlers
-
-* Juniper: device_params={'name':'junos'}
-* Cisco CSR: device_params={'name':'csr'}
-* Cisco Nexus: device_params={'name':'nexus'}
-* Huawei: device_params={'name':'huawei'}
-* Alcatel Lucent: device_params={'name':'alu'}
-* H3C: device_params={'name':'h3c'}
-* HP Comware: device_params={'name':'hpcomware'}
-
-
-### Changes | brief - v0.5.3
-
-* Add notifications support
-* Add support for ecdsa keys
-* Various bug fixes
-
-### Contributors
-* v0.5.3: [Justin Wilcox](https://github.com/jwwilcox), [Stacy W. 
Smith](https://github.com/stacywsmith), [Mircea 
Ulinic](https://github.com/mirceaulinic), [Ebben 
Aries](https://github.com/earies), [Einar 
Nilsen-Nygaard](https://github.com/einarnn), 
[QijunPan](https://github.com/QijunPan)
-* v0.5.2: [Nitin Kumar](https://github.com/vnitinv), [Kristian 
Larsson](https://github.com/plajjan), 
[palashgupta](https://github.com/palashgupta), [Jonathan 
Provost](https://github.com/JoProvost), 
[Jainpriyal](https://github.com/Jainpriyal), 
[sharang](https://github.com/sharang), [pseguel](https://github.com/pseguel), 
[nnakamot](https://github.com/nnakamot), [Алексей 
Пастухов](https://github.com/p-alik), [Christian 
Giese](https://github.com/GIC-de), [Peipei Guo](https://github.com/peipeiguo), 
[Time Warner Cable Openstack Team](https://github.com/twc-openstack)
-* v0.4.7: [Einar Nilsen-Nygaard](https://github.com/einarnn), [Vaibhav 
Bajpai](https://github.com/vbajpai), Norio Nakamoto
-* v0.4.6: [Nitin Kumar](https://github.com/vnitinv), [Carl 
Moberg](https://github.com/cmoberg), [Stavros 
Kroustouris](https://github.com/kroustou)
-* v0.4.5: [Sebastian Wiesinger](https://github.com/sebastianw), [Vincent 
Bernat](https://github.com/vincentbernat), [Matthew 
Stone](https://github.com/bigmstone), [Nitin Kumar](https://github.com/vnitinv)
-* v0.4.3: [Jeremy Schulman](https://github.com/jeremyschulman), [Ray 
Solomon](https://github.com/rsolomo), [Rick 
Sherman](https://github.com/shermdog), [subhak186](https://github.com/subhak186)
-* v0.4.2: [katharh](https://github.com/katharh), [Francis Luong 
(Franco)](https://github.com/francisluong), [Vincent 
Bernat](https://github.com/vincentbernat), [Juergen 
Brendel](https://github.com/juergenbrendel), [Quentin 
Loos](https://github.com/Kent1), [Ray Solomon](https://github.com/rsolomo), 
[Sebastian Wiesinger](https://github.com/sebastianw), [Ebben 
Aries](https://github.com/earies)
-* v0.4.1: [Jeremy Schulman](https://github.com/jeremyschulman), [Ebben 
Aries](https://github.com/earies), Juergen Brendel
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/README.md new/ncclient-0.6.9/README.md
--- old/ncclient-0.6.7/README.md        2019-12-21 20:16:07.000000000 +0100
+++ new/ncclient-0.6.9/README.md        2020-08-09 00:09:16.000000000 +0200
@@ -19,6 +19,8 @@
 
 |  Date  | Release | Description |
 | :----: | :-----: | :---------- |
+| 08/08/20 | `0.6.9` | See [release 
page](https://github.com/ncclient/ncclient/releases/tag/v0.6.9) |
+| 08/01/20 | `0.6.8` | Pulled due to accidental breaking API change |
 | 12/21/19 | `0.6.7` | See [release 
page](https://github.com/ncclient/ncclient/releases/tag/v0.6.7) |
 | 05/27/19 | `0.6.6` | See [release 
page](https://github.com/ncclient/ncclient/releases/tag/v0.6.6) |
 | 05/27/19 | `0.6.5` | Pulled due to bug in PyPi upload |
@@ -186,6 +188,7 @@
 
 ## Contributors
 
+* v0.6.8: [Fred Gan](https://github.com/fredgan), @vnitinv, @kbijakowski, 
@iwanb, @badguy99, @liuyong, Andrew Mallory, William Lvory
 * v0.6.7: @vnitinv, @chaitu-tk, @sidhujasminder, @crutcha, @markgoddard, 
@ganeshrn, @songxl, @doesitblend, @psikala, @xuxiaowei0512, @muffizone
 * v0.6.6: @sstancu, @hemna, @ishayansheikh
 * v0.6.4: @davidhankins, @mzagozen, @knobix, @markafarrell, @psikala, 
@moepman, @apt-itude, @yuekyang
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/README.rst 
new/ncclient-0.6.9/README.rst
--- old/ncclient-0.6.7/README.rst       2019-12-21 20:16:07.000000000 +0100
+++ new/ncclient-0.6.9/README.rst       2020-08-09 00:09:16.000000000 +0200
@@ -3,8 +3,9 @@
 
 ncclient is a Python library that facilitates client-side scripting and
 application development around the NETCONF protocol. ``ncclient`` was
-developed by `Shikar Bhushan <http://schmizz.net>`_. It is now
-maintained by `Leonidas Poulopoulos (@leopoul) <http://ncclient.org>`_
+developed by `Shikar Bhushan <http://schmizz.net>`. It is now
+maintained by `Leonidas Poulopoulos (@leopoul) <http://ncclient.org>`
+and `Einar Nilsen-Nygaard (@einarnn)`.
 
 Docs:
 `http://ncclient.readthedocs.org <http://ncclient.readthedocs.org>`_
@@ -86,17 +87,80 @@
 Supported device handlers
 '''''''''''''''''''''''''
 
-* Juniper: device_params={'name':'junos'}
-* Cisco CSR: device_params={'name':'csr'}
-* Cisco Nexus: device_params={'name':'nexus'}
-* Huawei: device_params={'name':'huawei'}
-* Alcatel Lucent: device_params={'name':'alu'}
-* H3C: device_params={'name':'h3c'}
-* HP Comware: device_params={'name':'hpcomware'}
+* Juniper: `device_params={'name':'junos'}`
+* Cisco:
+    - CSR: `device_params={'name':'csr'}`
+    - Nexus: `device_params={'name':'nexus'}`
+    - IOS XR: `device_params={'name':'iosxr'}`
+    - IOS XE: `device_params={'name':'iosxe'}`
+* Huawei:
+    - `device_params={'name':'huawei'}`
+    - `device_params={'name':'huaweiyang'}`
+* Alcatel Lucent: `device_params={'name':'alu'}`
+* H3C: `device_params={'name':'h3c'}`
+* HP Comware: `device_params={'name':'hpcomware'}`
+* Server or anything not in above: `device_params={'name':'default'}`
 
 Changes \| brief
 ~~~~~~~~~~~~~~~~
 
+**v0.6.9**
+
+* Fix for breaking API change
+
+**v0.6.8**
+
+* Pulled due to accidental breaking API change
+* Variety of small updates and bugfixes, but of note:
+    - Support for namespace prefixes for XPath queries
+    - `edit-config` parameter validation
+    - Support for multiple RPC errors
+    - API to get supported device types
+    - Support for subtree filters with multiple top-level tags
+* Thanks to all contributors!
+
+**v0.6.7**
+
+- Variety of bugfixes from a variety of contributors since 0.6.6 (see commit 
history)
+
+**v0.6.6**
+
+- Read ssh timeout from config file if not specified in method call
+- Tox support
+- Huge XML tree parser support
+- Adding optional bind address to connect
+
+**v0.6.5**
+
+- Updated README for 0.6.5 release
+
+**v0.6.4**
+
+- Pin selectors2 to Python versions <= 3.4
+- Fix config examples to actually use the nc namespace
+- Fix: correctly set port for paramiko when using ssh_config file
+- Test: add test to check ProxyCommand uses correct port
+- Update commits for py3
+- Enhance Alcatel-Lucent-support
+- Juniper RPC: allow specifying format in CompareConfiguration
+- Parsing of NETCONF 1.1 frames no longer decodes each chunk of bytes
+- Fix filter in create_subscription
+- Validate 'with-defaults' mode based on supported modes advertised in 
capability URI
+
+**v0.6.3**
+
+- Fix homepage link registered with PyPi
+- SSH Host Key checking
+- Updated junos.py to resolve RestrictedUser error
+- Close the channel when closing SSH session
+- Invoke self.parse() to ensure errors, if any, have been detected before 
check in ok()
+
+**v0.6.2**
+
+- Migration to user selectors instead of select, allowing higher scale 
operations
+- Improved netconf:base:1.1 parsing
+- Graceful exit on session close
+
 **v0.6.0**
 
 - Fix use of new Python 3.7 keyword, async
@@ -180,7 +244,13 @@
 
 Acknowledgements
 ~~~~~~~~~~~~~~~~
-
+-  v0.6.9: [Fred Gan](https://github.com/fredgan)
+-  v0.6.8: [Fred Gan](https://github.com/fredgan), @vnitinv, @kbijakowski, 
@iwanb, @badguy99, @liuyong, Andrew Mallory, William Lvory
+-  v0.6.7: @vnitinv, @chaitu-tk, @sidhujasminder, @crutcha, @markgoddard, 
@ganeshrn, @songxl, @doesitblend, @psikala, @xuxiaowei0512, @muffizone
+-  v0.6.6: @sstancu, @hemna, @ishayansheikh
+-  v0.6.4: @davidhankins, @mzagozen, @knobix, @markafarrell, @psikala, 
@moepman, @apt-itude, @yuekyang
+-  v0.6.3: @rdkls, @Anthony25, @rsmekala, @vnitinv, @siming85
+-  v0.6.2: @einarnn, @glennmatthews, @bryan-stripe, @nickylba
 -  v0.6.0: `Einar Nilsen-Nygaard`_
 -  v0.5.4: Various
 -  v0.5.3: `Justin Wilcox`_, `Stacy W. Smith`_, `Mircea Ulinic`_,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/docs/requirements.txt 
new/ncclient-0.6.9/docs/requirements.txt
--- old/ncclient-0.6.7/docs/requirements.txt    1970-01-01 01:00:00.000000000 
+0100
+++ new/ncclient-0.6.9/docs/requirements.txt    2020-08-09 00:09:16.000000000 
+0200
@@ -0,0 +1,2 @@
+Sphinx==3.2.0
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/docs/source/conf.py 
new/ncclient-0.6.9/docs/source/conf.py
--- old/ncclient-0.6.7/docs/source/conf.py      2019-12-21 20:16:07.000000000 
+0100
+++ new/ncclient-0.6.9/docs/source/conf.py      2020-08-09 00:09:16.000000000 
+0200
@@ -46,9 +46,9 @@
 # built documents.
 #
 # The short X.Y version.
-version = '0.5'
+version = '0.6'
 # The full version, including alpha/beta/rc tags.
-release = '0.5.3'
+release = '0.6.9'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/docs/source/index.rst 
new/ncclient-0.6.9/docs/source/index.rst
--- old/ncclient-0.6.7/docs/source/index.rst    2019-12-21 20:16:07.000000000 
+0100
+++ new/ncclient-0.6.9/docs/source/index.rst    2020-08-09 00:09:16.000000000 
+0200
@@ -3,7 +3,7 @@
 
 `ncclient` is a Python library for NETCONF clients. It aims to offer an 
intuitive API that sensibly maps the XML-encoded nature of NETCONF to Python 
constructs and idioms, and make writing network-management scripts easier. 
Other key features are:
 
-* Supports all operations and capabilities defined in :rfc:`4741`.
+* Supports all operations and capabilities defined in :rfc:`6241`.
 * Request pipelining.
 * Asynchronous RPC requests.
 * Keeping XML out of the way unless really needed.
@@ -39,10 +39,19 @@
 
 Supported device handlers
 -------------------------
-* Juniper: device_params={'name':'junos'}
-* Cisco CSR: device_params={'name':'csr'}
-* Cisco Nexus: device_params={'name':'nexus'}
-* Huawei: device_params={'name':'huawei'}
+* Juniper: `device_params={'name':'junos'}`
+* Cisco:
+    - CSR: `device_params={'name':'csr'}`
+    - Nexus: `device_params={'name':'nexus'}`
+    - IOS XR: `device_params={'name':'iosxr'}`
+    - IOS XE: `device_params={'name':'iosxe'}`
+* Huawei:
+    - `device_params={'name':'huawei'}`
+    - `device_params={'name':'huaweiyang'}`
+* Alcatel Lucent: `device_params={'name':'alu'}`
+* H3C: `device_params={'name':'h3c'}`
+* HP Comware: `device_params={'name':'hpcomware'}`
+* Server or anything not in above: `device_params={'name':'default'}`
 
 
 Contents:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/docs/source/manager.rst 
new/ncclient-0.6.9/docs/source/manager.rst
--- old/ncclient-0.6.7/docs/source/manager.rst  2019-12-21 20:16:07.000000000 
+0100
+++ new/ncclient-0.6.9/docs/source/manager.rst  2020-08-09 00:09:16.000000000 
+0200
@@ -40,37 +40,79 @@
 
     .. autoattribute:: HUGE_TREE_DEFAULT
 
-    .. automethod:: get_config(source, filter=None)
+    .. method:: get_config(source, filter=None, with_defaults=None)
 
-    .. automethod:: edit_config(target, config, default_operation=None, 
test_option=None, error_option=None)
+       `get_config` is mapped to :class:`~ncclient.operations.GetConfig`
 
-    .. automethod:: copy_config(source, target)
+    .. method:: get_schema(identifier, version=None, format=None)
 
-    .. automethod:: delete_config(target)
+       `get_schema` is mapped to :class:`~ncclient.operations.GetSchema`
 
-    .. automethod:: dispatch(rpc_command, source=None, filter=None)
+    .. method:: edit_config(config, format='xml', target='candidate', 
default_operation=None, test_option=None, error_option=None)
 
-    .. automethod:: lock(target)
+       `edit_config` is mapped to :class:`~ncclient.operations.EditConfig`
 
-    .. automethod:: unlock(target)
+    .. method:: copy_config(source, target)
 
-    .. automethod:: locked(target)
+       `copy_config` is mapped to :class:`~ncclient.operations.CopyConfig`
+
+    .. method:: delete_config(target)
+
+       `delete_config` is mapped to :class:`~ncclient.operations.DeleteConfig`
+
+    .. method:: dispatch(rpc_command, source=None, filter=None)
+
+       `dispatch` is mapped to :class:`~ncclient.operations.Dispatch`
+
+    .. method:: lock(target="candidate")
+
+       `lock` is mapped to :class:`~ncclient.operations.Lock`
+
+    .. method:: unlock(target="candidate")
+
+       `unlock` is mapped to :class:`~ncclient.operations.Unlock`
+
+    .. method:: get(filter=None, with_defaults=None)
+
+       `get` is mapped to :class:`~ncclient.operations.Get`
+
+    .. method:: close_session()
+
+       `close_session` is mapped to :class:`~ncclient.operations.CloseSession`
 
-    .. automethod:: get()
+    .. method:: kill_session(session_id)
 
-    .. automethod:: close_session()
+       `kill_session` is mapped to :class:`~ncclient.operations.KillSession`
 
-    .. automethod:: kill_session(session_id)
+    .. method:: commit(confirmed=False, timeout=None, persist=None, 
persist_id=None)
 
-    .. automethod:: commit(confirmed=False, timeout=None, persist=None)
+       `commit` is mapped to :class:`~ncclient.operations.Commit`
 
-    .. automethod:: cancel_commit(persist_id=None)
+    .. method:: cancel_commit(persist_id=None)
 
-    .. automethod:: discard_changes()
+       `cancel_commit` is mapped to :class:`~ncclient.operations.CancelCommit`
 
-    .. automethod:: validate(source)
+    .. method:: discard_changes()
 
-    .. automethod:: create_subscription()
+       `discard_changes` is mapped to 
:class:`~ncclient.operations.DiscardChanges`
+
+    .. method:: validate(source="candidate")
+
+       `validate` is mapped to :class:`~ncclient.operations.Validate`
+
+    .. method:: create_subscription(filter=None, stream_name=None, 
start_time=None, stop_time=None)
+
+       `create_subscription` is mapped to 
:class:`~ncclient.operations.CreateSubscription`
+
+    .. method:: reboot_machine()
+
+       `reboot_machine` is mapped to 
:class:`~ncclient.operations.RebootMachine`
+
+    .. method:: poweroff_machine()
+
+       `poweroff_machine` is mapped to 
:class:`~ncclient.operations.PoweroffMachine`
+
+    .. automethod:: locked(target)
 
     .. automethod:: take_notification(block=True, timeout=None)
 
@@ -115,7 +157,13 @@
 
     Here *type* has to be one of `"xpath"` or `"subtree"`.
 
-    * For `"xpath"` the *criteria* should be a string containing the XPath 
expression.
+    * For `"xpath"` the *criteria* should be a string containing the XPath 
expression or a tuple containing a dict of namespace mapping and the XPath 
expression.
     * For `"subtree"` the *criteria* should be an XML string or an 
:class:`~xml.etree.ElementTree.Element` object containing the criteria.
 
+* A list of *spec*
+
+    Here *type* has to be `"subtree"`.
+
+    * the *spec* should be a list containing multiple XML string or multiple 
:class:`~xml.etree.ElementTree.Element` objects.
+
 * A `<filter>` element as an XML string or an 
:class:`~xml.etree.ElementTree.Element` object.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/docs/source/operations.rst 
new/ncclient-0.6.9/docs/source/operations.rst
--- old/ncclient-0.6.7/docs/source/operations.rst       2019-12-21 
20:16:07.000000000 +0100
+++ new/ncclient-0.6.9/docs/source/operations.rst       2020-08-09 
00:09:16.000000000 +0200
@@ -48,6 +48,12 @@
 
     .. autoattribute:: REPLY_CLS
 
+.. autoclass:: GetSchema
+    :members: request
+    :show-inheritance:
+
+    .. autoattribute:: REPLY_CLS
+
 Editing
 ........
 
@@ -79,6 +85,17 @@
     :members: request
     :show-inheritance:
 
+Flowmon
+........
+
+.. autoclass:: PoweroffMachine
+    :members: request
+    :show-inheritance:
+
+.. autoclass:: RebootMachine
+    :members: request
+    :show-inheritance:
+
 Locking
 ........
 
@@ -101,6 +118,13 @@
     :members: request
     :show-inheritance:
 
+Subscribing
+............
+
+.. autoclass:: CreateSubscription
+    :members: request
+    :show-inheritance:
+
 Exceptions
 ----------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/ncclient/__init__.py 
new/ncclient-0.6.9/ncclient/__init__.py
--- old/ncclient-0.6.7/ncclient/__init__.py     2019-12-21 20:16:07.000000000 
+0100
+++ new/ncclient-0.6.9/ncclient/__init__.py     2020-08-09 00:09:16.000000000 
+0200
@@ -12,7 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-__version__ = (0,5,3)
+__version__ = (0,6,9)
 
 import sys
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/ncclient/_version.py 
new/ncclient-0.6.9/ncclient/_version.py
--- old/ncclient-0.6.7/ncclient/_version.py     2019-12-21 20:16:07.000000000 
+0100
+++ new/ncclient-0.6.9/ncclient/_version.py     2020-08-09 00:09:16.000000000 
+0200
@@ -23,9 +23,9 @@
     # setup.py/versioneer.py will grep for the variable names, so they must
     # each be defined on a line of their own. _version.py will just call
     # get_keywords().
-    git_refnames = " (tag: v0.6.7)"
-    git_full = "8d4cc7195a8160a1e35b4307b8b08c5de3dec97f"
-    git_date = "2019-12-21 19:16:07 +0000"
+    git_refnames = " (HEAD -> master, tag: v0.6.9)"
+    git_full = "3380f1140791f4a8de5d303f919f1e4cc9532f32"
+    git_date = "2020-08-08 23:09:16 +0100"
     keywords = {"refnames": git_refnames, "full": git_full, "date": git_date}
     return keywords
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/ncclient/capabilities.py 
new/ncclient-0.6.9/ncclient/capabilities.py
--- old/ncclient-0.6.7/ncclient/capabilities.py 2019-12-21 20:16:07.000000000 
+0100
+++ new/ncclient-0.6.9/ncclient/capabilities.py 2020-08-09 00:09:16.000000000 
+0200
@@ -13,7 +13,6 @@
 # limitations under the License.
 
 import logging
-import sys
 import six
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/ncclient/devices/__init__.py 
new/ncclient-0.6.9/ncclient/devices/__init__.py
--- old/ncclient-0.6.7/ncclient/devices/__init__.py     2019-12-21 
20:16:07.000000000 +0100
+++ new/ncclient-0.6.9/ncclient/devices/__init__.py     2020-08-09 
00:09:16.000000000 +0200
@@ -0,0 +1,19 @@
+# supported devices config, add new device (eg: 'device name':'device lable').
+supported_devices_cfg = {'junos':'Juniper',
+                         'csr':'Cisco CSR1000v',
+                         'nexus':'Cisco Nexus',
+                         'iosxr':'Cisco IOS XR',
+                         'iosxe':'Cisco IOS XE',
+                         'huawei':'Huawei',
+                         'huaweiyang':'Huawei',
+                         'alu':'Alcatel Lucent',
+                         'h3c':'H3C',
+                         'hpcomware':'HP Comware',
+                         'default':'Server or anything not in above'}
+
+def get_supported_devices():
+    return tuple(supported_devices_cfg.keys())
+
+def get_supported_device_labels():
+    return supported_devices_cfg
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/ncclient/devices/csr.py 
new/ncclient-0.6.9/ncclient/devices/csr.py
--- old/ncclient-0.6.7/ncclient/devices/csr.py  2019-12-21 20:16:07.000000000 
+0100
+++ new/ncclient-0.6.9/ncclient/devices/csr.py  2020-08-09 00:09:16.000000000 
+0200
@@ -28,6 +28,4 @@
         super(CsrDeviceHandler, self).__init__(device_params)
 
     def add_additional_ssh_connect_params(self, kwargs):
-        kwargs['allow_agent']   = False
-        kwargs['look_for_keys'] = False
         kwargs['unknown_host_cb'] = csr_unknown_host_cb
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/ncclient/devices/h3c.py 
new/ncclient-0.6.9/ncclient/devices/h3c.py
--- old/ncclient-0.6.7/ncclient/devices/h3c.py  2019-12-21 20:16:07.000000000 
+0100
+++ new/ncclient-0.6.9/ncclient/devices/h3c.py  2020-08-09 00:09:16.000000000 
+0200
@@ -1,19 +1,17 @@
 """
-Handler for Huawei device specific information.
+Handler for H3c device specific information.
 
 Note that for proper import, the classname has to be:
 
     "<Devicename>DeviceHandler"
 
-...where <Devicename> is something like "Default", "Huawei", etc.
+...where <Devicename> is something like "Default", "H3c", etc.
 
 All device-specific handlers derive from the DefaultDeviceHandler, which 
implements the
 generic information needed for interaction with a Netconf server.
 
 """
 
-from ncclient.xml_ import BASE_NS_1_0
-
 from .default import DefaultDeviceHandler
 from ncclient.operations.third_party.h3c.rpc import *
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/ncclient/devices/iosxe.py 
new/ncclient-0.6.9/ncclient/devices/iosxe.py
--- old/ncclient-0.6.7/ncclient/devices/iosxe.py        2019-12-21 
20:16:07.000000000 +0100
+++ new/ncclient-0.6.9/ncclient/devices/iosxe.py        2020-08-09 
00:09:16.000000000 +0200
@@ -35,6 +35,4 @@
         return dict
         
     def add_additional_ssh_connect_params(self, kwargs):
-        kwargs['allow_agent']   = False
-        kwargs['look_for_keys'] = False
         kwargs['unknown_host_cb'] = iosxe_unknown_host_cb
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/ncclient/devices/iosxr.py 
new/ncclient-0.6.9/ncclient/devices/iosxr.py
--- old/ncclient-0.6.7/ncclient/devices/iosxr.py        2019-12-21 
20:16:07.000000000 +0100
+++ new/ncclient-0.6.9/ncclient/devices/iosxr.py        2020-08-09 
00:09:16.000000000 +0200
@@ -28,9 +28,6 @@
         super(IosxrDeviceHandler, self).__init__(device_params)
 
     def add_additional_ssh_connect_params(self, kwargs):
-        kwargs['allow_agent']   = False
-        kwargs['look_for_keys'] = False
-        kwargs['hostkey_verify'] = False
         kwargs['unknown_host_cb'] = iosxr_unknown_host_cb
 
     def perform_qualify_check(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/ncclient/manager.py 
new/ncclient-0.6.9/ncclient/manager.py
--- old/ncclient-0.6.7/ncclient/manager.py      2019-12-21 20:16:07.000000000 
+0100
+++ new/ncclient-0.6.9/ncclient/manager.py      2020-08-09 00:09:16.000000000 
+0200
@@ -18,10 +18,8 @@
 It exposes all core functionality.
 """
 
-from ncclient import capabilities
 from ncclient import operations
 from ncclient import transport
-import six
 import logging
 import functools
 
@@ -57,8 +55,6 @@
 operations to the :class:`Manager` API.
 """
 
-VENDOR_OPERATIONS = {}
-
 
 def make_device_handler(device_params):
     """
@@ -131,8 +127,6 @@
 
     device_handler = make_device_handler(device_params)
     device_handler.add_additional_ssh_connect_params(kwds)
-    global VENDOR_OPERATIONS
-    VENDOR_OPERATIONS.update(device_handler.add_additional_operations())
     session = transport.SSHSession(device_handler)
     if "hostkey_verify" not in kwds or kwds["hostkey_verify"]:
         session.load_known_hosts()
@@ -157,8 +151,6 @@
 
     device_handler = make_device_handler(device_params)
 
-    global VENDOR_OPERATIONS
-    VENDOR_OPERATIONS.update(device_handler.add_additional_operations())
     session = third_party_import.IOProc(device_handler)
     session.connect()
 
@@ -180,7 +172,7 @@
 
     """
     For details on the expected behavior of the operations and their
-        parameters refer to :rfc:`4741`.
+        parameters refer to :rfc:`6241`.
 
     Manager instances are also context managers so you can use it like this::
 
@@ -209,6 +201,9 @@
         self._raise_mode = operations.RaiseMode.ALL
         self._huge_tree = self.HUGE_TREE_DEFAULT
         self._device_handler = device_handler
+        self._vendor_operations = {}
+        if device_handler:
+            
self._vendor_operations.update(device_handler.add_additional_operations())
 
     def __enter__(self):
         return self
@@ -259,8 +254,8 @@
         raise NotImplementedError
 
     def __getattr__(self, method):
-        if method in VENDOR_OPERATIONS:
-            return functools.partial(self.execute, VENDOR_OPERATIONS[method])
+        if method in self._vendor_operations:
+            return functools.partial(self.execute, 
self._vendor_operations[method])
         elif method in OPERATIONS:
             return functools.partial(self.execute, OPERATIONS[method])
         else:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/ncclient/operations/edit.py 
new/ncclient-0.6.9/ncclient/operations/edit.py
--- old/ncclient-0.6.7/ncclient/operations/edit.py      2019-12-21 
20:16:07.000000000 +0100
+++ new/ncclient-0.6.9/ncclient/operations/edit.py      2020-08-09 
00:09:16.000000000 +0200
@@ -39,7 +39,7 @@
 
         *default_operation* if specified must be one of { `"merge"`, 
`"replace"`, or `"none"` }
 
-        *test_option* if specified must be one of { `"test_then_set"`, `"set"` 
}
+        *test_option* if specified must be one of { `"test-then-set"`, 
`"set"`, `"test-only"` }
 
         *error_option* if specified must be one of { `"stop-on-error"`, 
`"continue-on-error"`, `"rollback-on-error"` }
 
@@ -47,25 +47,25 @@
         """
         node = new_ele("edit-config")
         node.append(util.datastore_or_url("target", target, self._assert))
-        if default_operation is not None:
-        # TODO: check if it is a valid default-operation
+        if (default_operation is not None
+                and util.validate_args('default_operation', default_operation, 
["merge", "replace", "none"]) is True):
             sub_ele(node, "default-operation").text = default_operation
-        if test_option is not None:
+        if (test_option is not None
+                and util.validate_args('test_option', test_option, 
["test-then-set", "set", "test-only"]) is True):
             self._assert(':validate')
+            if test_option == 'test-only':
+                self._assert(':validate:1.1')
             sub_ele(node, "test-option").text = test_option
-        if error_option is not None:
+        if (error_option is not None
+                and util.validate_args('error_option', error_option, 
["stop-on-error", "continue-on-error", "rollback-on-error"]) is True):
             if error_option == "rollback-on-error":
                 self._assert(":rollback-on-error")
             sub_ele(node, "error-option").text = error_option
-# <<<<<<< HEAD
-#         node.append(validated_element(config, ("config", qualify("config"))))
-# =======
         if format == 'xml':
             node.append(validated_element(config, ("config", 
qualify("config"))))
         if format == 'text':
             config_text = sub_ele(node, "config-text")
             sub_ele(config_text, "configuration-text").text = config
-# >>>>>>> juniper
         return self._request(node)
 
 
@@ -149,8 +149,8 @@
         *persist_id* value must be equal to the value given in the <persist> 
parameter to the original <commit> operation.
         """
         node = new_ele("commit")
-        if (confirmed or persist) and persist_id:
-            raise OperationError("Invalid operation as confirmed or persist 
cannot be present with persist-id")
+        if persist and persist_id:
+            raise OperationError("Invalid operation as persist cannot be 
present with persist-id")
         if confirmed:
             self._assert(":confirmed-commit")
             sub_ele(node, "confirmed")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/ncclient/operations/retrieve.py 
new/ncclient-0.6.9/ncclient/operations/retrieve.py
--- old/ncclient-0.6.7/ncclient/operations/retrieve.py  2019-12-21 
20:16:07.000000000 +0100
+++ new/ncclient-0.6.9/ncclient/operations/retrieve.py  2020-08-09 
00:09:16.000000000 +0200
@@ -74,7 +74,7 @@
 
         *filter* specifies the portion of the configuration to retrieve (by 
default entire configuration is retrieved)
 
-        *with_defaults* defines an explicit method of retrieving default 
values from the configuration (see RFC 6243)
+        *with_defaults* defines an explicit method of retrieving default 
values from the configuration (see :rfc:`6243`)
 
         :seealso: :ref:`filter_params`
         """
@@ -149,7 +149,7 @@
 
         *filter* specifies the portion of the configuration to retrieve (by 
default entire configuration is retrieved)
 
-        *with_defaults* defines an explicit method of retrieving default 
values from the configuration (see RFC 6243)
+        *with_defaults* defines an explicit method of retrieving default 
values from the configuration (see :rfc:`6243`)
 
         :seealso: :ref:`filter_params`"""
         node = new_ele("get-config")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/ncclient/operations/rpc.py 
new/ncclient-0.6.9/ncclient/operations/rpc.py
--- old/ncclient-0.6.7/ncclient/operations/rpc.py       2019-12-21 
20:16:07.000000000 +0100
+++ new/ncclient-0.6.9/ncclient/operations/rpc.py       2020-08-09 
00:09:16.000000000 +0200
@@ -14,7 +14,6 @@
 
 from threading import Event, Lock
 from uuid import uuid4
-import six
 
 from ncclient.xml_ import *
 from ncclient.logging_ import SessionLoggerAdapter
@@ -33,6 +32,7 @@
     tag_to_attr = {
         qualify("error-type"): "_type",
         qualify("error-tag"): "_tag",
+        qualify("error-app-tag"): "_app_tag",
         qualify("error-severity"): "_severity",
         qualify("error-info"): "_info",
         qualify("error-path"): "_path",
@@ -43,6 +43,7 @@
         self._raw = raw
         if errs is None:
             # Single RPCError
+            self._errlist = None
             for attr in six.itervalues(RPCError.tag_to_attr):
                 setattr(self, attr, None)
             for subele in raw:
@@ -55,6 +56,7 @@
                 OperationError.__init__(self, self.to_dict())
         else:
             # Multiple errors returned. Errors is a list of RPCError objs
+            self._errlist = errs
             errlist = []
             for err in errs:
                 if err.severity:
@@ -96,6 +98,11 @@
         return self._tag
 
     @property
+    def app_tag(self):
+        "The contents of the `error-app-tag` element."
+        return self._app_tag
+
+    @property
     def severity(self):
         "The contents of the `error-severity` element."
         return self._severity
@@ -115,6 +122,11 @@
         "XML string or `None`; representing the `error-info` element."
         return self._info
 
+    @property
+    def errlist(self):
+        "List of errors if this represents multiple errors, otherwise None."
+        return self._errlist
+
 
 class RPCReply(object):
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/ncclient/operations/util.py 
new/ncclient-0.6.9/ncclient/operations/util.py
--- old/ncclient-0.6.7/ncclient/operations/util.py      2019-12-21 
20:16:07.000000000 +0100
+++ new/ncclient-0.6.9/ncclient/operations/util.py      2020-08-09 
00:09:16.000000000 +0200
@@ -49,13 +49,23 @@
     type = None
     if isinstance(spec, tuple):
         type, criteria = spec
-        rep = new_ele("filter", type=type)
         if type == "xpath":
-            rep.attrib["select"] = criteria
+            if isinstance(criteria, tuple):
+                ns, select = criteria
+                rep = new_ele_nsmap("filter", ns, type=type)
+                rep.attrib["select"] = select
+            else:
+                rep = new_ele("filter", type=type)
+                rep.attrib["select"]=criteria
         elif type == "subtree":
+            rep = new_ele("filter", type=type)
             rep.append(to_ele(criteria))
         else:
             raise OperationError("Invalid filter type")
+    elif isinstance(spec, list):
+        rep = new_ele("filter", type="subtree")
+        for cri in spec:
+            rep.append(to_ele(cri))
     else:
 
         rep = validated_element(spec, ("filter", qualify("filter"),
@@ -67,3 +77,9 @@
     if type == "xpath" and capcheck is not None:
         capcheck(":xpath")
     return rep
+
+def validate_args(arg_name, value, args_list):
+    # this is a common method, which used to check whether a value is in 
args_list
+    if value not in args_list:
+        raise OperationError('Invalid value "%s" in "%s" element' % (value, 
arg_name))
+    return True
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/ncclient/transport/session.py 
new/ncclient-0.6.9/ncclient/transport/session.py
--- old/ncclient-0.6.7/ncclient/transport/session.py    2019-12-21 
20:16:07.000000000 +0100
+++ new/ncclient-0.6.9/ncclient/transport/session.py    2020-08-09 
00:09:16.000000000 +0200
@@ -14,8 +14,6 @@
 # limitations under the License.
 
 
-import re
-import sys
 import logging
 from threading import Thread, Lock, Event
 try:
@@ -72,10 +70,12 @@
             else:
                 self.logger.error('error parsing dispatch message: %s', e)
                 return
+        self.logger.debug('dispatching message to different listeners: %s',
+                          raw)
         with self._lock:
             listeners = list(self._listeners)
         for l in listeners:
-            self.logger.debug('dispatching message to %r: %s', l, raw)
+            self.logger.debug('dispatching message to listener: %r', l)
             l.callback(root, raw) # no try-except; fail loudly if you must!
 
     def _dispatch_error(self, err):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/ncclient/transport/ssh.py 
new/ncclient-0.6.9/ncclient/transport/ssh.py
--- old/ncclient-0.6.7/ncclient/transport/ssh.py        2019-12-21 
20:16:07.000000000 +0100
+++ new/ncclient-0.6.9/ncclient/transport/ssh.py        2020-08-09 
00:09:16.000000000 +0200
@@ -322,7 +322,7 @@
             host_port = '[%s]:%s' % (host, port)
             
known_host_keys_for_this_host.update(self._host_keys.lookup(host_port) or {})
             if known_host_keys_for_this_host:
-                self._transport._preferred_keys = [x.key.get_name() for x in 
known_host_keys_for_this_host._entries]
+                self._transport._preferred_keys = 
list(known_host_keys_for_this_host)
 
         # Connect
         try:
@@ -349,7 +349,7 @@
                 is_known_host = any(self._host_keys.check(lookup, 
server_key_obj) for lookup in known_hosts_lookups)
 
             if not is_known_host and not unknown_host_cb(host, fingerprint):
-                raise SSHUnknownHostError(known_hosts_lookup[0], fingerprint)
+                raise SSHUnknownHostError(known_hosts_lookups[0], fingerprint)
 
         # Authenticating with our private key/identity
         if key_filename is None:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ncclient-0.6.7/ncclient/transport/third_party/junos/ioproc.py 
new/ncclient-0.6.9/ncclient/transport/third_party/junos/ioproc.py
--- old/ncclient-0.6.7/ncclient/transport/third_party/junos/ioproc.py   
2019-12-21 20:16:07.000000000 +0100
+++ new/ncclient-0.6.9/ncclient/transport/third_party/junos/ioproc.py   
2020-08-09 00:09:16.000000000 +0200
@@ -1,4 +1,3 @@
-import os
 import sys
 import re
 import six
@@ -7,7 +6,6 @@
     from cStringIO import StringIO
 else:
     from io import BytesIO as StringIO
-from select import select
 if sys.version>='2.7':
     from subprocess import Popen, check_output, PIPE, STDOUT
 else:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ncclient-0.6.7/ncclient/transport/third_party/junos/parser.py 
new/ncclient-0.6.9/ncclient/transport/third_party/junos/parser.py
--- old/ncclient-0.6.7/ncclient/transport/third_party/junos/parser.py   
2019-12-21 20:16:07.000000000 +0100
+++ new/ncclient-0.6.9/ncclient/transport/third_party/junos/parser.py   
2020-08-09 00:09:16.000000000 +0200
@@ -33,12 +33,10 @@
 import logging
 logger = logging.getLogger("ncclient.transport.third_party.junos.parser")
 
+from ncclient.xml_ import BASE_NS_1_0
 
-class RPCTags:
-    RPC_REPLY_END_TAG = "</rpc-reply>"
-    RPC_REPLY_END_TAG_LEN = len(RPC_REPLY_END_TAG)
-    RPC_REPLY_START_TAG = "<rpc-reply"
-    NAMESPACES = {"nc": "urn:ietf:params:xml:ns:netconf:base:1.0"}
+RPC_REPLY_END_TAG = "</rpc-reply>"
+RFC_RPC_REPLY_END_TAG = "</nc:rpc-reply>"
 
 
 class JunosXMLParser(DefaultXMLParser):
@@ -47,7 +45,6 @@
         self._session = session
         self.sax_parser = make_parser()
         self.sax_parser.setContentHandler(SAXParser(session))
-        self.rpc_tags = RPCTags
 
     def parse(self, data):
         try:
@@ -82,9 +79,11 @@
             # we need to renew parser, as old parser is gone.
             self.sax_parser = make_parser()
             self.sax_parser.setContentHandler(SAXParser(self._session))
-        elif self.rpc_tags.RPC_REPLY_END_TAG in data:
+        elif RPC_REPLY_END_TAG in data or RFC_RPC_REPLY_END_TAG in data:
+            tag = RPC_REPLY_END_TAG if RPC_REPLY_END_TAG in data else \
+                RFC_RPC_REPLY_END_TAG
             logger.warning("Check for rpc reply end tag within data received: 
%s" % data)
-            msg, delim, remaining = 
data.partition(self.rpc_tags.RPC_REPLY_END_TAG)
+            msg, delim, remaining = data.partition(tag)
             self._session._buffer.seek(0, os.SEEK_END)
             self._session._buffer.write(remaining.encode())
         else:
@@ -94,9 +93,13 @@
             # if then, wait for next iteration of data and do a recursive call 
to
             # _delimiter_check for MSG_DELIM check
             buf = self._session._buffer
-            buf.seek(buf.tell() - self.rpc_tags.RPC_REPLY_END_TAG_LEN - 
MSG_DELIM_LEN)
+            buf.seek(buf.tell() - len(RFC_RPC_REPLY_END_TAG) - MSG_DELIM_LEN)
             rpc_response_last_msg = buf.read().decode('UTF-8').replace('\n', 
'')
-            if self.rpc_tags.RPC_REPLY_END_TAG in rpc_response_last_msg:
+            if RPC_REPLY_END_TAG in rpc_response_last_msg or \
+                    RFC_RPC_REPLY_END_TAG in rpc_response_last_msg:
+                tag = RPC_REPLY_END_TAG if RPC_REPLY_END_TAG in \
+                                           rpc_response_last_msg else \
+                    RFC_RPC_REPLY_END_TAG
                 # rpc_response_last_msg and data can be overlapping
                 match_obj = difflib.SequenceMatcher(None, 
rpc_response_last_msg,
                                                     data).get_matching_blocks()
@@ -114,9 +117,7 @@
                             # as first if condition will add full delimiter, 
so clean
                             # it off
                             clean_up = len(rpc_response_last_msg) - (
-                                    rpc_response_last_msg.find(
-                                        self.rpc_tags.RPC_REPLY_END_TAG) +
-                                    self.rpc_tags.RPC_REPLY_END_TAG_LEN)
+                                    rpc_response_last_msg.find(tag) + len(tag))
                             self._session._buffer.truncate(buf.tell() - 
clean_up)
                             self._delimiter_check(data.encode())
                         else:
@@ -193,12 +194,12 @@
         self._session = session
         self._validate_reply_and_sax_tag = False
         self._lock = Lock()
+        self.nc_namespace = None
 
     def startElement(self, tag, attributes):
         if tag in ['rpc-reply', 'nc:rpc-reply']:
             if tag == 'nc:rpc-reply':
-                RPCTags.RPC_REPLY_END_TAG = "</nc:rpc-reply>"
-                RPCTags.RPC_REPLY_START_TAG = "<nc:rpc-reply"
+                self.nc_namespace = BASE_NS_1_0
             # in case last rpc called used sax parsing and error'd out
             # without resetting use_filer in endElement rpc-reply check
             with self._lock:
@@ -222,7 +223,7 @@
         if self._cur == self._root and self._cur.tag == tag:
             node = self._root
         else:
-            node = self._cur.find(tag, namespaces=RPCTags.NAMESPACES)
+            node = self._cur.find(tag, namespaces={"nc": self.nc_namespace})
 
         if self._validate_reply_and_sax_tag:
             if tag != self._root.tag:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/ncclient/xml_.py 
new/ncclient-0.6.9/ncclient/xml_.py
--- old/ncclient-0.6.7/ncclient/xml_.py 2019-12-21 20:16:07.000000000 +0100
+++ new/ncclient-0.6.9/ncclient/xml_.py 2020-08-09 00:09:16.000000000 +0200
@@ -223,11 +223,17 @@
                                        parser=self.__parser)
         return self.__root
 
+def parent_ns(node):
+    if node.prefix:
+        return node.nsmap[node.prefix]
+    return None
+
+new_ele_nsmap = lambda tag, nsmap, attrs={}, **extra: 
etree.Element(qualify(tag), attrs, nsmap, **extra)
 
 new_ele = lambda tag, attrs={}, **extra: etree.Element(qualify(tag), attrs, 
**extra)
 
 new_ele_ns = lambda tag, ns, attrs={}, **extra: etree.Element(qualify(tag,ns), 
attrs, **extra)
 
-sub_ele = lambda parent, tag, attrs={}, **extra: etree.SubElement(parent, 
qualify(tag), attrs, **extra)
+sub_ele = lambda parent, tag, attrs={}, **extra: etree.SubElement(parent, 
qualify(tag, parent_ns(parent)), attrs, **extra)
 
 sub_ele_ns = lambda parent, tag, ns, attrs={}, **extra: 
etree.SubElement(parent, qualify(tag, ns), attrs, **extra)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/setup.py new/ncclient-0.6.9/setup.py
--- old/ncclient-0.6.7/setup.py 2019-12-21 20:16:07.000000000 +0100
+++ new/ncclient-0.6.9/setup.py 2020-08-09 00:09:16.000000000 +0200
@@ -49,7 +49,7 @@
       author=__author__,
       author_email=__author_email__,
       url="https://github.com/ncclient/ncclient";,
-      packages=find_packages('.'),
+      packages=find_packages(exclude=['test', 'test.*']),
       install_requires=install_reqs,
       tests_require=test_reqs,
       license=__licence__,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/test/unit/devices/test_default.py 
new/ncclient-0.6.9/test/unit/devices/test_default.py
--- old/ncclient-0.6.7/test/unit/devices/test_default.py        2019-12-21 
20:16:07.000000000 +0100
+++ new/ncclient-0.6.9/test/unit/devices/test_default.py        2020-08-09 
00:09:16.000000000 +0200
@@ -37,6 +37,24 @@
     def test_handle_connection_exceptions(self):
         self.assertFalse(self.obj.handle_connection_exceptions(None))
 
+    def test_is_rpc_error_exempt_1(self):
+        self.assertFalse(self.obj.is_rpc_error_exempt(None))
+
+    def test_is_rpc_error_exempt_2(self):
+        self.obj._exempt_errors_exact_match = ["test_exempt"]
+        self.assertTrue(self.obj.is_rpc_error_exempt("  Test_Exempt"))
+
+    def test_is_rpc_error_exempt_3(self):
+        self.obj._exempt_errors_startwith_wildcard_match = ["test_exempt"]
+        self.assertTrue(self.obj.is_rpc_error_exempt("*Test_Exempt"))
+
+    def test_is_rpc_error_exempt_4(self):
+        self.obj._exempt_errors_endwith_wildcard_match = ["test_exempt"]
+        self.assertTrue(self.obj.is_rpc_error_exempt("Test_Exempt*"))
+
+    def test_is_rpc_error_exempt_5(self):
+        self.obj._exempt_errors_full_wildcard_match = ["test_exempt"]
+        self.assertTrue(self.obj.is_rpc_error_exempt("*Test_Exempt*"))
 
 suite = unittest.TestSuite()
 unittest.TextTestRunner().run(suite)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ncclient-0.6.7/test/unit/devices/test_get_supported_devices.py 
new/ncclient-0.6.9/test/unit/devices/test_get_supported_devices.py
--- old/ncclient-0.6.7/test/unit/devices/test_get_supported_devices.py  
1970-01-01 01:00:00.000000000 +0100
+++ new/ncclient-0.6.9/test/unit/devices/test_get_supported_devices.py  
2020-08-09 00:09:16.000000000 +0200
@@ -0,0 +1,33 @@
+import unittest
+from ncclient import devices
+
+class  TestGetSupportedDevices(unittest.TestCase):
+
+    def test_get_supported_devices(self):
+        supported_devices = devices.get_supported_devices()
+        self.assertEqual(sorted(supported_devices), sorted(('junos',
+                                                            'csr',
+                                                            'nexus',
+                                                            'iosxr',
+                                                            'iosxe',
+                                                            'huawei',
+                                                            'huaweiyang',
+                                                            'alu',
+                                                            'h3c',
+                                                            'hpcomware',
+                                                            'default')))
+
+    def test_get_supported_device_labels(self):
+        supported_device_labels = devices.get_supported_device_labels()
+        self.assertEqual(supported_device_labels, {'junos':'Juniper',
+                                                   'csr':'Cisco CSR1000v',
+                                                   'nexus':'Cisco Nexus',
+                                                   'iosxr':'Cisco IOS XR',
+                                                   'iosxe':'Cisco IOS XE',
+                                                   'huawei':'Huawei',
+                                                   'huaweiyang':'Huawei',
+                                                   'alu':'Alcatel Lucent',
+                                                   'h3c':'H3C',
+                                                   'hpcomware':'HP Comware',
+                                                   'default':'Server or 
anything not in above'})
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/test/unit/operations/test_edit.py 
new/ncclient-0.6.9/test/unit/operations/test_edit.py
--- old/ncclient-0.6.7/test/unit/operations/test_edit.py        2019-12-21 
20:16:07.000000000 +0100
+++ new/ncclient-0.6.9/test/unit/operations/test_edit.py        2020-08-09 
00:09:16.000000000 +0200
@@ -52,12 +52,16 @@
                 host-name foo-bar;
             }
             """
-        obj.request(copy.deepcopy(root), format="text", target="running", 
error_option="rollback-on-error",
-                    default_operation="default", test_option="test")
+        obj.request(copy.deepcopy(root),
+                    format="text",
+                    target="running",
+                    error_option="rollback-on-error",
+                    default_operation="merge",
+                    test_option="test-then-set")
         node = new_ele("edit-config")
         node.append(util.datastore_or_url("target", "running"))
-        sub_ele(node, "default-operation").text = "default"
-        sub_ele(node, "test-option").text = "test"
+        sub_ele(node, "default-operation").text = "merge"
+        sub_ele(node, "test-option").text = "test-then-set"
         sub_ele(node, "error-option").text = "rollback-on-error"
         config_text = sub_ele(node, "config-text")
         sub_ele(config_text, "configuration-text").text = root
@@ -66,6 +70,63 @@
         call = ElementTree.tostring(call)
         self.assertEqual(call, xml)
 
+    def test_edit_config_invalid_arguments_exception(self):
+        session = ncclient.transport.SSHSession(self.device_handler)
+        session._server_capabilities = [":rollback-on-error", ":validate", 
":validate:1.1"]
+        obj = EditConfig(
+            session,
+            self.device_handler,
+            raise_mode=RaiseMode.ALL)
+        root = """
+            system {
+                host-name foo-bar;
+            }
+            """
+        #invalid argument "default_operation"
+        self.assertRaises(OperationError, obj.request,
+                          copy.deepcopy(root),
+                          format="xml",
+                          target="running",
+                          error_option="stop-on-error",
+                          default_operation="create",
+                          test_option="test-then-set")
+        #invalid argument "error_option"
+        self.assertRaises(OperationError, obj.request,
+                          copy.deepcopy(root),
+                          format="xml",
+                          target="running",
+                          error_option="commit-on-error",
+                          default_operation="merge",
+                          test_option="test-then-set")
+        #invalid argument "test_option"
+        self.assertRaises(OperationError, obj.request,
+                          copy.deepcopy(root),
+                          format="xml",
+                          target="running",
+                          error_option="stop-on-error",
+                          default_operation="merge",
+                          test_option="test")
+
+    def test_edit_config_validate_capability_exception(self):
+        session = ncclient.transport.SSHSession(self.device_handler)
+        session._server_capabilities = [":validate"]
+        obj = EditConfig(
+            session,
+            self.device_handler,
+            raise_mode=RaiseMode.ALL)
+        root = """
+            system {
+                host-name foo-bar;
+            }
+            """
+        self.assertRaises(MissingCapabilityError, obj.request,
+                          copy.deepcopy(root),
+                          format="xml",
+                          target="running",
+                          error_option="stop-on-error",
+                          default_operation="merge",
+                          test_option="test-only")
+
     @patch('ncclient.operations.RPC._request')
     def test_delete_config(self, mock_request):
         session = ncclient.transport.SSHSession(self.device_handler)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/test/unit/operations/test_retrieve.py 
new/ncclient-0.6.9/test/unit/operations/test_retrieve.py
--- old/ncclient-0.6.7/test/unit/operations/test_retrieve.py    2019-12-21 
20:16:07.000000000 +0100
+++ new/ncclient-0.6.9/test/unit/operations/test_retrieve.py    2020-08-09 
00:09:16.000000000 +0200
@@ -220,3 +220,43 @@
         call = mock_request.call_args_list[0][0][0]
         call = ElementTree.tostring(call)
         self.assertEqual(call, xml)
+
+    @patch('ncclient.operations.retrieve.RPC._request')
+    def test_get_with_multi_subtree_filters(self, mock_request):
+        result = '''
+                <?xml version="1.0" encoding="UTF-8"?>
+                <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
+                      xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
+                    <cont1 xmlns="urn:mod1">
+                        <le1>test_mod1_001</le1>
+                        <le2>this is a test-one example</le2>
+                    </cont1>
+                    <cont2 xmlns="urn:mod2">
+                        <le1>test_mod2_002</le1>
+                        <le2>this is a test-two example</le2>
+                        <lst>
+                            <le3>a list of mod2</le3>
+                        </lst>
+                    </cont2>
+                </data>'''
+        mock_request.return_value = result
+        session = ncclient.transport.SSHSession(self.device_handler)
+        obj = Get(session, self.device_handler, raise_mode=RaiseMode.ALL)
+
+        multi_subtree_filters = [
+            '<cont1 xmlns="urn:mod1"> \
+                <le1/> \
+                <le2/> \
+             </cont1>',
+             '<cont2 xmlns="urn:mod2"/>'
+        ]
+
+        ret = obj.request(copy.deepcopy(multi_subtree_filters))
+        node = new_ele("get")
+        node.append(util.build_filter(multi_subtree_filters))
+        xml = ElementTree.tostring(node)
+        call = mock_request.call_args_list[0][0][0]
+        call = ElementTree.tostring(call)
+        self.assertEqual(call, xml)
+        self.assertEqual(ret, result)
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/test/unit/operations/test_rpc.py 
new/ncclient-0.6.9/test/unit/operations/test_rpc.py
--- old/ncclient-0.6.7/test/unit/operations/test_rpc.py 2019-12-21 
20:16:07.000000000 +0100
+++ new/ncclient-0.6.9/test/unit/operations/test_rpc.py 2020-08-09 
00:09:16.000000000 +0200
@@ -89,6 +89,31 @@
 <configuration-text 
xmlns="http://xml.juniper.net/xnm/1.1/xnm";>%s</configuration-text>
 </rpc-reply>""" % escape(huge_configuration_text)
 
+xml6 = """<rpc-error xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+                       <error-type>application</error-type>
+                       <error-tag>invalid-value</error-tag>
+                       <error-severity>error</error-severity>
+                       <error-path>path/to/node</error-path>
+                       <error-info>
+                               <bad-element>system1</bad-element>
+                       </error-info>
+                       <error-app-tag>app-tag1</error-app-tag>
+                       <error-message>syntax error</error-message>
+         </rpc-error>
+"""
+
+xml7 = """<rpc-error xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+                       <error-type>protocol</error-type>
+                       <error-tag>missing-element</error-tag>
+                       <error-severity>error</error-severity>
+                       <error-path>path/to/different/node</error-path>
+                       <error-info>
+                               <bad-element>system2</bad-element>
+                       </error-info>
+                       <error-app-tag>app-tag2</error-app-tag>
+                       <error-message>missing element error</error-message>
+         </rpc-error>
+"""
 
 class TestRPC(unittest.TestCase):
 
@@ -180,6 +205,50 @@
         obj.deliver_error(err)
         self.assertRaises(RPCError, obj._request, node)
 
+    def test_rpc_rpcerror_tag_to_attr(self):
+        '''All elements in <rpc-error> extracted.'''
+        err = RPCError(to_ele(xml6))
+
+        self.assertEqual(None, err.errlist)
+
+        self.assertEqual("application", err.type)
+        self.assertEqual("invalid-value", err.tag)
+        self.assertEqual("error", err.severity)
+        self.assertEqual("path/to/node", err.path)
+        self.assertEqual("app-tag1", err.app_tag)
+        self.assertEqual("syntax error", err.message)
+        self.assertIn("<bad-element>system1</bad-element>", err.info)
+
+    def test_rpc_rpcerror_multiple_errors(self):
+        '''Multiple errors in <rpc-reply> extracted correctly'''
+        errlist = [RPCError(to_ele(xml6)), RPCError(to_ele(xml7))]
+
+        multiple_xml = (
+        '<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">' +
+        xml6 + xml7 +
+        "</rpc-reply>")
+
+        multiple_err = RPCError(to_ele(multiple_xml), errs=errlist)
+        errs = multiple_err.errlist
+
+        self.assertEqual(2, len(errs))
+
+        self.assertEqual("application", errs[0].type)
+        self.assertEqual("invalid-value", errs[0].tag)
+        self.assertEqual("error", errs[0].severity)
+        self.assertEqual("path/to/node", errs[0].path)
+        self.assertEqual("app-tag1", errs[0].app_tag)
+        self.assertEqual("syntax error", errs[0].message)
+        self.assertIn("<bad-element>system1</bad-element>", errs[0].info)
+
+        self.assertEqual("protocol", errs[1].type)
+        self.assertEqual("missing-element", errs[1].tag)
+        self.assertEqual("error", errs[1].severity)
+        self.assertEqual("path/to/different/node", errs[1].path)
+        self.assertEqual("app-tag2", errs[1].app_tag)
+        self.assertEqual("missing element error", errs[1].message)
+        self.assertIn("<bad-element>system2</bad-element>", errs[1].info)
+
     @patch('ncclient.transport.Session.send')
     @patch(patch_str)
     def test_rpc_capability_error(self, mock_thread, mock_send):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/test/unit/operations/test_utils.py 
new/ncclient-0.6.9/test/unit/operations/test_utils.py
--- old/ncclient-0.6.7/test/unit/operations/test_utils.py       2019-12-21 
20:16:07.000000000 +0100
+++ new/ncclient-0.6.9/test/unit/operations/test_utils.py       2020-08-09 
00:09:16.000000000 +0200
@@ -57,7 +57,7 @@
         call = ElementTree.tostring(reply)
         self.assertEqual(call, ElementTree.tostring(to_ele(xml)))
 
-    def test_build_filter_2(self):
+    def test_build_filter_xpath(self):
         criteria = "configuration/system"
         filter = ("xpath", criteria)
         reply = build_filter(filter)
@@ -66,7 +66,18 @@
         node.attrib["select"] = criteria
         self.assertEqual(call, ElementTree.tostring(node))
 
-    def test_build_filter_3(self):
+    def test_build_filter_xpath_ns(self):
+        select = "configuration/system"
+        ns = {"ns0": "http://www.xxx.org"}
+        criteria = (ns, select)
+        filter = ("xpath", criteria)
+        reply = build_filter(filter)
+        call = ElementTree.tostring(reply)
+        node = new_ele_nsmap("filter", ns, type="xpath")
+        node.attrib["select"] = select
+        self.assertEqual(call, ElementTree.tostring(node))
+
+    def test_build_filter_subtree(self):
         criteria =  """<configuration>
             <system>
                 <services/>
@@ -79,7 +90,7 @@
         node.append(to_ele(criteria))
         self.assertEqual(call, ElementTree.tostring(node))
 
-    def test_build_filter_4(self):
+    def test_build_filter_other(self):
         criteria =  """<configuration>
             <system>
                 <services/>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/test/unit/test_manager.py 
new/ncclient-0.6.9/test/unit/test_manager.py
--- old/ncclient-0.6.7/test/unit/test_manager.py        2019-12-21 
20:16:07.000000000 +0100
+++ new/ncclient-0.6.9/test/unit/test_manager.py        2020-08-09 
00:09:16.000000000 +0200
@@ -26,6 +26,60 @@
         manager.connect(host='host')
         mock_ssh.assert_called_once_with(host='host')
 
+    @patch('ncclient.transport.SSHSession.load_known_hosts')
+    @patch('ncclient.transport.SSHSession.connect')
+    def test_connect_ssh1(self, mock_ssh, mock_load_known_hosts):
+        manager.connect(host='host')
+        mock_ssh.assert_called_once_with(host='host')
+        mock_load_known_hosts.assert_called_once_with()
+
+    @patch('ncclient.transport.SSHSession.connect')
+    @patch('ncclient.transport.SSHSession.transport')
+    @patch('ncclient.transport.SSHSession.close')
+    def test_connect_exception(self, mock_close, mock_transport, mock_ssh):
+        mock_ssh.side_effect = Exception
+        try:
+            manager.connect(host='host')
+        except Exception:
+            Exception("connect occured exception")
+        mock_ssh.assert_called_once_with(host='host')
+
+    @patch('ncclient.transport.SSHSession.connect')
+    @patch('ncclient.transport.SSHSession.take_notification')
+    def test_manager_take_notification(self, mock_take_notification, mock_ssh):
+        mock_take_notification.return_value = "test_take_notification"
+        conn = self._mock_manager()
+        ret = conn.take_notification()
+        mock_take_notification.assert_called_once_with(True, None)
+        self.assertEqual(ret, "test_take_notification")
+
+    @patch('ncclient.transport.SSHSession.connect')
+    @patch('ncclient.operations.retrieve.GetConfig._request')
+    def test_manager_getattr(self, mock_request, mock_ssh):
+        conn = self._mock_manager()
+        conn.get_config("running")
+        mock_ssh.assert_called_once_with(host='10.10.10.10',
+                                         port=22,
+                                         username='user',
+                                         password='password',
+                                         timeout=3,
+                                         hostkey_verify=False,
+                                         allow_agent=False)
+
+    @patch('ncclient.transport.SSHSession.connect')
+    
@patch('ncclient.operations.third_party.juniper.rpc.GetConfiguration._request')
+    @patch('ncclient.operations.third_party.juniper.rpc.ExecuteRpc._request')
+    def test_manager_getattr2(self, mock_rpc, mock_request, mock_ssh):
+        conn = self._mock_manager()
+        conn.get_edit('config')
+        mock_ssh.assert_called_once_with(host='10.10.10.10',
+                                         port=22,
+                                         username='user',
+                                         password='password',
+                                         timeout=3,
+                                         hostkey_verify=False,
+                                         allow_agent=False)
+
     @patch('ncclient.manager.connect_ssh')
     def test_connect_ssh_with_hostkey_ed25519(self, mock_ssh):
         hostkey = 
'AAAAC3NzaC1lZDI1NTE5AAAAIIiHpGSf8fla6tCwLpwshvMGmUK+B/0v5CsRu+5v4uT7'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/test/unit/test_xml_.py 
new/ncclient-0.6.9/test/unit/test_xml_.py
--- old/ncclient-0.6.7/test/unit/test_xml_.py   2019-12-21 20:16:07.000000000 
+0100
+++ new/ncclient-0.6.9/test/unit/test_xml_.py   2020-08-09 00:09:16.000000000 
+0200
@@ -176,3 +176,16 @@
         result_xml = result.data_xml
         self.assertRaises(XMLError,
             validated_element, result_xml, tags=["rpc"])
+
+    def test_sub_ele_inherit_parent_namespace(self):
+        device_params = {'name': 'junos'}
+        device_handler = manager.make_device_handler(device_params)
+        transform_reply = device_handler.transform_reply()
+        result = NCElement(self.reply, transform_reply)
+        ele = new_ele_ns(result.find("./cli").tag, "http://www.xxx.org";)
+        child = sub_ele(ele, "child")
+        sibling = sub_ele(ele, "sibling")
+        grandchild = sub_ele(child, "grandchild")
+        self.assertEqual(child.tag, "{http://www.xxx.org}child";)
+        self.assertEqual(sibling.tag, "{http://www.xxx.org}sibling";)
+        self.assertEqual(grandchild.tag, "{http://www.xxx.org}grandchild";)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/test/unit/transport/test_session.py 
new/ncclient-0.6.9/test/unit/transport/test_session.py
--- old/ncclient-0.6.7/test/unit/transport/test_session.py      2019-12-21 
20:16:07.000000000 +0100
+++ new/ncclient-0.6.9/test/unit/transport/test_session.py      2020-08-09 
00:09:16.000000000 +0200
@@ -76,6 +76,26 @@
         self.assertNotEqual(
             mock_log.call_args_list[0][0][0].find("error parsing dispatch 
message"), -1)
 
+    @patch('ncclient.transport.session.parse_root')
+    @patch('ncclient.devices.junos.JunosDeviceHandler.handle_raw_dispatch')
+    @patch('ncclient.transport.session.HelloHandler.errback')
+    @patch('ncclient.logging_.SessionLoggerAdapter.debug')
+    def test_dispatch_message_error2(self, mock_log, mock_errback,
+                                     mock_handle_raw_dispatch, 
mock_parse_root):
+        mock_parse_root.side_effect = Exception
+        mock_handle_raw_dispatch.return_value = Exception()
+        mock_errback.side_effect = Exception
+        cap = [':candidate']
+        obj = Session(cap)
+        device_handler = JunosDeviceHandler({'name': 'junos'})
+        obj._device_handler = device_handler
+        listener = HelloHandler(None, None)
+        obj._listeners.add(listener)
+        obj._dispatch_message(rpc_reply)
+        mock_handle_raw_dispatch.assert_called_once_with(rpc_reply)
+        self.assertEqual(
+            mock_log.call_args_list[0][0][0].find("error dispatching to"), -1)
+
     @patch('ncclient.transport.session.HelloHandler.errback')
     def test_dispatch_error(self, mock_handler):
         cap = [':candidate']
@@ -105,6 +125,26 @@
             log_args[0].find("server_capabilities="), -1)
         self.assertEqual(log_args[2], [':candidate'])
 
+    @patch('ncclient.logging_.SessionLoggerAdapter.info')
+    @patch('ncclient.transport.session.Thread.start')
+    @patch('ncclient.transport.session.Event')
+    def test_post_connect2(self, mock_lock, mock_handler, mock_log):
+        cap = ['urn:ietf:params:netconf:base:1.1']
+        obj = Session(cap)
+        device_handler = JunosDeviceHandler({'name': 'junos'})
+        obj._device_handler = device_handler
+        obj._connected = True
+        obj._id = 100
+        obj._server_capabilities = cap
+        obj._post_connect()
+        log_args = mock_log.call_args_list[0][0]
+        self.assertNotEqual(log_args[0].find("initialized"), -1)
+        self.assertNotEqual(log_args[0].find("session-id="), -1)
+        self.assertEqual(log_args[1], 100)
+        self.assertNotEqual(
+            log_args[0].find("server_capabilities="), -1)
+        self.assertEqual(log_args[2], ['urn:ietf:params:netconf:base:1.1'])
+
     def test_add_listener(self):
         cap = [':candidate']
         obj = Session(cap)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ncclient-0.6.7/test/unit/transport/test_ssh.py 
new/ncclient-0.6.9/test/unit/transport/test_ssh.py
--- old/ncclient-0.6.7/test/unit/transport/test_ssh.py  2019-12-21 
20:16:07.000000000 +0100
+++ new/ncclient-0.6.9/test/unit/transport/test_ssh.py  2020-08-09 
00:09:16.000000000 +0200
@@ -267,6 +267,16 @@
         obj.load_known_hosts()
         mock_load.assert_called_once_with("file_name")
 
+    @patch('os.path.expanduser')
+    @patch('paramiko.hostkeys.HostKeys.load')
+    def test_load_host_key_IOError(self, mock_load, mock_os):
+        mock_os.return_value = "file_name"
+        mock_load.side_effect = IOError
+        device_handler = JunosDeviceHandler({'name': 'junos'})
+        obj = SSHSession(device_handler)
+        obj.load_known_hosts()
+        mock_load.assert_called_with("file_name")
+
     @unittest.skipIf(sys.version_info.major == 2, "test not supported < 
Python3")
     @patch('ncclient.transport.ssh.SSHSession.close')
     @patch('paramiko.channel.Channel.recv')


Reply via email to