From b29dc8b49690a7f4bcc9c9a394404822f20b2365 Mon Sep 17 00:00:00 2001 From: Dmitry Lyssenko Date: Sun, 21 May 2023 13:40:58 +0200 Subject: [PATCH 1/3] fixing doc build issues, errors, and providing docstring interpolation decorator --- docs/Makefile | 2 +- docs/conf.py | 2 +- docs/generate_modules.py | 3 +-- pyeapi/api/ipinterfaces.py | 4 +++- pyeapi/api/ospf.py | 24 ++++++++++++++---------- pyeapi/utils.py | 33 +++++++++++++++++++++++++++++++++ 6 files changed, 53 insertions(+), 15 deletions(-) diff --git a/docs/Makefile b/docs/Makefile index da55edf..e7c16e6 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -8,7 +8,7 @@ PAPER = BUILDDIR = _build APIDIR = api_modules CLIENTDIR = client_modules -CWD := $(shell pwd) +CWD := '$(shell pwd)' # User-friendly check for sphinx-build ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) diff --git a/docs/conf.py b/docs/conf.py index b89bc0b..d83565c 100755 --- a/docs/conf.py +++ b/docs/conf.py @@ -20,7 +20,7 @@ # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -sys.path.insert(0, '../pyeapi') +sys.path.insert(0, os.path.abspath('..') ) # -- General configuration ------------------------------------------------ diff --git a/docs/generate_modules.py b/docs/generate_modules.py index 9bbd074..3032fde 100755 --- a/docs/generate_modules.py +++ b/docs/generate_modules.py @@ -1,5 +1,4 @@ -#!/usr/bin/python -from __future__ import absolute_import, division, print_function +#!/usr/bin/python3 from os import listdir, path, makedirs from os.path import isfile, join, exists diff --git a/pyeapi/api/ipinterfaces.py b/pyeapi/api/ipinterfaces.py index 9518d52..9320298 100644 --- a/pyeapi/api/ipinterfaces.py +++ b/pyeapi/api/ipinterfaces.py @@ -49,6 +49,7 @@ import re from pyeapi.api import EntityCollection +from pyeapi.utils import _interpolate_docstr IP_MTU_MIN = 68 IP_MTU_MAX = 65535 @@ -217,6 +218,7 @@ def set_address(self, name, value=None, default=False, disable=False): default=default, disable=disable)) return self.configure(commands) + @_interpolate_docstr( 'IP_MTU_MIN', 'IP_MTU_MAX', __name__ ) def set_mtu(self, name, value=None, default=False, disable=False): """ Configures the interface IP MTU @@ -225,7 +227,7 @@ def set_mtu(self, name, value=None, default=False, disable=False): config to value (integer): The MTU value to set the interface to. Accepted - values include IP_MTU_MIN (68) to IP_MTU_MAX (65535) + values include IP_MTU_MIN to IP_MTU_MAX default (bool): Configures the mtu parameter to its default value using the EOS CLI default command diff --git a/pyeapi/api/ospf.py b/pyeapi/api/ospf.py index a1c50ef..4dd013d 100644 --- a/pyeapi/api/ospf.py +++ b/pyeapi/api/ospf.py @@ -55,16 +55,20 @@ def get(self, vrf=None): vrf (str): VRF name to return OSPF routing config for Returns: dict: - keys: router_id (int): OSPF router-id - vrf (str): VRF of the OSPF process - networks (dict): All networks that - are advertised in OSPF - ospf_process_id (int): OSPF proc id - redistribution (dict): All protocols that - are configured to be - redistributed in OSPF - shutdown (bool): Gives the current shutdown - off the process + keys: + router_id (int): OSPF router-id + + vrf (str): VRF of the OSPF process + networks (dict): All networks that + are advertised in OSPF + + ospf_process_id (int): OSPF proc id + + redistribution (dict): All protocols that + are configured to be redistributed in OSPF + + shutdown (bool): Gives the current shutdown + off the process """ match = '^router ospf .*' if vrf: diff --git a/pyeapi/utils.py b/pyeapi/utils.py index ad21164..a12d48c 100644 --- a/pyeapi/utils.py +++ b/pyeapi/utils.py @@ -257,3 +257,36 @@ def __init__(self, *cli): assert len( cli ) >= 2, 'must be initialized with 2 or more arguments' self.variants = [ v if not isinstance(v, str) and isinstance(v, Iterable) else [v] for v in cli ] + + +# Docstring decorator. +# SYNOPSIS: +# +# MIN_MTU=68 +# MAX_MTU=65535 +# +# @interpolate_docstr( 'MIN_MTU', 'MAX_MTU', __name__ ) +# def mtu_check( val ): +# """ check mtu against its min value (MIN_MTU) and max value (MAX_MTU)""" +# ... +# +# print( mtu_check.__doc__ ) +# check mtu against its min value (68) and max value (65535) +# +# Note: `__name__` must be provided as the last argument because the decorator +# could be imported, thus the current (importing) module needs to be resolved + +def _interpolate_docstr( *tkns ): + def docstr_decorator( user_fn ): + """update user_fn_wrapper doc string with the interpolated user_fn's + """ + def user_fn_wrapper( *args, **kwargs ): + return user_fn( *args, **kwargs ) + module = sys.modules[ tkns[-1] ] + docstr = user_fn.__doc__ + for tkn in tkns[:-1]: + sval = str( getattr(module, tkn) ) + docstr = docstr.replace( tkn, sval ) + user_fn_wrapper.__doc__ = docstr + return user_fn_wrapper + return docstr_decorator From 8e3fff43e6f82eca182905f99338708bdea16942 Mon Sep 17 00:00:00 2001 From: Dmitry Lyssenko Date: Sun, 21 May 2023 13:47:36 +0200 Subject: [PATCH 2/3] fixing indents --- pyeapi/utils.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/pyeapi/utils.py b/pyeapi/utils.py index a12d48c..e1ec976 100644 --- a/pyeapi/utils.py +++ b/pyeapi/utils.py @@ -277,16 +277,16 @@ def __init__(self, *cli): # could be imported, thus the current (importing) module needs to be resolved def _interpolate_docstr( *tkns ): - def docstr_decorator( user_fn ): - """update user_fn_wrapper doc string with the interpolated user_fn's - """ - def user_fn_wrapper( *args, **kwargs ): - return user_fn( *args, **kwargs ) - module = sys.modules[ tkns[-1] ] - docstr = user_fn.__doc__ - for tkn in tkns[:-1]: - sval = str( getattr(module, tkn) ) - docstr = docstr.replace( tkn, sval ) - user_fn_wrapper.__doc__ = docstr - return user_fn_wrapper - return docstr_decorator + def docstr_decorator( user_fn ): + """update user_fn_wrapper doc string with the interpolated user_fn's + """ + def user_fn_wrapper( *args, **kwargs ): + return user_fn( *args, **kwargs ) + module = sys.modules[ tkns[-1] ] + docstr = user_fn.__doc__ + for tkn in tkns[:-1]: + sval = str( getattr(module, tkn) ) + docstr = docstr.replace( tkn, sval ) + user_fn_wrapper.__doc__ = docstr + return user_fn_wrapper + return docstr_decorator From f77cd53ad3de0f1443f51d54199da620ee32472d Mon Sep 17 00:00:00 2001 From: Dmitry Lyssenko Date: Sun, 21 May 2023 13:53:45 +0200 Subject: [PATCH 3/3] moved decorator's descriptin into the doc string --- pyeapi/utils.py | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/pyeapi/utils.py b/pyeapi/utils.py index e1ec976..6e81d89 100644 --- a/pyeapi/utils.py +++ b/pyeapi/utils.py @@ -259,24 +259,25 @@ def __init__(self, *cli): str) and isinstance(v, Iterable) else [v] for v in cli ] -# Docstring decorator. -# SYNOPSIS: -# -# MIN_MTU=68 -# MAX_MTU=65535 -# -# @interpolate_docstr( 'MIN_MTU', 'MAX_MTU', __name__ ) -# def mtu_check( val ): -# """ check mtu against its min value (MIN_MTU) and max value (MAX_MTU)""" -# ... -# -# print( mtu_check.__doc__ ) -# check mtu against its min value (68) and max value (65535) -# -# Note: `__name__` must be provided as the last argument because the decorator -# could be imported, thus the current (importing) module needs to be resolved def _interpolate_docstr( *tkns ): + """Docstring decorator. + SYNOPSIS: + + MIN_MTU=68 + MAX_MTU=65535 + + @_interpolate_docstr( 'MIN_MTU', 'MAX_MTU', __name__ ) + def mtu_check( val ): + "check mtu against its min value (MIN_MTU) and max value (MAX_MTU)" + ... + + print( mtu_check.__doc__ ) + check mtu against its min value (68) and max value (65535) + + Note: `__name__` must be provided as the last argument because the decorator + could be imported, thus the current (importing) module needs to be resolved + """ def docstr_decorator( user_fn ): """update user_fn_wrapper doc string with the interpolated user_fn's """