Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-ciscoconfparse for 
openSUSE:Factory checked in at 2023-01-04 17:53:34
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-ciscoconfparse (Old)
 and      /work/SRC/openSUSE:Factory/.python-ciscoconfparse.new.1563 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-ciscoconfparse"

Wed Jan  4 17:53:34 2023 rev:28 rq:1055824 version:1.7.0

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-ciscoconfparse/python-ciscoconfparse.changes  
    2022-12-08 16:52:23.899855826 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-ciscoconfparse.new.1563/python-ciscoconfparse.changes
    2023-01-04 17:53:50.858621871 +0100
@@ -1,0 +2,10 @@
+Wed Jan  4 14:04:22 UTC 2023 - Dirk Müller <dmuel...@suse.com>
+
+- update to 1.7.0:
+  * Add deprecat dependency
+  * Add more Makefile targets
+  * Makefile will successfully ping to internet or fail
+  * Update Makefile to delete poetry.lock file
+  * Correct 'make ping' logic and other tricky Makefile syntax
+
+-------------------------------------------------------------------

Old:
----
  ciscoconfparse-1.6.53.tar.gz

New:
----
  ciscoconfparse-1.7.0.tar.gz

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

Other differences:
------------------
++++++ python-ciscoconfparse.spec ++++++
--- /var/tmp/diff_new_pack.02GLkX/_old  2023-01-04 17:53:51.318624582 +0100
+++ /var/tmp/diff_new_pack.02GLkX/_new  2023-01-04 17:53:51.334624677 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-ciscoconfparse
 #
-# Copyright (c) 2022 SUSE LLC
+# Copyright (c) 2023 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -19,7 +19,7 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %bcond_without python2
 Name:           python-ciscoconfparse
-Version:        1.6.53
+Version:        1.7.0
 Release:        0
 Summary:        Library for parsing, querying and modifying Cisco IOS-style 
configurations
 License:        GPL-3.0-or-later

++++++ ciscoconfparse-1.6.53.tar.gz -> ciscoconfparse-1.7.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ciscoconfparse-1.6.53/CHANGES.md 
new/ciscoconfparse-1.7.0/CHANGES.md
--- old/ciscoconfparse-1.6.53/CHANGES.md        2022-11-09 20:24:50.707943000 
+0100
+++ new/ciscoconfparse-1.7.0/CHANGES.md 2023-01-02 15:07:57.459834600 +0100
@@ -2,15 +2,36 @@
 
 - Released: Not released
 - Summary:
+    - Insert something here
+
+## Version: 1.7.1
+
+- Released: 2023-01-02
+- Summary:
+    - Add deprecat dependency
+    - Add more Makefile targets
+    - Makefile will successfully ping to internet or fail
+    - Update Makefile to delete poetry.lock file
+    - Correct 'make ping' logic and other tricky Makefile syntax
+
+## Version: 1.7.0
+
+- Released: 2023-01-02
+- Summary:
+    - Add deprecat dependency
+    - Add more Makefile targets
+    - Makefile will successfully ping to internet or fail
     - Update Makefile to delete poetry.lock file
+    - Correct 'make ping' logic and other tricky Makefile syntax
 
 
 ## Version: 1.6.53
 
-- Released: 2022-11-09
+- Released: 2022-11-18
 - Summary:
     - Reformat pyproject.toml to be most compatible with 'pip install'
     - Several internal project-level optimizations...
