def tcl_interp(): """ create a new Tcl interpreter with the standard packages loaded TESTS:: sage: from yacop.utils.tcl import tcl_interp, tcl_eval sage: tcl = tcl_interp() sage: tcl.eval("package present sqlite3") # random 3.8.2 """ tcl = Tcl() xdirs = Yacop.tcllibrary if not xdirs is None: if not isinstance(xdirs, list): xdirs = [xdirs] [tcl.eval("lappend auto_path {%s}" % path) for path in xdirs] tcl.eval( """ lappend auto_path $::env(SAGE_LOCAL)/tcl/lib lappend auto_path $::env(SAGE_LOCAL)/lib package require yacop::sage 1.0 """ ) return tcl
class TgnTk: """Native Python Tk interpreter.""" def __init__(self) -> None: """Init Tcl object.""" self.tcl = Tcl() def eval(self, command: str) -> str: # noqa: A003 """Execute Tcl eval command.""" return self.tcl.eval(command)
class IxiaMapper(object): """Tcl to Python functions mapper. """ class_logger = None def __init__(self, config, opts): """Initialize IxiaMapper class. Args: config(dict): Configuration information opts(OptionParser): py.test config.option object which contains all py.test cli options """ self.class_logger.info("Init Ixia HLTAPI class.") self._init_tcl() home = os.path.dirname(__file__) self.__config = config self.tcl("package req Ixia") self.tcl("source " + home + "/library/ixia_lacp_api.tcl") self.tcl("source " + home + "/library/ixnetwork_lacp_api.tcl") self.__register_methods() self.id = config['id'] self.type = config['instance_type'] self.chassis_ip = config['ip_host'] self.tcl_server = config['tcl_server'] def _init_tcl(self): """Initialize Tcl interpreter. Returns: None """ try: self.Tcl is None except AttributeError: self.Tcl = Tcl() # Define logger def tcl_puts(*args): """Enables logging for tcl output. Returns: None """ if len(args) >= 2: stream = args[0] if stream == "stdout": self.class_logger.debug(" ".join(args[1:])) elif stream == "stderr": self.class_logger.error(" ".join(args[1:])) else: self.class_logger.debug("stream <%s>: %s" % (args[0], " ".join(args[1:]))) elif len(args) == 1: self.class_logger.debug(args[0]) else: self.class_logger.error("Called puts without arguments.") return None self.Tcl.createcommand("tcl_puts", tcl_puts) self.class_logger.debug("Insert tcl script to catch puts output.") ixia_helpers.tcl_puts_replace(self.Tcl) ixia_helpers.ixtclhal_import(self.Tcl) def tcl(self, code): """Log end execute tcl code. Args: code(str): Tcl command Returns: str: Result of execution. """ self.class_logger.debug("Exec tcl: {0}".format(code)) return self.Tcl.eval(code) def __register_methods(self): """Register all Ixia.tcl methods. Returns: None """ def wrap(func, method): return lambda *args, **kwargs: self.__ixia_tcl_wrapper( method, *args, **kwargs) methods = self.tcl("info commands ::ixia::*") m_list = methods.split(" ") for _m in m_list: f_name = _m.replace("::ixia::", "") setattr(self, "ixia_" + f_name, wrap(self.__ixia_tcl_wrapper, f_name)) def __ixia_tcl_wrapper(self, method, *args, **kwargs): """Execute tcl ::ixia::method. Args: method(str): Method name Returns: str: Result of execution. """ _tcl_code = "set return_code [::ixia::" + method if args: _tcl_code += " " + " ".join(args) for name, value in list(kwargs.items()): if isinstance(value, bool): if value: _tcl_code += " -" + name else: _tcl_code += " -" + name + " " + str(value) _tcl_code += " ]" return self.tcl(_tcl_code) def check_return_code(self): """Check if ERROR is in return_code. Returns: str: Error message or empty string. """ return self.tcl( 'if {[keylget return_code status] != $::SUCCESS} ' + '{return "Last tcl operation FAIL - [keylget return_code log]"}') def set_var(self, **kwargs): """Set variable in tcl namespace. Returns: None """ for name, value in list(kwargs.items()): self.tcl("set {0} {1}".format(name, value)) def get_var(self, var_name): """Get variable value string representation from tcl namespace. Args: var_name(str): Variable name Returns: str: Value of variable. """ return self.tcl("return ${0}".format(var_name)) def puts(self, expr): """Call tcl puts method. Args: expr(str): Expression Returns: None """ self.tcl("puts {0}".format(expr))