def _mutate_expected_based_on_doctest_flags(self, expected_str): options = self.options options.mask_default(False) if options['py_doctest']: if not options['DONT_ACCEPT_BLANKLINE']: expected_str = self._blankline_tag_re.sub('', expected_str) m = _EXCEPTION_RE.match(expected_str) if options['ELLIPSIS'] or m: # we will enable the capture mode, check and warn if the example # contains strings like <label> that may confuse byexample and # or the user if self.capture_tag_regex().search(expected_str): log( "[Warn] The expected strings has <label> strings that will not be considered literal but as capture tags.", self.verbosity) if options['ELLIPSIS']: ellipsis_tag = '<%s>' % self.ellipsis_marker() expected_str = expected_str.replace('...', ellipsis_tag) # yes, again, we modified the expected_str in the step before m = _EXCEPTION_RE.match(expected_str) if m: # make an expected string ignoring the stack trace # and the traceback header like doctest does. ellipsis_tag = '<%s>' % self.ellipsis_marker() msg = m.group('msg') if options['IGNORE_EXCEPTION_DETAIL']: # we assume, like doctest does, that the first : is at # the end of the class name of the exception. full_class_name = msg.split(":", 1)[0] class_name = full_class_name.rsplit(".", 1)[-1] msg = class_name + ":" expected_str = '\n'.join([ # a Traceback header 'Traceback ' + ellipsis_tag, # the stack trace (ignored) ellipsis_tag, # the "relaxed" exception message # in Python 2.x this starts with a class # name while in Python 3.x starts with # a full name (module dot class name) # # this breaks almost all the exception # checks in doctest so this should be a nice # improvement. ellipsis_tag + msg + \ (ellipsis_tag if options['IGNORE_EXCEPTION_DETAIL'] else ""), ]) # enable the capture, this should affect to this example only options['tags'] = True options.unmask_default() return expected_str
def _map_doctest_opts_to_byexample_opts(self): ''' In compatibility mode, take all the Python doctest's options and flags and map them to a byexample option if possible. Otherwise log a message. Also, in compatibility mode, disable any "tags" unless the ELLIPSIS flag is present. Return a dictionary with the mapped flags; self.options is unchanged. ''' options = self.options options.mask_default(False) mapped = {} if options['py_doctest']: # map the following doctest's options to byexample's ones if options['NORMALIZE_WHITESPACE']: mapped['norm_ws'] = True if options['SKIP']: mapped['skip'] = True if options['ELLIPSIS']: # enable the 'tags' if ELLIPSIS but see also expected_from_match # as this byexample's option is not equivalent to doctest's one mapped['tags'] = True if options['REPORT_UDIFF']: mapped['diff'] = 'unified' if options['REPORT_CDIFF']: mapped['diff'] = 'context' if options['REPORT_NDIFF']: mapped['diff'] = 'ndiff' # the following are not supported: ignore them and print a note # somewhere if options['DONT_ACCEPT_TRUE_FOR_1']: log("[Note] DONT_ACCEPT_TRUE_FOR_1 flag is not supported.", self.verbosity - 2) # in compatibility mode, do not interpret <...> by default [force this] if self.options['py_doctest'] and 'tags' not in mapped: mapped['tags'] = False options.unmask_default() return mapped