+    - git changes committed on 2022-11-09... somehow 1.6.53 wasn't pushed to 
pypi on 9-Nov-2022.  It was pushed to pypi on 18-Nov-2022
 
 ## Version: 1.6.52
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ciscoconfparse-1.6.53/Makefile 
new/ciscoconfparse-1.7.0/Makefile
--- old/ciscoconfparse-1.6.53/Makefile  2022-11-18 12:15:49.277552400 +0100
+++ new/ciscoconfparse-1.7.0/Makefile   2023-01-02 15:56:14.612502800 +0100
@@ -1,7 +1,20 @@
 DOCHOST ?= $(shell bash -c 'read -p "documentation host: " dochost; echo 
$$dochost')
 # VERSION detection:
 #    Ref -> https://stackoverflow.com/a/71592061/667301
-VERSION := $(shell grep version pyproject.toml | tr -s ' ' | tr -d "'" | tr -d 
'"' | cut -d' ' -f3)
+export VERSION := $(shell grep version pyproject.toml | tr -s ' ' | tr -d "'" 
| tr -d '"' | cut -d' ' -f3)
+
+# We MUST escape Makefile dollar signs as $$foo
+export PING_OUTPUT := $(shell perl -e '@output = qx/ping -q -W0.5 -c1 
4.2.2.2/; $$alloutput = join "", @output; if ( $$alloutput =~ /\s0\sreceived/ ) 
{ print "failure"; } else { print "success"; }')
+
+export NUMBER_OF_CCP_TESTS := $(shell grep "def " tests/test*py | wc -l)
+
+# Makefile color codes...
+#     ref -> https://stackoverflow.com/a/5947802/667301
+COL_GREEN=\033[0;32m
+COL_CYAN=\033[0;36m
+COL_YELLOW=\033[0;33m
+COL_RED=\033[0;31m
+COL_END=\033[0;0m
 
 .DEFAULT_GOAL := test
 
@@ -9,7 +22,7 @@
 # Ref -> 
https://packaging.python.org/en/latest/guides/making-a-pypi-friendly-readme/
 .PHONY: pypi-packaging
 pypi-packaging:
-       @echo ">> building ciscoconfparse pypi artifacts (wheel and tar.gz)"
+       @echo "$(COL_GREEN)>> building ciscoconfparse pypi artifacts (wheel and 
tar.gz)$(COL_END)"
        pip install -U setuptools>=58.0.0
        pip install -U wheel>=0.37.1
        pip install -U twine>=4.0.1
@@ -19,7 +32,7 @@
 
 .PHONY: pypi
 pypi:
-       @echo ">> uploading ciscoconfparse pypi artifacts to pypi"
+       @echo "$(COL_CYAN)>> uploading ciscoconfparse pypi artifacts to 
pypi$(COL_END)"
        make clean
        make pypi-packaging
        poetry lock --no-update
@@ -27,6 +40,9 @@
        # twine is the simplest pypi package uploader...
        python -m twine upload dist/*
 
+.PHONY: readme
+readme:
+
 .PHONY: bump-version-patch
 bump-version-patch:
        $(shell python dev_tools/git_helper.py -I patch)
@@ -35,45 +51,51 @@
 bump-version-minor:
        $(shell python dev_tools/git_helper.py -I minor)
 
+
 .PHONY: repo-push
 repo-push:
-       @echo ">> git push (w/o force) ciscoconfparse local main branch to 
github"
-       #git remote remove origin
-       #git remote add origin "g...@github.com:mpenning/ciscoconfparse"
-       #git push g...@github.com:mpenning/ciscoconfparse.git
-       #git push origin +main
-       $(shell python dev_tools/git_helper.py -P ciscoconfparse --push)
+       @echo "$(COL_GREEN)>> git push and merge (w/o force) to ciscoconfparse 
main branch to github$(COL_END)"
+       make ping
+       -git checkout master || git checkout main # Add dash to ignore checkout 
fails
+       # Now the main branch is checked out...
+       THIS_BRANCH=$(shell git branch --show-current)  # assign 'main' to 
$THIS_BRANCH
+       git merge @{-1}                           # merge the previous branch 
into main...
+       git push origin $(THIS_BRANCH)            # git push to origin / 
$THIS_BRANCH
+       git checkout @{-1}                        # checkout the previous 
branch...
+
 
 .PHONY: repo-push-force
 repo-push-force:
-       @echo ">> git push (w/ force) ciscoconfparse local main branch to 
github"
-       #git remote remove origin
-       #git remote add origin "g...@github.com:mpenning/ciscoconfparse"
-       #git push --force-with-lease g...@github.com:mpenning/ciscoconfparse.git
-       #git push --force-with-lease origin +main
-       $(shell python dev_tools/git_helper.py -P ciscoconfparse --push --force)
+       @echo "$(COL_GREEN)>> git push and merge (w/ force) ciscoconfparse 
local main branch to github$(COL_END)"
+       make ping
+       -git checkout master || git checkout main # Add dash to ignore checkout 
fails
+       # Now the main branch is checked out...
+       THIS_BRANCH=$(shell git branch --show-current)  # assign 'main' to 
$THIS_BRANCH
+       git merge @{-1}                           # merge the previous branch 
into main...
+       git push --force-with-lease origin $(THIS_BRANCH)    # force push to 
origin / $THIS_BRANCH
+       git checkout @{-1}                        # checkout the previous 
branch...
 
 .PHONY: repo-push-tag
 repo-push-tag:
-       @echo ">> git push (w/ local tag) ciscoconfparse local main branch to 
github"
-       #make repo-push
-       $(shell python dev_tools/git_helper.py -P ciscoconfparse --push --tag)
+       @echo "$(COL_GREEN)>> git push (w/ local tag) ciscoconfparse local main 
branch to github$(COL_END)"
+       git push origin +main
+       git push --tags origin +main
 
 .PHONY: repo-push-tag-force
 repo-push-tag-force:
-       @echo ">> git push (w/ local tag and w/ force) ciscoconfparse local 
main branch to github"
-       #make repo-push-force
-       $(shell python dev_tools/git_helper.py -P ciscoconfparse --push --tag 
--force)
+       @echo "$(COL_GREEN)>> git push (w/ local tag and w/ force) 
ciscoconfparse local main branch to github$(COL_END)"
+       git push --force-with-lease origin +main
+       git push --force-with-lease --tags origin +main
 
 .PHONY: pylama
 pylama:
-       @echo ">> running pylama against ciscoconfparse"
+       @echo "$(COL_GREEN)>> running pylama against ciscoconfparse$(COL_END)"
        # Good usability info here -> https://pythonspeed.com/articles/pylint/
        pylama --ignore=E501,E301,E265,E266 ciscoconfparse/*py | less -XR
 
 .PHONY: pylint
 pylint:
-       @echo ">> running pylint against ciscoconfparse"
+       @echo "$(COL_GREEN)>> running pylint against ciscoconfparse$(COL_END)"
        # Good usability info here -> https://pythonspeed.com/articles/pylint/
        pylint --rcfile=./utils/pylintrc 
--ignore-patterns='^build|^dist|utils/pylintrc|README.rst|CHANGES|LICENSE|MANIFEST.in|Makefile|TODO'
 --output-format=colorized * | less -XR
 
@@ -118,24 +140,24 @@
 
 .PHONY: pip
 pip:
-       @echo ">> Upgrading pip to the latest version"
-       pip install -U pip
+       @echo "$(COL_GREEN)>> Upgrading pip to the latest version$(COL_END)"
+       make ping
+       pip install -U pip>=22.2.0
 
 .PHONY: dep
 dep:
-       @echo ">> installing all ciscoconfparse prod dependencies"
-       make pip
-       pip install -U pip>=22.2.0
-       pip install -U dnspython==2.1.0 # Previously version 1.14.0
+       @echo "$(COL_GREEN)>> installing all ciscoconfparse prod 
dependencies$(COL_END)"
+       pip install -U dnspython==1.15.0 # Previously version 1.14.0
        pip install -U passlib==1.7.4
        pip install -U loguru==0.6.0
        pip install -U toml>=0.10.2
+       pip install -U deprecat>=2.1.1
 
 .PHONY: dev
 dev:
-       @echo ">> installing all prod and development ciscoconfparse 
dependencies"
+       @echo "$(COL_GREEN)>> installing all prod and development 
ciscoconfparse dependencies$(COL_END)"
+       make pip
        make dep
-       pip install -U pip>=22.2.0
        pip install -U virtualenv
        pip install -U virtualenvwrapper>=4.8.0
        pip install -U pss
@@ -156,14 +178,35 @@
        pip install -U invoke>=1.7.0
        pip install -U ipaddr>=2.2.0
 
+.PHONY: rm-timestamp
+rm-timestamp:
+       @echo "$(COL_GREEN)>> delete .pip_dependency if older than a 
day$(COL_END)"
+       #delete .pip_dependency if older than a day
+       $(shell find .pip_dependency -mtime +1 -exec rm {} \;)
+
+.PHONY: timestamp
+timestamp:
+       @echo "$(COL_GREEN)>> delete .pip_dependency if older than a 
day$(COL_END)"
+       $(shell touch .pip_dependency)
+
+.PHONY: ping
+ping:
+       @echo "$(COL_GREEN)>> ping to ensure internet connectivity$(COL_END)"
+       @if [ "$${PING_OUTPUT}" = 'success' ]; then return 0; else return 1; fi
 
 .PHONY: test
 test:
+       @echo "$(COL_GREEN)>> running unit tests$(COL_END)"
+       $(shell touch .pip_dependency)
+       make timestamp
+       make dep
+       #make ping
        make clean
        cd tests && ./runtests.sh
 
 .PHONY: clean
 clean:
+       @echo "$(COL_GREEN)>> cleaning the repo$(COL_END)"
        # Delete bogus files... see https://stackoverflow.com/a/73992288/667301
        perl -e 'unlink( grep { /^=\d*\.*\d*/ && !-d } glob( "*" ) );'
        find ./* -name '*.pyc' -exec rm {} \;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ciscoconfparse-1.6.53/PKG-INFO 
new/ciscoconfparse-1.7.0/PKG-INFO
--- old/ciscoconfparse-1.6.53/PKG-INFO  1970-01-01 01:00:00.000000000 +0100
+++ new/ciscoconfparse-1.7.0/PKG-INFO   1970-01-01 01:00:00.000000000 +0100
@@ -1,7 +1,7 @@
 Metadata-Version: 2.1
 Name: ciscoconfparse
-Version: 1.6.53
-Summary: Parse, Audit, Query, Build, and Modify Cisco IOS-style and 
JunOS-style configurations
+Version: 1.7.0
+Summary: Parse, Audit, Query, Build, and Modify Cisco IOS-style and 
JunOS-style configs
 License: GPL-3.0-only
 Keywords: Parse,audit,query,modify,Cisco IOS,Cisco,NXOS,ASA,Juniper
 Author: Mike Pennington
@@ -29,6 +29,7 @@
 Classifier: Topic :: System :: Networking :: Monitoring
 Requires-Dist: Sphinx (==4.3.0)
 Requires-Dist: black (>=20.8b1)
+Requires-Dist: deprecat (>=2.1.1)
 Requires-Dist: dnspython (>=2.1.0,<3.0.0)
 Requires-Dist: loguru (==0.6.0)
 Requires-Dist: packaging (>21.0)
@@ -52,7 +53,7 @@
 ciscoconfparse
 ==============
 
-[![Github unittest workflow][4]][5] [![Code Health][37]][38] 
[![Version][2]][3] [![Downloads][6]][7] [![License][8]][9]
+[![Github unittest workflow][4]][5] [![Code Health][37]][38] [![git 
commits][41]][42] [![Repo Code Grade][43]][44]  [![Version][2]][3] 
[![Downloads][6]][7] [![License][8]][9]
 
 
 Introduction: What is ciscoconfparse?
@@ -180,6 +181,11 @@
         cd ciscoconfparse/
         python -m pip install .
 
+Github Star History
+-------------------
+
+[![Github Star History Chart][40]][40]
+
 Other Resources
 ---------------
 
@@ -265,4 +271,9 @@
   [37]: https://snyk.io/advisor/python/ciscoconfparse/badge.svg
   [38]: https://snyk.io/advisor/python/ciscoconfparse
   [39]: https://www.reddit.com/r/Python/
+  [40]: 
https://api.star-history.com/svg?repos=mpenning/ciscoconfparse&type=Date
+  [41]: https://img.shields.io/github/commit-activity/m/mpenning/ciscoconfparse
+  [42]: https://img.shields.io/github/commit-activity/m/mpenning/ciscoconfparse
+  [43]: https://www.codefactor.io/Content/badges/B.svg
+  [44]: https://www.codefactor.io/repository/github/mpenning/ciscoconfparse/
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ciscoconfparse-1.6.53/README.md 
new/ciscoconfparse-1.7.0/README.md
--- old/ciscoconfparse-1.6.53/README.md 2022-10-22 22:21:23.743468000 +0200
+++ new/ciscoconfparse-1.7.0/README.md  2022-12-17 12:00:56.507440600 +0100
@@ -1,7 +1,7 @@
 ciscoconfparse
 ==============
 
-[![Github unittest workflow][4]][5] [![Code Health][37]][38] 
[![Version][2]][3] [![Downloads][6]][7] [![License][8]][9]
+[![Github unittest workflow][4]][5] [![Code Health][37]][38] [![git 
commits][41]][42] [![Repo Code Grade][43]][44]  [![Version][2]][3] 
[![Downloads][6]][7] [![License][8]][9]
 
 
 Introduction: What is ciscoconfparse?
@@ -129,6 +129,11 @@
         cd ciscoconfparse/
         python -m pip install .
 
+Github Star History
+-------------------
+
+[![Github Star History Chart][40]][40]
+
 Other Resources
 ---------------
 
@@ -214,3 +219,8 @@
   [37]: https://snyk.io/advisor/python/ciscoconfparse/badge.svg
   [38]: https://snyk.io/advisor/python/ciscoconfparse
   [39]: https://www.reddit.com/r/Python/
+  [40]: 
https://api.star-history.com/svg?repos=mpenning/ciscoconfparse&type=Date
+  [41]: https://img.shields.io/github/commit-activity/m/mpenning/ciscoconfparse
+  [42]: https://img.shields.io/github/commit-activity/m/mpenning/ciscoconfparse
+  [43]: https://www.codefactor.io/Content/badges/B.svg
+  [44]: https://www.codefactor.io/repository/github/mpenning/ciscoconfparse/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ciscoconfparse-1.6.53/ciscoconfparse/ccp_util.py 
new/ciscoconfparse-1.7.0/ciscoconfparse/ccp_util.py
--- old/ciscoconfparse-1.6.53/ciscoconfparse/ccp_util.py        2022-10-22 
22:21:23.743468000 +0200
+++ new/ciscoconfparse-1.7.0/ciscoconfparse/ccp_util.py 2023-01-02 
16:14:56.554239700 +0100
@@ -40,6 +40,8 @@
 from dns.resolver import Resolver
 from dns import reversename, query, zone
 
+from deprecat import deprecat
+
 from loguru import logger
 
 from ciscoconfparse.protocol_values import ASA_TCP_PORTS, ASA_UDP_PORTS
@@ -855,6 +857,7 @@
         else:
             raise ValueError("type(%s) is not supported" % arg)
 
+
         if isinstance(arg, str):
             # Removing string length checks in 1.6.29... there are too many
             #    options such as IPv4Obj("111.111.111.111      
255.255.255.255")
@@ -1191,10 +1194,7 @@
         """
         Fix github issue #203... build a `_prefixlen` attribute...
         """
-        if self.version == 4:
-            return IPV4_MAX_PREFIXLEN
-        else:
-            return IPV6_MAX_PREFIXLEN
+        return IPV4_MAX_PREFIXLEN
 
     # do NOT wrap with @logger.catch(...)
     # On IPv4Obj()
@@ -1625,7 +1625,10 @@
             except Exception as ee:
                 masklen = IPV6_MAX_PREFIXLEN
 
-            netmask_int = 2**(128 - masklen) - 1
+            assert isinstance(masklen, int) and masklen <= 128
+            # If we have to derive the netmask as a long hex string,
+            # calculate the netmask from the masklen as follows...
+            netmask_int = (2**128 - 1) - (2**(128 - masklen) - 1)
             netmask = str(IPv6Address(netmask_int))
 
         elif isinstance(arg, int):
@@ -1637,7 +1640,7 @@
         elif isinstance(arg, IPv6Obj):
             addr = str(arg.ip)
             netmask = str(arg.netmask)
-            masklen = arg.masklen
+            masklen = int(arg.masklen)
 
         else:
             raise AddressValueError("IPv6Obj(arg='%s')" % (arg))
@@ -1883,10 +1886,7 @@
         """
         Fix github issue #203... build a `_prefixlen` attribute...
         """
-        if self.version == 4:
-            return IPV4_MAX_PREFIXLEN
-        else:
-            return IPV6_MAX_PREFIXLEN
+        return IPV6_MAX_PREFIXLEN
 
     # On IPv6Obj()
     @property
@@ -2331,7 +2331,7 @@
     start = time.time()
     if (query_type == "A") or (query_type == "AAAA"):
         try:
-            answer = rr.query(input_str, query_type)
+            answer = query(input_str, query_type)
             duration = time.time() - start
             for result in answer:
                 response = DNSResponse(
@@ -2477,14 +2477,21 @@
 
 
 @logger.catch(reraise=True)
+@deprecat(reason="dns_lookup() is obsolete; use dns_query() instead.  
dns_lookup() will be removed", version = '1.7.0')
 def dns_lookup(input_str, timeout=3, server="", record_type="A"):
     """Perform a simple DNS lookup, return results in a dictionary"""
+    assert isinstance(input_str, str)
+    assert isinstance(timeout, int)
+    assert isinstance(server, str)
+    assert isinstance(record_type, str)
+
     rr = Resolver()
     rr.timeout = float(timeout)
     rr.lifetime = float(timeout)
-    if server:
+    if server != "":
         rr.nameservers = [server]
-    dns_session = rr.resolve(input_str, record_type)
+    #dns_session = rr.resolve(input_str, record_type)
+    dns_session = rr.query(input_str, record_type)
     responses = list()
     for rdata in dns_session:
         responses.append(str(rdata))
@@ -2517,6 +2524,7 @@
 
 
 @logger.catch(reraise=True)
+@deprecat(reason="dns6_lookup() is obsolete; use dns_query() instead.  
dns6_lookup() will be removed", version = '1.7.0')
 def dns6_lookup(input_str, timeout=3, server=""):
     """Perform a simple DNS lookup, return results in a dictionary"""
     rr = Resolver()
@@ -2571,6 +2579,7 @@
     return (input_addr, ipaddr_family)
 
 @logger.catch(reraise=True)
+@deprecat(reason="reverse_dns_lookup() is obsolete; use dns_query() instead.  
reverse_dns_lookup() will be removed", version = '1.7.0')
 def reverse_dns_lookup(input_str, timeout=3.0, server="4.2.2.2", proto="udp"):
     """Perform a simple reverse DNS lookup on an IPv4 or IPv6 address; return 
results in a python dictionary"""
     assert isinstance(proto, str) and (proto=="udp" or proto=="tcp")
@@ -2587,35 +2596,16 @@
     else:
         raise ValueError()
 
-    rr = Resolver()
-    rr.nameservers = []
-
-    # Append valid addresses to rr.nameservers...
-    for candidate_server_addr in server.split(","):
-        addr, addr_family = 
check_valid_ipaddress(input_addr=candidate_server_addr)
-        rr.nameservers.append(addr)
-
-    #rr = rr.resolve_address(ipaddr=input_str, tcp=tcp_flag, rdtype="PTR", 
lifetime=float(timeout))
-    #rr = rr.resolve_address(ipaddr=input_str, tcp=tcp_flag, 
lifetime=float(timeout))
-
-    records = []
-    retval = {}
-    try:
-        records = rr.resolve_address(ipaddr=input_str, tcp=tcp_flag, 
lifetime=float(timeout))
-        retval = {
-            "name": records[0].to_text(), # this key was called "addrs"
-            "lookup": input_str,
-            "error": "",
-            "addrs": [input_str],
-        }
-    except DNSException as e:
-        retval = {
-            "name": "",   # this key was called "addrs"
-            "lookup": input_str,
-            "error": repr(e),
-            "addrs": [input_str],
-        }
+    raw_result = dns_query(input_str, query_type="PTR", server=server, 
timeout=timeout)
+    assert isinstance(raw_result, set)
+    assert len(raw_result)>=1
+    tmp = raw_result.pop()
+    assert isinstance(tmp, DNSResponse)
 
+    if tmp.has_error is True:
+        retval = {'addrs': [input_str], 'error': str(tmp.error_str), 'name': 
tmp.result_str}
+    else:
+        retval = {'addrs': [input_str], 'error': '', 'name': tmp.result_str}
     return retval
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ciscoconfparse-1.6.53/ciscoconfparse/ciscoconfparse.py 
new/ciscoconfparse-1.7.0/ciscoconfparse/ciscoconfparse.py
--- old/ciscoconfparse-1.6.53/ciscoconfparse/ciscoconfparse.py  2022-11-09 
16:20:29.818929000 +0100
+++ new/ciscoconfparse-1.7.0/ciscoconfparse/ciscoconfparse.py   2022-12-12 
22:59:40.827519700 +0100
@@ -83,6 +83,7 @@
 # Not using ccp_re yet... still a work in progress
 # from ciscoconfparse.ccp_util import ccp_re
 
+from deprecat import deprecat
 from loguru import logger
 import toml
 
@@ -437,6 +438,8 @@
         encoding : str
             A string holding the coding type.  Default is 
`locale.getpreferredencoding()`
 
+
+
         Returns
         -------
         :class:`~ciscoconfparse.CiscoConfParse`
@@ -503,7 +506,9 @@
 
         assert self.syntax in ALL_VALID_SYNTAX
 
+        # Read the configuration lines and detect invalid inputs...
         config = self.get_config_lines(config=config, logger=logger)
+
         valid_syntax = copy.copy(set(ALL_VALID_SYNTAX))
 
         # add exceptions for brace-delimited syntax...
@@ -589,38 +594,54 @@
     @logger.catch(reraise=True)
     def get_config_lines(self, config=None, logger=None, 
linesplit_rgx=r"\r*\n+"):
         """
-        Enforce rules - If config is a str, assume it's a filepath.  If config 
is a list, assume it's a router config.
+        If the config parameter is a str, assume it's a filepath and read the 
config.  If the config parameter is a list, assume it's a list of text config 
commands.  Return the list of text configuration commands or raise an error.
         """
         config_lines = None
 
-        # config string - assume a filename... open file return lines...
-        if self.debug > 0:
-            logger.debug("parsing config from '%s'" % config)
+        if config is None:
+            raise ValueError("config='%s' is unsupported.  `config` must be 
either a python string, patlib.Path, or list" % config)
 
-        try:
-            assert isinstance(config, (str, pathlib.Path,))
-            assert os.path.isfile(config) is True
-            with open(config, **self.openargs) as fh:
-                text = fh.read()
-            rgx = re.compile(linesplit_rgx)
-            config_lines = rgx.split(text)
+        elif isinstance(config, list) or isinstance(config, Iterator):
+            # Here we assume that `config` is a list of text config lines...
+            #
+            # config list of text lines...
+            assert len(config) > 0, "FATAL - there is no configuration stored 
in the list()"
+            if self.debug > 0:
+                logger.debug("parsing config stored in this list: '%s'" % 
config)
+            config_lines = config
             return config_lines
 
-        except (OSError or FileNotFoundError):
-            error = "CiscoConfParse could not open() the filepath '%s'" % 
config
-            logger.critical(error)
-            raise OSError
-
-        except AssertionError:
-            # Allow list / iterator config to fall through the next logic below
-            pass
+        elif isinstance(config, (str, pathlib.Path,)) and 
os.path.isfile(config) is True:
 
-        if isinstance(config, (Iterator, list,)):
-            config_lines = config
-            return config_lines
+            # config string - assume a filename... open file return lines...
+            if self.debug > 0:
+                logger.debug("parsing config from the filepath named '%s'" % 
config)
+
+            try:
+                with open(file=config, **self.openargs) as fh:
+                    text = fh.read()
+                rgx = re.compile(linesplit_rgx)
+                config_lines = rgx.split(text)
+                return config_lines
+
+            except OSError:
+                error = "CiscoConfParse could not open() the filepath named 
'%s'" % config
+                logger.critical(error)
+                raise OSError("FATAL - could not open() the config filepath 
named '{}'".format(config))
+
+            except Exception as eee:
+                error = "FATAL - {}".format(str(eee))
+                logger.critical(error)
+                raise OSError(error)
+
+        elif isinstance(config, (str, pathlib.Path,)) and 
os.path.isfile(config) is False:
+            if self.debug > 0:
+                logger.debug("filepath not found - '%s'" % config)
+            error = """FATAL - Attempted to open(file='{0}', mode='r', 
encoding='{1}'); however, file filepath named:"{0}" does not 
exist.""".format(config, self.openargs['encoding'])
+            raise ValueError(error)
 
         else:
-            raise ValueError("config='%s' is an unexpected type()" % config)
+            raise ValueError("config='%s' is an unexpected type().  `config` 
must be either a python string, patlib.Path, or list" % config)
 
     #########################################################################
     # This method is on CiscoConfParse()
@@ -643,17 +664,17 @@
     # This method is on CiscoConfParse()
     @property
     def ioscfg(self):
-        """A list containing all text configuration statements"""
+        """Return a list containing all text configuration statements"""
         ## I keep ioscfg to emulate legacy ciscoconfparse behavior
         return [ii.text for ii in self.ConfigObjs]
 
     # This method is on CiscoConfParse()
     @property
     def objs(self):
-        """An alias to the ``ConfigObjs`` attribute"""
+        """CiscoConfParse().objs is an alias for the 
CiscoConfParse().ConfigObjs property; it returns a ConfigList() of config-line 
objects."""
         if self.ConfigObjs is None:
             err_txt = ("ConfigObjs is set to None.  ConfigObjs should be a "
-                       "list of text {} config strings".format(self.syntax))
+                       "ConfigList() of configuration-line 
objects".format(self.syntax))
             logger.error(err_txt)
             raise ValueError(err_txt)
         return self.ConfigObjs
@@ -661,7 +682,7 @@
     # This method is on CiscoConfParse()
     @logger.catch(reraise=True)
     def atomic(self):
-        """Call :func:`~ciscoconfparse.CiscoConfParse.atomic` to manually fix
+        """Use :func:`~ciscoconfparse.CiscoConfParse.atomic` to manually fix
         up ``ConfigObjs`` relationships
         after modifying a parsed configuration.  This method is slow; try to
         batch calls to :func:`~ciscoconfparse.CiscoConfParse.atomic()` if
@@ -714,112 +735,6 @@
         """
         self.atomic()  # atomic() calls self.ConfigObjs._bootstrap_from_text()
 
-    def _parse_line_braces_DEPRECATED(self, line_txt):
-        """
-        """
-        assert isinstance(line_txt, str)
-        child_indent = 0
-        this_line_indent = 0
-
-        junos_re_str = r"""^
-        (?:\s*
-            
(?P<braces_close_left>\})*(?P<line1>.*?)(?P<braces_open_right>\{)*;*
-           
|(?P<line2>[^\{\}]*?)(?P<braces_open_left>\{)(?P<condition2>.*?)(?P<braces_close_right>\});*\s*
-           |(?P<line3>[^\{\}]*?);*\s*
-        )$
-        """
-        line_re = re.compile(junos_re_str, re.VERBOSE)
-        comment_re = 
re.compile(r'^\s*(?P<delimiter>[{0}]+)(?P<comment>[^{0}]*)$'.format(re.escape(self.comment_delimiter)))
-
-        mm = line_re.search(line_txt.strip())
-        nn = comment_re.search(line_txt.strip())
-
-        if nn is not None:
-            results = nn.groupdict()
-            return (this_line_indent, child_indent, results.get('delimiter') + 
results.get('comment', ''))
-
-        elif mm is not None:
-            results = mm.groupdict()
-
-            # } line1 { foo bar this } {
-            braces_close_left = bool(results.get('braces_close_left', ''))
-            braces_open_right = bool(results.get('braces_open_right', ''))
-
-            # line2
-            braces_open_left = bool(results.get('braces_open_left', ''))
-            braces_close_right = bool(results.get('braces_close_right', ''))
-
-            # line3
-            line1_str = results.get('line1', '')
-            line3_str = results.get('line3', '')
-
-            if braces_close_left and braces_open_right:
-                # Based off line1
-                #     } elseif { bar baz } {
-                this_line_indent -= 1
-                child_indent     += 0
-                retval = results.get('line1', None)
-                return (this_line_indent, child_indent, retval)
-
-            elif bool(line1_str) and (braces_close_left is False) and 
(braces_open_right is False):
-                # Based off line1:
-                #     address 1.1.1.1
-                this_line_indent -= 0
-                child_indent     += 0
-                retval = results.get('line1', '').strip()
-                # Strip empty braces here
-                retval = re.sub(r'\s*\{\s*\}\s*', '', retval)
-                return (this_line_indent, child_indent, retval)
-
-            elif (line1_str == '') and (braces_close_left is False) and 
(braces_open_right is False):
-                # Based off line1:
-                #     return empty string
-                this_line_indent -= 0
-                child_indent += 0
-                return (this_line_indent, child_indent, '')
-
-            elif braces_open_left and braces_close_right:
-                # Based off line2
-                #    this { bar baz }
-                this_line_indent -= 0
-                child_indent += 0
-                line = results.get('line2', None) or ''
-                condition = results.get('condition2', None) or ''
-                if condition.strip() == '':
-                    retval = line
-                else:
-                    retval = line + " {" + condition + " }"
-                return (this_line_indent, child_indent, retval)
-
-            elif braces_close_left:
-                # Based off line1
-                #   }
-                this_line_indent -= 1
-                child_indent     -= 1
-                return (this_line_indent, child_indent, '')
-
-            elif braces_open_right:
-                # Based off line1
-                #   this that foo {
-                this_line_indent -= 0
-                child_indent     += 1
-                line = results.get('line1', None) or ''
-                return (this_line_indent, child_indent, line)
-
-            elif (line3_str != '') and (line3_str is not None):
-                this_line_indent += 0
-                child_indent     += 0
-                return (this_line_indent, child_indent, '')
-
-            else:
-                raise ValueError('Cannot parse {} match:"{}"'.format(
-                        self.syntax, line_txt))
-
-        else:
-            raise ValueError('Cannot parse {}:"{}"'.format(self.syntax,
-                        line_txt))
-
-
     # This method is on CiscoConfParse()
     @logger.catch(reraise=True)
     def convert_terraform_to_ios(self, input_list, stop_width=4, quotes=False, 
comment_delimiter="#"):
@@ -3083,6 +2998,7 @@
 
     # This method is on CiscoConfParse()
     @logger.catch(reraise=True)
+    @deprecat(reason="req_cfgspec_all_diff() is obsolete; use HDiff() instead. 
 req_cfgspec_all_diff() will be removed", version = '1.7.0')
     def req_cfgspec_all_diff(self, cfgspec, ignore_ws=False):
         """
         req_cfgspec_all_diff takes a list of required configuration lines,
@@ -3151,6 +3067,7 @@
 
     # This method is on CiscoConfParse()
     @logger.catch(reraise=True)
+    @deprecat(reason="req_cfgspec_excl_diff() is obsolete; use HDiff() 
instead.  req_cfgspec_excl_diff() will be removed", version = '1.7.0')
     def req_cfgspec_excl_diff(self, linespec, uncfgspec, cfgspec):
         r"""
         req_cfgspec_excl_diff accepts a linespec, an unconfig spec, and
@@ -3339,6 +3256,7 @@
 
     # This method is on CiscoConfParse()
     @logger.catch(reraise=True)
+    @deprecat(reason="sync_diff() is obsolete; use HDiff() instead.  
sync_diff() will be removed", version = '1.7.0')
     def sync_diff(
         self,
         cfgspec,
@@ -3410,6 +3328,10 @@
         deprecation_warn_str = "`sync_diff()` will be deprecated and removed 
in future versions."
         warnings.warn(deprecation_warn_str, DeprecationWarning)
 
+        assert isinstance(cfgspec, (list, tuple, Iterator)), "FATAL - 
`cfgspec` requires a python Iterable, typically a `list()`."
+        assert isinstance(linespec, str) and len(linespec) > 0, "FATAL - 
`linespec` requires a python string."
+        assert isinstance(unconfspec, str) and len(unconfspec) > 0, "FATAL - 
`unconfspec` requires a python string."
+
         tmp = self._find_line_OBJ(linespec)
         if uncfgspec is None:
             uncfgspec = linespec
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ciscoconfparse-1.6.53/pyproject.toml 
new/ciscoconfparse-1.7.0/pyproject.toml
--- old/ciscoconfparse-1.6.53/pyproject.toml    2022-11-18 11:42:29.383412000 
+0100
+++ new/ciscoconfparse-1.7.0/pyproject.toml     2023-01-02 16:23:02.461910500 
+0100
@@ -20,8 +20,8 @@
 
 [tool.poetry]
 name = "ciscoconfparse"
-version = "1.6.53"
-description = "Parse, Audit, Query, Build, and Modify Cisco IOS-style and 
JunOS-style configurations"
+version = "1.7.0"
+description = "Parse, Audit, Query, Build, and Modify Cisco IOS-style and 
JunOS-style configs"
 license = "GPL-3.0-only"
 authors = ["Mike Pennington <m...@pennington.net>"]
 readme = "README.md"
@@ -75,6 +75,7 @@
 dnspython = "^2.1.0"
 loguru = "0.6.0"
 toml = ">=0.10.2"
+deprecat = ">=2.1.1"
 
 [tool.poetry.urls]
 source = "https://github.com/mpenning/ciscoconfparse";
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ciscoconfparse-1.6.53/setup.py 
new/ciscoconfparse-1.7.0/setup.py
--- old/ciscoconfparse-1.6.53/setup.py  1970-01-01 01:00:00.000000000 +0100
+++ new/ciscoconfparse-1.7.0/setup.py   1970-01-01 01:00:00.000000000 +0100
@@ -10,6 +10,7 @@
 install_requires = \
 ['Sphinx==4.3.0',
  'black>=20.8b1',
+ 'deprecat>=2.1.1',
  'dnspython>=2.1.0,<3.0.0',
  'loguru==0.6.0',
  'packaging>21.0',
@@ -27,9 +28,9 @@
 
 setup_kwargs = {
     'name': 'ciscoconfparse',
-    'version': '1.6.53',
-    'description': 'Parse, Audit, Query, Build, and Modify Cisco IOS-style and 
JunOS-style configurations',
-    'long_description': 'ciscoconfparse\n==============\n\n[![Github unittest 
workflow][4]][5] [![Code Health][37]][38] [![Version][2]][3] 
[![Downloads][6]][7] [![License][8]][9]\n\n\nIntroduction: What is 
ciscoconfparse?\n-------------------------------------\n\nShort answer: 
ciscoconfparse is a [Python][10] library\nthat helps you quickly answer 
questions like these about your\nconfigurations:\n\n- What interfaces are 
shutdown?\n- Which interfaces are in trunk mode?\n- What address and subnet 
mask is assigned to each interface?\n- Which interfaces are missing a critical 
command?\n- Is this configuration missing a standard config line?\n\nIt can 
help you:\n\n- Audit existing router / switch / firewall / wlc 
configurations\n- Modify existing configurations\n- Build new 
configurations\n\nSpeaking generally, the library examines an IOS-style config 
and breaks\nit into a set of linked parent / child relationships. You can 
perform\ncomplex queries about these relationships.\n\n[![Cisco 
 IOS config: Parent / child][11]][11]\n\nUsage\n-----\n\nThe following code 
will parse a configuration stored in\n\\\'exampleswitch.conf\\\' and select 
interfaces that are shutdown.\n\n```python\nfrom ciscoconfparse import 
CiscoConfParse\n\nparse = CiscoConfParse(\'exampleswitch.conf\', 
syntax=\'ios\')\n\nfor intf_obj in parse.find_objects_w_child(\'^interface\', 
\'^\\s+shutdown\'):\n    print("Shutdown: " + intf_obj.text)\n```\n\nThe next 
example will find the IP address assigned to interfaces.\n\n```python\nfrom 
ciscoconfparse import CiscoConfParse\n\nparse = 
CiscoConfParse(\'exampleswitch.conf\', syntax=\'ios\')\n\nfor intf_obj in 
parse.find_objects(\'^interface\'):\n\n    intf_name = 
intf_obj.re_match_typed(\'^interface\\s+(\\S.+?)$\')\n\n    # Search children 
of all interfaces for a regex match and return\n    # the value matched in 
regex match group 1.  If there is no match,\n    # return a default value: 
\'\'\n    intf_ip_addr = intf_obj.re_match_iter_typed(\n        r\'ip\\sa
 ddress\\s(\\d+\\.\\d+\\.\\d+\\.\\d+)\\s\', result_type=str,\n        group=1, 
default=\'\')\n    print("{0}: {1}".format(intf_name, 
intf_ip_addr))\n```\n\nWhat if we don\\\'t use 
Cisco?\n----------------------------\n\nDon\\\'t let that stop you.\n\nAs of 
CiscoConfParse 1.2.4, you can parse [brace-delimited configurations][13] into a 
Cisco IOS style (see [Github Issue \\#17][14]), which means that CiscoConfParse 
can parse these configurations:\n\n- Juniper Networks Junos\n- Palo Alto 
Networks Firewall configurations\n- F5 Networks 
configurations\n\nCiscoConfParse also handles anything that has a Cisco IOS 
style of configuration, which includes:\n\n- Cisco IOS, Cisco Nexus, Cisco 
IOS-XR, Cisco IOS-XE, Aironet OS, Cisco ASA, Cisco CatOS\n- Arista EOS\n- 
Brocade\n- HP Switches\n- Force 10 Switches\n- Dell PowerConnect Switches\n- 
Extreme Networks\n- Enterasys\n- Screenos\n\nDocs\n----\n\n- The latest copy of 
the docs are [archived on the web][15]\n- There is also a [CiscoConfParse Tuto
 rial][16]\n\nEditing the Package\n-------------------\n\n-   `git clone 
https://github.com/mpenning/ciscoconfparse`\n-   `cd ciscoconfparse`\n-   `git 
checkout -b develop`\n-   Add / modify / delete on the `develop` branch\n-   
`make test`\n-   If tests run clean, `git commit` all the pending changes on 
the `develop` branch\n-   (as required) Edit the version number in 
[pyproject.toml][12]\n-   `git checkout main`\n-   `git merge develop`\n-   
`make test`\n-   `make repo-push`\n-   `make 
pypi`\n\nPre-requisites\n--------------\n\n[The ciscoconfparse python 
package][3] requires Python versions 3.7+ (note: Python version 3.7.0 has a bug 
- ref [Github issue \\#117][18], but version 3.7.1 works); the OS should not 
matter.\n\nInstallation and Downloads\n--------------------------\n\n-   Use 
`poetry` for Python3.x\\... :\n\n        python -m pip install 
ciscoconfparse\n\nIf you\\\'re interested in the source, you can always pull 
from the [github repo][17]:\n\n- Download from [the github r
 epo][17]: :\n\n        git clone git://github.com/mpenning/ciscoconfparse\n    
    cd ciscoconfparse/\n        python -m pip install .\n\nOther 
Resources\n---------------\n\n- [Dive into 
Python3](http://www.diveintopython3.net/) is a good way to learn Python\n- 
[Team CYMRU][30] has a [Secure IOS Template][29], which is especially useful 
for external-facing routers / switches\n- [Cisco\\\'s Guide to hardening IOS 
devices][31]\n- [Center for Internet Security Benchmarks][32] (An email 
address, cookies, and javascript are required)\n\nBug Tracker and 
Support\n-----------------------\n\n- Please report any suggestions, bug 
reports, or annoyances with a [github bug report][24].\n- If you\\\'re having 
problems with general python issues, consider searching for a solution on 
[Stack Overflow][33].  If you can\\\'t find a solution for your problem or need 
more help, you can [ask on Stack Overflow][34] or [reddit/r/Python][39].\n- If 
you\\\'re having problems with your Cisco devices, you can 
 contact:\n  - [Cisco TAC][28]\n  - [reddit/r/Cisco][35]\n  - 
[reddit/r/networking][36]\n  - 
[NetworkEngineering.se][23]\n\nUnit-Tests\n----------\n\nThe project\\\'s [test 
workflow][1] checks ciscoconfparse on Python versions 3.6 and higher, as well 
as a [pypy JIT][22] executable.\n\nClick the image below for details; the 
current build status is: [![Github unittest status][4]][5]\n\nLicense and 
Copyright\n---------------------\n\n[ciscoconfparse][3] is licensed 
[GPLv3][21]\n\n- Copyright (C) 2021-2022 David Michael Pennington\n- Copyright 
(C) 2020-2021 David Michael Pennington at Cisco Systems (post-acquisition: 
Cisco acquired ThousandEyes)\n- Copyright (C) 2019 David Michael Pennington at 
ThousandEyes\n- Copyright (C) 2012-2019 David Michael Pennington at Samsung 
Data Services\n- Copyright (C) 2011-2012 David Michael Pennington at Dell 
Computer Corp\n- Copyright (C) 2007-2011 David Michael Pennington\n\nThe word 
\\"Cisco\\" is a registered trademark of [Cisco Systems][27].\n\nAutho
 r\n------\n\n[ciscoconfparse][3] was written by [David Michael Pennington][25] 
(mike \\[\\~at\\~\\] pennington \\[.dot.\\] net).\n\n\n  [1]: 
https://github.com/mpenning/ciscoconfparse/tree/master/.github/workflows\n  
[2]: https://img.shields.io/pypi/v/ciscoconfparse.svg\n  [3]: 
https://pypi.python.org/pypi/ciscoconfparse/\n  [4]: 
https://github.com/mpenning/ciscoconfparse/actions/workflows/tests.yml/badge.svg\n
  [5]: https://github.com/mpenning/ciscoconfparse/actions/workflows/tests.yml\n 
 [6]: https://pepy.tech/badge/ciscoconfparse\n  [7]: 
https://pepy.tech/project/ciscoconfparse\n  [8]: 
http://img.shields.io/badge/license-GPLv3-blue.svg\n  [9]: 
https://www.gnu.org/copyleft/gpl.html\n  [10]: https://www.python.org\n  [11]: 
https://raw.githubusercontent.com/mpenning/ciscoconfparse/master/sphinx-doc/_static/ciscoconfparse_overview_75pct.png\n
  [12]: https://github.com/mpenning/ciscoconfparse/blob/main/pyproject.toml\n  
[13]: https://github.com/mpenning/ciscoconfparse/blob/master/conf
 igs/sample_01.junos\n  [14]: 
https://github.com/mpenning/ciscoconfparse/issues/17\n  [15]: 
http://www.pennington.net/py/ciscoconfparse/\n  [16]: 
http://pennington.net/tutorial/ciscoconfparse/ccp_tutorial.html\n  [17]: 
https://github.com/mpenning/ciscoconfparse\n  [18]: 
https://github.com/mpenning/ciscoconfparse/issues/117\n  [19]: 
https://github.com/mpenning/ciscoconfparse/issues/13\n  [20]: 
https://github.com/CrackerJackMack/\n  [21]: 
http://www.gnu.org/licenses/gpl-3.0.html\n  [22]: https://pypy.org\n  [23]: 
https://networkengineering.stackexchange.com/\n  [24]: 
https://github.com/mpenning/ciscoconfparse/issues/new/choose\n  [25]: 
https://github.com/mpenning\n  [26]: https://github.com/muir\n  [27]: 
https://www.cisco.com/\n  [28]: https://www.cisco.com/go/support\n  [29]: 
https://www.cymru.com/Documents/secure-ios-template.html\n  [30]: 
https://team-cymru.com/company/\n  [31]: 
http://www.cisco.com/c/en/us/support/docs/ip/access-lists/13608-21.html\n  
[32]: https://learn.cisecurity
 .org/benchmarks\n  [33]: https://stackoverflow.com\n  [34]: 
http://stackoverflow.com/questions/ask\n  [35]: 
https://www.reddit.com/r/Cisco/\n  [36]: https://www.reddit.com/r/networking\n  
[37]: https://snyk.io/advisor/python/ciscoconfparse/badge.svg\n  [38]: 
https://snyk.io/advisor/python/ciscoconfparse\n  [39]: 
https://www.reddit.com/r/Python/\n',
+    'version': '1.7.0',
+    'description': 'Parse, Audit, Query, Build, and Modify Cisco IOS-style and 
JunOS-style configs',
+    'long_description': 'ciscoconfparse\n==============\n\n[![Github unittest 
workflow][4]][5] [![Code Health][37]][38] [![git commits][41]][42] [![Repo Code 
Grade][43]][44]  [![Version][2]][3] [![Downloads][6]][7] 
[![License][8]][9]\n\n\nIntroduction: What is 
ciscoconfparse?\n-------------------------------------\n\nShort answer: 
ciscoconfparse is a [Python][10] library\nthat helps you quickly answer 
questions like these about your\nconfigurations:\n\n- What interfaces are 
shutdown?\n- Which interfaces are in trunk mode?\n- What address and subnet 
mask is assigned to each interface?\n- Which interfaces are missing a critical 
command?\n- Is this configuration missing a standard config line?\n\nIt can 
help you:\n\n- Audit existing router / switch / firewall / wlc 
configurations\n- Modify existing configurations\n- Build new 
configurations\n\nSpeaking generally, the library examines an IOS-style config 
and breaks\nit into a set of linked parent / child relationships. You can 
perform\n
 complex queries about these relationships.\n\n[![Cisco IOS config: Parent / 
child][11]][11]\n\nUsage\n-----\n\nThe following code will parse a 
configuration stored in\n\\\'exampleswitch.conf\\\' and select interfaces that 
are shutdown.\n\n```python\nfrom ciscoconfparse import CiscoConfParse\n\nparse 
= CiscoConfParse(\'exampleswitch.conf\', syntax=\'ios\')\n\nfor intf_obj in 
parse.find_objects_w_child(\'^interface\', \'^\\s+shutdown\'):\n    
print("Shutdown: " + intf_obj.text)\n```\n\nThe next example will find the IP 
address assigned to interfaces.\n\n```python\nfrom ciscoconfparse import 
CiscoConfParse\n\nparse = CiscoConfParse(\'exampleswitch.conf\', 
syntax=\'ios\')\n\nfor intf_obj in parse.find_objects(\'^interface\'):\n\n    
intf_name = intf_obj.re_match_typed(\'^interface\\s+(\\S.+?)$\')\n\n    # 
Search children of all interfaces for a regex match and return\n    # the value 
matched in regex match group 1.  If there is no match,\n    # return a default 
value: \'\'\n    intf_ip_
 addr = intf_obj.re_match_iter_typed(\n        
r\'ip\\saddress\\s(\\d+\\.\\d+\\.\\d+\\.\\d+)\\s\', result_type=str,\n        
group=1, default=\'\')\n    print("{0}: {1}".format(intf_name, 
intf_ip_addr))\n```\n\nWhat if we don\\\'t use 
Cisco?\n----------------------------\n\nDon\\\'t let that stop you.\n\nAs of 
CiscoConfParse 1.2.4, you can parse [brace-delimited configurations][13] into a 
Cisco IOS style (see [Github Issue \\#17][14]), which means that CiscoConfParse 
can parse these configurations:\n\n- Juniper Networks Junos\n- Palo Alto 
Networks Firewall configurations\n- F5 Networks 
configurations\n\nCiscoConfParse also handles anything that has a Cisco IOS 
style of configuration, which includes:\n\n- Cisco IOS, Cisco Nexus, Cisco 
IOS-XR, Cisco IOS-XE, Aironet OS, Cisco ASA, Cisco CatOS\n- Arista EOS\n- 
Brocade\n- HP Switches\n- Force 10 Switches\n- Dell PowerConnect Switches\n- 
Extreme Networks\n- Enterasys\n- Screenos\n\nDocs\n----\n\n- The latest copy of 
the docs are [archived 
 on the web][15]\n- There is also a [CiscoConfParse Tutorial][16]\n\nEditing 
the Package\n-------------------\n\n-   `git clone 
https://github.com/mpenning/ciscoconfparse`\n-   `cd ciscoconfparse`\n-   `git 
checkout -b develop`\n-   Add / modify / delete on the `develop` branch\n-   
`make test`\n-   If tests run clean, `git commit` all the pending changes on 
the `develop` branch\n-   (as required) Edit the version number in 
[pyproject.toml][12]\n-   `git checkout main`\n-   `git merge develop`\n-   
`make test`\n-   `make repo-push`\n-   `make 
pypi`\n\nPre-requisites\n--------------\n\n[The ciscoconfparse python 
package][3] requires Python versions 3.7+ (note: Python version 3.7.0 has a bug 
- ref [Github issue \\#117][18], but version 3.7.1 works); the OS should not 
matter.\n\nInstallation and Downloads\n--------------------------\n\n-   Use 
`poetry` for Python3.x\\... :\n\n        python -m pip install 
ciscoconfparse\n\nIf you\\\'re interested in the source, you can always pull 
from 
 the [github repo][17]:\n\n- Download from [the github repo][17]: :\n\n        
git clone git://github.com/mpenning/ciscoconfparse\n        cd 
ciscoconfparse/\n        python -m pip install .\n\nGithub Star 
History\n-------------------\n\n[![Github Star History Chart][40]][40]\n\nOther 
Resources\n---------------\n\n- [Dive into 
Python3](http://www.diveintopython3.net/) is a good way to learn Python\n- 
[Team CYMRU][30] has a [Secure IOS Template][29], which is especially useful 
for external-facing routers / switches\n- [Cisco\\\'s Guide to hardening IOS 
devices][31]\n- [Center for Internet Security Benchmarks][32] (An email 
address, cookies, and javascript are required)\n\nBug Tracker and 
Support\n-----------------------\n\n- Please report any suggestions, bug 
reports, or annoyances with a [github bug report][24].\n- If you\\\'re having 
problems with general python issues, consider searching for a solution on 
[Stack Overflow][33].  If you can\\\'t find a solution for your problem or ne
 ed more help, you can [ask on Stack Overflow][34] or [reddit/r/Python][39].\n- 
If you\\\'re having problems with your Cisco devices, you can contact:\n  - 
[Cisco TAC][28]\n  - [reddit/r/Cisco][35]\n  - [reddit/r/networking][36]\n  - 
[NetworkEngineering.se][23]\n\nUnit-Tests\n----------\n\nThe project\\\'s [test 
workflow][1] checks ciscoconfparse on Python versions 3.6 and higher, as well 
as a [pypy JIT][22] executable.\n\nClick the image below for details; the 
current build status is: [![Github unittest status][4]][5]\n\nLicense and 
Copyright\n---------------------\n\n[ciscoconfparse][3] is licensed 
[GPLv3][21]\n\n- Copyright (C) 2021-2022 David Michael Pennington\n- Copyright 
(C) 2020-2021 David Michael Pennington at Cisco Systems (post-acquisition: 
Cisco acquired ThousandEyes)\n- Copyright (C) 2019 David Michael Pennington at 
ThousandEyes\n- Copyright (C) 2012-2019 David Michael Pennington at Samsung 
Data Services\n- Copyright (C) 2011-2012 David Michael Pennington at Dell 
Compute
 r Corp\n- Copyright (C) 2007-2011 David Michael Pennington\n\nThe word 
\\"Cisco\\" is a registered trademark of [Cisco 
Systems][27].\n\nAuthor\n------\n\n[ciscoconfparse][3] was written by [David 
Michael Pennington][25] (mike \\[\\~at\\~\\] pennington \\[.dot.\\] net).\n\n\n 
 [1]: 
https://github.com/mpenning/ciscoconfparse/tree/master/.github/workflows\n  
[2]: https://img.shields.io/pypi/v/ciscoconfparse.svg\n  [3]: 
https://pypi.python.org/pypi/ciscoconfparse/\n  [4]: 
https://github.com/mpenning/ciscoconfparse/actions/workflows/tests.yml/badge.svg\n
  [5]: https://github.com/mpenning/ciscoconfparse/actions/workflows/tests.yml\n 
 [6]: https://pepy.tech/badge/ciscoconfparse\n  [7]: 
https://pepy.tech/project/ciscoconfparse\n  [8]: 
http://img.shields.io/badge/license-GPLv3-blue.svg\n  [9]: 
https://www.gnu.org/copyleft/gpl.html\n  [10]: https://www.python.org\n  [11]: 
https://raw.githubusercontent.com/mpenning/ciscoconfparse/master/sphinx-doc/_static/ciscoconfparse_overview_75pct.png\n
  [
 12]: https://github.com/mpenning/ciscoconfparse/blob/main/pyproject.toml\n  
[13]: 
https://github.com/mpenning/ciscoconfparse/blob/master/configs/sample_01.junos\n
  [14]: https://github.com/mpenning/ciscoconfparse/issues/17\n  [15]: 
http://www.pennington.net/py/ciscoconfparse/\n  [16]: 
http://pennington.net/tutorial/ciscoconfparse/ccp_tutorial.html\n  [17]: 
https://github.com/mpenning/ciscoconfparse\n  [18]: 
https://github.com/mpenning/ciscoconfparse/issues/117\n  [19]: 
https://github.com/mpenning/ciscoconfparse/issues/13\n  [20]: 
https://github.com/CrackerJackMack/\n  [21]: 
http://www.gnu.org/licenses/gpl-3.0.html\n  [22]: https://pypy.org\n  [23]: 
https://networkengineering.stackexchange.com/\n  [24]: 
https://github.com/mpenning/ciscoconfparse/issues/new/choose\n  [25]: 
https://github.com/mpenning\n  [26]: https://github.com/muir\n  [27]: 
https://www.cisco.com/\n  [28]: https://www.cisco.com/go/support\n  [29]: 
https://www.cymru.com/Documents/secure-ios-template.html\n  [30]: https
 ://team-cymru.com/company/\n  [31]: 
http://www.cisco.com/c/en/us/support/docs/ip/access-lists/13608-21.html\n  
[32]: https://learn.cisecurity.org/benchmarks\n  [33]: 
https://stackoverflow.com\n  [34]: http://stackoverflow.com/questions/ask\n  
[35]: https://www.reddit.com/r/Cisco/\n  [36]: 
https://www.reddit.com/r/networking\n  [37]: 
https://snyk.io/advisor/python/ciscoconfparse/badge.svg\n  [38]: 
https://snyk.io/advisor/python/ciscoconfparse\n  [39]: 
https://www.reddit.com/r/Python/\n  [40]: 
https://api.star-history.com/svg?repos=mpenning/ciscoconfparse&type=Date\n  
[41]: https://img.shields.io/github/commit-activity/m/mpenning/ciscoconfparse\n 
 [42]: 
https://img.shields.io/github/commit-activity/m/mpenning/ciscoconfparse\n  
[43]: https://www.codefactor.io/Content/badges/B.svg\n  [44]: 
https://www.codefactor.io/repository/github/mpenning/ciscoconfparse/\n',
     'author': 'Mike Pennington',
     'author_email': 'm...@pennington.net',
     'maintainer': 'None',

Reply via email to