Skip to content

Commit

Permalink
Remove CiscoConfParse().find_lines()
Browse files Browse the repository at this point in the history
  • Loading branch information
mpenning committed Nov 30, 2023
1 parent 405acbd commit 5ee4208
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 102 deletions.
17 changes: 11 additions & 6 deletions ciscoconfparse/ccp_abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -878,10 +878,9 @@ def insert_after(self, insertstr=None):
# On BaseCfgLine()
@junos_unsupported
@logger.catch(reraise=True)
def append_to_family(
self, insertstr, indent=-1, auto_indent_width=1, auto_indent=False
):
"""Append an :class:`~models_cisco.IOSCfgLine` object with ``insertstr``
def append_to_family(self, insertstr, indent=-1, auto_indent_width=1, auto_indent=False):
"""
Append an :class:`~models_cisco.IOSCfgLine` object with ``insertstr``
as a child at the top of the current configuration family.
``insertstr`` is inserted at the top of the family to ensure there are no
Expand All @@ -894,6 +893,9 @@ def append_to_family(
If auto_indent is True, add ``insertstr`` with the correct left-indent
level automatically.
Call :func:`~ciscoconfparse.CiscoConfParse.commit` if inserting something other
than a text configuration string.
Parameters
----------
insertstr : str
Expand All @@ -904,15 +906,18 @@ def append_to_family(
Amount of whitespace to automatically indent
auto_indent : bool
Automatically indent the child to ``auto_indent_width``
Returns
-------
str
The text matched by the regular expression group; if there is no match, None is returned.
Examples
--------
This example illustrates how you can use
:func:`~ccp_abc.append_to_family` to add a
This example illustrates how you can use :func:`~ccp_abc.append_to_family` to add a
``carrier-delay`` to each interface.
.. code-block:: python
:emphasize-lines: 14
>>> from ciscoconfparse import CiscoConfParse
Expand Down
51 changes: 7 additions & 44 deletions ciscoconfparse/ciscoconfparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -949,6 +949,7 @@ def openargs(self):
@property
@logger.catch(reraise=True)
def text(self):
"""Return a list containing all text configuration statements; it is an alias for ``CiscoConfParse().ioscfg``."""
return self.ioscfg

# This method is on CiscoConfParse()
Expand Down Expand Up @@ -987,7 +988,7 @@ def atomic(self):
Warnings
--------
If you modify a configuration after parsing it with :class:`~ciscoconfparse.CiscoConfParse`, you *must* call :func:`~ciscoconfparse.CiscoConfParse.commit` or :func:`~ciscoconfparse.CiscoConfParse.atomic` before searching the configuration again with methods such as :func:`~ciscoconfparse.CiscoConfParse.find_objects` or :func:`~ciscoconfparse.CiscoConfParse.find_lines`. Failure to call :func:`~ciscoconfparse.CiscoConfParse.commit` or :func:`~ciscoconfparse.CiscoConfParse.atomic` on config modifications could lead to unexpected search results.
If you modify a configuration after parsing it with :class:`~ciscoconfparse.CiscoConfParse`, you *must* call :func:`~ciscoconfparse.CiscoConfParse.commit` or :func:`~ciscoconfparse.CiscoConfParse.atomic` before searching the configuration again with methods such as :func:`~ciscoconfparse.CiscoConfParse.find_objects`. Failure to call :func:`~ciscoconfparse.CiscoConfParse.commit` or :func:`~ciscoconfparse.CiscoConfParse.atomic` on config modifications could lead to unexpected search results.
See Also
--------
Expand All @@ -1003,7 +1004,7 @@ def commit(self):
Warnings
--------
If you modify a configuration after parsing it with :class:`~ciscoconfparse.CiscoConfParse`, you *must* call :func:`~ciscoconfparse.CiscoConfParse.commit` or :func:`~ciscoconfparse.CiscoConfParse.atomic` before searching the configuration again with methods such as :func:`~ciscoconfparse.CiscoConfParse.find_objects` or :func:`~ciscoconfparse.CiscoConfParse.find_lines`. Failure to call :func:`~ciscoconfparse.CiscoConfParse.commit` or :func:`~ciscoconfparse.CiscoConfParse.atomic` on config modifications could lead to unexpected search results.
If you modify a configuration after parsing it with :class:`~ciscoconfparse.CiscoConfParse`, you *must* call :func:`~ciscoconfparse.CiscoConfParse.commit` or :func:`~ciscoconfparse.CiscoConfParse.atomic` before searching the configuration again with methods such as :func:`~ciscoconfparse.CiscoConfParse.find_objects`. Failure to call :func:`~ciscoconfparse.CiscoConfParse.commit` or :func:`~ciscoconfparse.CiscoConfParse.atomic` on config modifications could lead to unexpected search results.
See Also
--------
Expand Down Expand Up @@ -1422,7 +1423,7 @@ def find_objects_dna(self, dnaspec, exactmatch=False):
# This method is on CiscoConfParse()
@logger.catch(reraise=True)
def find_objects(self, linespec, exactmatch=False, ignore_ws=False):
"""Find all :class:`~models_cisco.IOSCfgLine` objects whose text matches ``linespec`` and return the :class:`~models_cisco.IOSCfgLine` objects in a python list. :func:`~ciscoconfparse.CiscoConfParse.find_objects` is similar to :func:`~ciscoconfparse.CiscoConfParse.find_lines`; however, the former returns a list of :class:`~models_cisco.IOSCfgLine` objects, while the latter returns a list of text configuration statements. Going forward, I strongly encourage people to start using :func:`~ciscoconfparse.CiscoConfParse.find_objects` instead of :func:`~ciscoconfparse.CiscoConfParse.find_lines`.
"""Find all :class:`~models_cisco.IOSCfgLine` objects whose text matches ``linespec`` and return the :class:`~models_cisco.IOSCfgLine` objects in a python list.
Parameters
----------
Expand All @@ -1440,9 +1441,8 @@ def find_objects(self, linespec, exactmatch=False, ignore_ws=False):
Examples
--------
This example illustrates the difference between
:func:`~ciscoconfparse.CiscoConfParse.find_objects` and
:func:`~ciscoconfparse.CiscoConfParse.find_lines`.
This example illustrates the use of :func:`~ciscoconfparse.CiscoConfParse.find_objects`
>>> from ciscoconfparse import CiscoConfParse
>>> config = [
... '!',
Expand All @@ -1458,9 +1458,6 @@ def find_objects(self, linespec, exactmatch=False, ignore_ws=False):
>>> parse.find_objects(r'^interface')
[<IOSCfgLine # 1 'interface Serial1/0'>, <IOSCfgLine # 4 'interface Serial1/1'>]
>>>
>>> parse.find_lines(r'^interface')
['interface Serial1/0', 'interface Serial1/1']
>>>
"""
if self.debug > 0:
Expand All @@ -1472,37 +1469,6 @@ def find_objects(self, linespec, exactmatch=False, ignore_ws=False):
linespec = build_space_tolerant_regex(linespec)
return self._find_line_OBJ(linespec, exactmatch)

# This method is on CiscoConfParse()
@logger.catch(reraise=True)
def find_lines(self, linespec, exactmatch=False, ignore_ws=False):
"""This method is the equivalent of a simple configuration grep (Case-sensitive).
Parameters
----------
linespec : str
Text regular expression for the line to be matched
exactmatch : bool
Defaults to False. When set True, this option requires ``linespec`` match the whole configuration line, instead of a portion of the configuration line.
ignore_ws : bool
boolean that controls whether whitespace is ignored. Default is False.
Returns
-------
list
A list of matching configuration lines
"""
if ignore_ws:
linespec = build_space_tolerant_regex(linespec)

if exactmatch is False:
# Return the lines in self.ioscfg, which match linespec
return list(filter(re.compile(linespec).search, self.ioscfg))
else:
# Return the lines in self.ioscfg, which match (exactly) linespec
return list(
filter(re.compile("^%s$" % linespec).search, self.ioscfg),
)

# This method is on CiscoConfParse()
@logger.catch(reraise=True)
def find_objects_w_child(self, parentspec, childspec, ignore_ws=False, recurse=False):
Expand Down Expand Up @@ -4289,9 +4255,7 @@ def parse_global_options():
)
(opts, args) = pp.parse_args()

if opts.method == "find_lines":
diff = CiscoConfParse(config=opts.config).find_lines(opts.arg1)
elif opts.method == "find_children":
if opts.method == "find_children":
diff = CiscoConfParse(config=opts.config).find_children(opts.arg1)
elif opts.method == "find_all_children":
diff = CiscoConfParse(config=opts.config).find_all_children(opts.arg1)
Expand All @@ -4318,7 +4282,6 @@ def parse_global_options():
exit(1)
elif opts.method == "help":
print("Valid methods and their arguments:")
print(" find_lines: arg1=linespec")
print(" find_children: arg1=linespec")
print(" find_all_children: arg1=linespec")
print(" find_blocks: arg1=linespec")
Expand Down
1 change: 1 addition & 0 deletions sphinx-doc/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ This part of the documentation covers all the significant Python classes and met
:caption: Contents:

api_CiscoConfParse.rst
api_Ccp_Abc.rst
api_ConfigList.rst
api_Models_Cisco.rst
api_Models_Nxos.rst
Expand Down
58 changes: 6 additions & 52 deletions tests/test_CiscoConfParse.py
Original file line number Diff line number Diff line change
Expand Up @@ -1202,50 +1202,6 @@ def testValues_parent_child_parsing_02():
assert correct_result == test_result


def testValues_find_lines(parse_c01):
c01_intf = ["interface Serial 1/0"]
c01_find_gige_no_exactmatch = [
"interface GigabitEthernet4/1",
"interface GigabitEthernet4/2",
"interface GigabitEthernet4/3",
"interface GigabitEthernet4/4",
"interface GigabitEthernet4/5",
"interface GigabitEthernet4/6",
"interface GigabitEthernet4/7",
"interface GigabitEthernet4/8",
]
find_lines_Values = (
# Ensure exact matches work regardless of the exactmatch boolean
({"linespec": "interface Serial 1/0", "exactmatch": False}, c01_intf),
({"linespec": "interface Serial 1/0", "exactmatch": True}, c01_intf),
# Ensure we can find string matches inside an interface config block
({"linespec": "encapsulation", "exactmatch": False}, [" encapsulation ppp"]),
# Ensure exactmatch=False catches beginning phrases in the config
(
{"linespec": "interface GigabitEthernet4/", "exactmatch": False},
c01_find_gige_no_exactmatch,
),
# Ensure exactmatch=False catches single words in the config
(
{"linespec": "igabitEthernet", "exactmatch": False},
c01_find_gige_no_exactmatch,
),
# Negative test: matches are Case-Sensitive
({"linespec": "GigaBitEtherNeT", "exactmatch": False}, []),
# Negative test for exactmatch=True
({"linespec": "interface GigabitEthernet4/", "exactmatch": True}, []),
# Negative test for exactmatch=True and ignore_ws=False
(
{"linespec": "interface Serial1/0", "exactmatch": True, "ignore_ws": False},
[],
),
)

for args, correct_result in find_lines_Values:
test_result = parse_c01.find_lines(**args)
assert correct_result == test_result


def testValues_obj_insert_before_01():
"""test whether we can insert before IOSCfgLine() elements"""
c01 = [
Expand Down Expand Up @@ -2161,25 +2117,23 @@ def testValues_Diff_09():


def testValues_ignore_ws():
## test find_lines with ignore_ws flag
config = ["set snmp community read-only myreadonlystring"]
correct_result = config
cfg = CiscoConfParse(config)
test_result = cfg.find_lines(
parse = CiscoConfParse(config)
uut = parse.find_objects(
"set snmp community read-only myreadonlystring", ignore_ws=True
)
assert correct_result == test_result
assert correct_result == [ii.text for ii in uut]


def testValues_negative_ignore_ws():
"""test find_lines WITHOUT ignore_ws"""
config = ["set snmp community read-only myreadonlystring"]
correct_result = list()
cfg = CiscoConfParse(config)
test_result = cfg.find_lines(
parse = CiscoConfParse(config)
uut = parse.find_objects(
"set snmp community read-only myreadonlystring", ignore_ws=False
)
assert correct_result == test_result
assert correct_result == uut


def testValues_IOSCfgLine_all_parents(parse_c01):
Expand Down

0 comments on commit 5ee4208

Please sign in to comment.