def resolve_arguments(self, args_and_kwargs, variables=None): """More Pythonic argument handling for interactive :class:`robottools.testrobot.keyword.Keyword` calls. Original ``resolve_arguments`` methods from ``robot.running.handlers`` expect as first argument a single list of Keyword arguments coming from an RFW script:: ['arg0', 'arg1', ..., 'name=value', ...] So there is no chance to pass unstringified named argument values. Only unstringified positional arguments are possible. This wrapper method takes a normal Python `args_and_kwargs` pair instead as first argument:: (arg0, arg1, ...), {name: value, ...} It resolves the named arguments stringified via the original method but returns the original Python values:: [arg0, arg1, ...], [(name, value), ...] Only strings are untouched. So RFW ``'...${variable}...'`` substitution still works. """ posargs, kwargs = args_and_kwargs rfwargs = list(posargs) # prepare 'key=value' strings for original RFW method for name, value in dictitems(kwargs): if not isstring(value): value = repr(value) rfwargs.append(u'%s=%s' % (name, value)) posargs, rfwkwargs = self._resolve_arguments(rfwargs, variables) # and replace values with original non-string objects after resolving kwargslist = [] if isdict(rfwkwargs): # ==> RFW < 3.0 rfwkwargs = dictitems(rfwkwargs) for name, rfwvalue in rfwkwargs: value = kwargs[name] if isstring(value): value = rfwvalue kwargslist.append((name, value)) if hasattr(self, 'run'): # ==> RFW < 3.0 return posargs, dict(kwargslist) # RFW >= 3.0 return posargs, kwargslist
def __init__(self, result, **options): """Initialize with a :class:`robot.result.Result` instance and test run `options`. - Writes out 'output' XML, 'log' HTML and 'report' HTML if destination streams or file paths are defined in `options` (given streams won't get flushed or closed). """ self.robot_result = result self.options = options # post-processed RebotSettings from **options settings = self.settings # write output if destinations defined for output, format in [ ('output', 'xml'), ('log', 'html'), ('report', 'html'), ]: # first check if output paths or streams are defined in **options # because RebotSettings always define default output paths file = options.get(output) and getattr(settings, output) if not file: continue # get data from related property data = getattr(self, '%s_%s' % (output, format)) if isstring(file): # file path? with open(file, 'w') as f: f.write(data) else: # stream file.write(data)
def test_string_result(self, process, robot_Remote): for value in [1, 2.3, 'four', u'five']: result = robot_Remote.ConvertToString(value) # not consistent in current PY2-only robotremoteserver # (can be str or unicode): # assert isinstance(result, unicode) assert isstring(result) assert result == unicode(value)
def method(self, *args, **kwargs): varargs = [] for arg in args[nposargs:]: if isstring(arg) and '=' in arg: kwargs.setdefault(*arg.split('=', 1)) else: varargs.append(arg) return func(self, *chain(args[:nposargs], varargs), **kwargs)
def __new__(cls, string_or_year, *mdhms): """Create a new :class:`modeled.datetime` instance by giving either a """ if isstring(string_or_year): dt = base.strptime(string_or_year, cls.format) return base.__new__(cls, *dt.timetuple()[:6]) return base.__new__(cls, string_or_year, *mdhms)
def register_bool_class(cls_or_name, name=None, true=None, false=None, ignore=None, caseless=True, spaceless=True): if isstring(cls_or_name): name = cls_or_name Bool = normboolclass(name, true=true, false=false, ignore=ignore, caseless=caseless, spaceless=spaceless) else: if not isboolclass(cls_or_name): raise TypeError("No bool class: %s" % repr(cls_or_name)) Bool = cls_or_name if not name: name = Bool.__name__ BOOL_CLASSES[name] = Bool
def require_node_modules(dist, keyword='require_node_modules', jsmodules=None): """ Install required `jsmodules` during a Python package ``setup()``. """ assert keyword == 'require_node_modules' if jsmodules is None: return if isstring(jsmodules): jsmodules = filter(None, (mod.strip() for mod in jsmodules.split('\n'))) for jsmod in jsmodules: nodely.install(jsmod)
def __init__(self, props): Q = self.Q QObject.__init__(self, props) layout = props.pop('layout', None) children = props.pop('children', ()) if layout: self.setLayout(layout) layout = self.qclass.layout(self) for rown, q in enumerate(children): if isstring(q): q = Q.Label(text=q) layout.addWidget(q) continue try: row = iter(q) except TypeError: if isinstance(q, Aligned): layout.addWidget(q.q, 0, q.qalign) elif isinstance(q, Labeled): qlayout = {'<': 'HBox', '^': 'VBox'}[q.qpos] qpanel = Q.Widget(layout=qlayout, children=[ q.qlabel, q.q ]) layout.addWidget(qpanel) else: layout.addWidget(q) else: for coln, q in enumerate(row): if isstring(q): q = Q.Label(text=q) layout.addWidget(q, rown, coln) elif isinstance(q, Aligned): layout.addWidget(q.q, rown, coln, q.qalign) else: layout.addWidget(q, rown, coln) else: for q in children: q.setParent(self)
def __init__(self, props): Q = self.Q QObject.__init__(self, props) layout = props.pop('layout', None) children = props.pop('children', ()) if layout: self.setLayout(layout) layout = self.qclass.layout(self) for rown, q in enumerate(children): if isstring(q): q = Q.Label(text=q) layout.addWidget(q) continue try: row = iter(q) except TypeError: if isinstance(q, Aligned): layout.addWidget(q.q, 0, q.qalign) elif isinstance(q, Labeled): qlayout = {'<': 'HBox', '^': 'VBox'}[q.qpos] qpanel = Q.Widget(layout=qlayout, children=[q.qlabel, q.q]) layout.addWidget(qpanel) else: layout.addWidget(q) else: for coln, q in enumerate(row): if isstring(q): q = Q.Label(text=q) layout.addWidget(q, rown, coln) elif isinstance(q, Aligned): layout.addWidget(q.q, rown, coln, q.qalign) else: layout.addWidget(q, rown, coln) else: for q in children: q.setParent(self)
def convert_to_bool(self, value, *true_false, **options): if true_false: lists = NormalizedDict({'true': [], 'false': []}) # choose the first list to fill with items # based on given TRUE or FALSE specifier: try: t_or_f_list = lists[true_false[0]] except KeyError: raise ValueError("Expected TRUE or FALSE, not: %s" % repr(true_false[0])) for item in true_false[1:]: if item in lists: #==> is new TRUE or FALSE specifier #==> switch to corresponding list t_or_f_list = lists[item] if t_or_f_list: raise ValueError("Multiple %s lists specfied." % normalize(item).upper()) else: t_or_f_list.append(item) for key, items in lists.items(): if not items: raise ValueError("No %s list specified." % key.upper()) if RobotBool(options.get('normalized', True)): boolcls = normboolclass(**lists) else: boolcls = boolclass(**lists) else: boolcls = options.get('boolclass') or options.get('booltype') if not boolcls: # fallback to robot's default bool conversion return BUILTIN.convert_to_boolean(value) if isstring(boolcls): try: # is a registered bool class name? boolcls = BOOL_CLASSES[boolcls] except KeyError: if '.' not in boolcls: raise ValueError( "No such bool class registered: '%s'" % boolcls) modname, clsname = boolcls.rsplit('.', 1) try: # is an importable 'module.class' string? boolcls = getattr(__import__(modname), clsname) except (ImportError, AttributeError): raise ValueError( "Can't import bool class: '%s'" % boolcls) elif not isboolclass(boolcls): raise TypeError("No bool class: %s" % repr(boolcls)) BUILTIN._log_types(value) return boolcls(value)
def convert_to_bool(self, value, *true_false, **options): if true_false: lists = NormalizedDict({'true': [], 'false': []}) # choose the first list to fill with items # based on given TRUE or FALSE specifier: try: t_or_f_list = lists[true_false[0]] except KeyError: raise ValueError("Expected TRUE or FALSE, not: %s" % repr(true_false[0])) for item in true_false[1:]: if item in lists: #==> is new TRUE or FALSE specifier #==> switch to corresponding list t_or_f_list = lists[item] if t_or_f_list: raise ValueError("Multiple %s lists specfied." % normalize(item).upper()) else: t_or_f_list.append(item) for key, items in lists.items(): if not items: raise ValueError("No %s list specified." % key.upper()) if RobotBool(options.get('normalized', True)): boolcls = normboolclass(**lists) else: boolcls = boolclass(**lists) else: boolcls = options.get('boolclass') or options.get('booltype') if not boolcls: # fallback to robot's default bool conversion return BUILTIN.convert_to_boolean(value) if isstring(boolcls): try: # is a registered bool class name? boolcls = BOOL_CLASSES[boolcls] except KeyError: if '.' not in boolcls: raise ValueError( "No such bool class registered: '%s'" % boolcls) modname, clsname = boolcls.rsplit('.', 1) try: # is an importable 'module.class' string? boolcls = getattr(__import__(modname), clsname) except (ImportError, AttributeError): raise ValueError("Can't import bool class: '%s'" % boolcls) elif not isboolclass(boolcls): raise TypeError("No bool class: %s" % repr(boolcls)) BUILTIN._log_types(value) return boolcls(value)
def handle_data(self, text): if self.tag in exclude_tags: return if self.tag == 'script': if ('type', 'text/x-jquery-tmpl') in self.attrs: # also process the contents of embedded jQuery templates Parser().feed(text) return if not standalone \ and re.match(r'^\s*\$\(document\)\.ready', text): # dynamically created content should be appended # to parent element of embedded documentation text = text.replace( #TODO: better selector "$('body')", "$('div#javascript-disabled').parent()") elif self.tag == 'h1' and isstring(heading): # custom override heading text = heading stream.write(text)
def libdoc(library, out=None, name=None, version=None, format=None, docformat=None, **options): """Alternative to :func:`robot.libdoc` with the following extra features: - `out` can be a file path (with implicit format from extension) or a stream object (which won't be flushed or closed). In both cases, the number of written characters will be returned. - If `out` is ``None``, the document text will be returned. - For 'html' format, some extra post-processing `options` are supported: - If ``standalone=False``, the ``<html>``, ``<head>``, ``<meta>``, and ``<body>`` tags will be stripped to make the document embeddable in existing HTML documents without the use of ``<iframe>``s - ``heading=`` can be set to an alternative main heading text (which defaults to the library name) or to ``False`` to completely remove the heading element. """ outpath = isstring(out) and Path(out) if outpath and not format: # get implicit format from file extension _, ext = Path(out).splitext() format = ext[1:] # remove leading '.' if not format: raise ValueError("Missing format for robottools.libdoc()") if format not in FORMATS: raise ValueError("Invalid robottools.libdoc() format: %s" % repr(format)) if format != "html" and options: raise RuntimeError("robottools.libdoc() doesn't support extra options for %s format." % repr(format)) if out is not None: class Stream(object): """Simple out stream wrapper for counting written characters and preventing stream closing. """ count = 0 # look like a text stream encoding = "utf8" def write(self, text): self.count += len(text) out.write(text) def close(self): pass else: # memory stream for returning text class Stream(StringIO): """StringIO with close prevention. """ def close(self): pass stream = Stream() if outpath: # need `str` stream in PY2 and PY3 out = open(outpath, "w") doc = LibraryDocumentation(library, name, version, docformat) LibdocWriter(format).write(doc, stream if format != "html" else HTML(stream, **options)) if out is not None: if outpath: out.close() return stream.count # else return the text from StringIO stream.seek(0) text = stream.read() StringIO.close(stream) # close was overridden return text
def setLayout(self, qlayout): Q = self.Q if isstring(qlayout): qlayout = getattr(Q, qlayout + 'Layout')() self.qclass.setLayout(self, qlayout)
def libdoc(library, out=None, name=None, version=None, format=None, docformat=None, **options): """Alternative to :func:`robot.libdoc` with the following extra features: - `out` can be a file path (with implicit format from extension) or a stream object (which won't be flushed or closed). In both cases, the number of written characters will be returned. - If `out` is ``None``, the document text will be returned. - For 'html' format, some extra post-processing `options` are supported: - If ``standalone=False``, the ``<html>``, ``<head>``, ``<meta>``, and ``<body>`` tags will be stripped to make the document embeddable in existing HTML documents without the use of ``<iframe>``s - ``heading=`` can be set to an alternative main heading text (which defaults to the library name) or to ``False`` to completely remove the heading element. """ outpath = isstring(out) and Path(out) if outpath and not format: # get implicit format from file extension _, ext = Path(out).splitext() format = ext[1:] # remove leading '.' if not format: raise ValueError("Missing format for robottools.libdoc()") if format not in FORMATS: raise ValueError( "Invalid robottools.libdoc() format: %s" % repr(format)) if format != 'html' and options: raise RuntimeError( "robottools.libdoc() doesn't support extra options for %s format." % repr(format)) if out is not None: class Stream(object): """Simple out stream wrapper for counting written characters and preventing stream closing. """ count = 0 # look like a text stream encoding = 'utf8' def write(self, text): self.count += len(text) out.write(text) def close(self): pass else: # memory stream for returning text class Stream(StringIO): """StringIO with close prevention. """ def close(self): pass stream = Stream() if outpath: # need `str` stream in PY2 and PY3 out = open(outpath, 'w') doc = LibraryDocumentation(library, name, version, docformat) LibdocWriter(format).write( doc, stream if format != 'html' else HTML(stream, **options)) if out is not None: if outpath: out.close() return stream.count # else return the text from StringIO stream.seek(0) text = stream.read() StringIO.close(stream) # close was overridden return text