⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ezt.py

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 PY
📖 第 1 页 / 共 2 页
字号:
        elif cmd in _block_cmds:          if len(args) > _block_cmd_specs[cmd] + 1:            raise ArgCountSyntaxError(str(args[1:]))          ### this assumes arg1 is always a ref          args[1] = _prepare_ref(args[1], for_names, file_args)          # handle arg2 for the 'is' command          if cmd == 'is':            args[2] = _prepare_ref(args[2], for_names, file_args)          elif cmd == 'for':            for_names.append(args[1][0])          # remember the cmd, current pos, args, and a section placeholder          stack.append([cmd, len(program), args[1:], None])        elif cmd == 'include':          if args[1][0] == '"':            include_filename = args[1][1:-1]            f_args = [ ]            for arg in args[2:]:              f_args.append(_prepare_ref(arg, for_names, file_args))            program.extend(self._parse(reader.read_other(include_filename),                                       for_names,                                       f_args))          else:            if len(args) != 2:              raise ArgCountSyntaxError(str(args))            program.append((self._cmd_include,                            (_prepare_ref(args[1], for_names, file_args),                             reader)))        elif cmd == 'if-any':          f_args = [ ]          for arg in args[1:]:            f_args.append(_prepare_ref(arg, for_names, file_args))          stack.append(['if-any', len(program), f_args, None])        else:          # implied PRINT command          if len(args) > 1:            f_args = [ ]            for arg in args:              f_args.append(_prepare_ref(arg, for_names, file_args))            program.append((self._cmd_format, (f_args[0], f_args[1:])))          else:            program.append((self._cmd_print,                            _prepare_ref(args[0], for_names, file_args)))    if stack:      ### would be nice to say which blocks...      raise UnclosedBlocksError()    return program  def _execute(self, program, fp, ctx):    """This private helper function takes a 'program' sequence as created    by the method '_parse' and executes it step by step.  strings are written    to the file object 'fp' and functions are called.    """    for step in program:      if isinstance(step, StringType):        fp.write(step)      else:        step[0](step[1], fp, ctx)  def _cmd_print(self, valref, fp, ctx):    value = _get_value(valref, ctx)    # if the value has a 'read' attribute, then it is a stream: copy it    if hasattr(value, 'read'):      while 1:        chunk = value.read(16384)        if not chunk:          break        fp.write(chunk)    else:      fp.write(value)  def _cmd_format(self, (valref, args), fp, ctx):    fmt = _get_value(valref, ctx)    parts = _re_subst.split(fmt)    for i in range(len(parts)):      piece = parts[i]      if i%2 == 1 and piece != '%':        idx = int(piece)        if idx < len(args):          piece = _get_value(args[idx], ctx)        else:          piece = '<undef>'      fp.write(piece)  def _cmd_include(self, (valref, reader), fp, ctx):    fname = _get_value(valref, ctx)    ### note: we don't have the set of for_names to pass into this parse.    ### I don't think there is anything to do but document it.    self._execute(self._parse(reader.read_other(fname)), fp, ctx)  def _cmd_if_any(self, args, fp, ctx):    "If any value is a non-empty string or non-empty list, then T else F."    (valrefs, t_section, f_section) = args    value = 0    for valref in valrefs:      if _get_value(valref, ctx):        value = 1        break    self._do_if(value, t_section, f_section, fp, ctx)  def _cmd_if_index(self, args, fp, ctx):    ((valref, value), t_section, f_section) = args    list, idx = ctx.for_index[valref[0]]    if value == 'even':      value = idx % 2 == 0    elif value == 'odd':      value = idx % 2 == 1    elif value == 'first':      value = idx == 0    elif value == 'last':      value = idx == len(list)-1    else:      value = idx == int(value)    self._do_if(value, t_section, f_section, fp, ctx)  def _cmd_is(self, args, fp, ctx):    ((left_ref, right_ref), t_section, f_section) = args    value = _get_value(right_ref, ctx)    value = string.lower(_get_value(left_ref, ctx)) == string.lower(value)    self._do_if(value, t_section, f_section, fp, ctx)  def _do_if(self, value, t_section, f_section, fp, ctx):    if t_section is None:      t_section = f_section      f_section = None    if value:      section = t_section    else:      section = f_section    if section is not None:      self._execute(section, fp, ctx)  def _cmd_for(self, args, fp, ctx):    ((valref,), unused, section) = args    list = _get_value(valref, ctx)    if isinstance(list, StringType):      raise NeedSequenceError()    refname = valref[0]    ctx.for_index[refname] = idx = [ list, 0 ]    for item in list:      self._execute(section, fp, ctx)      idx[1] = idx[1] + 1    del ctx.for_index[refname]def boolean(value):  "Return a value suitable for [if-any bool_var] usage in a template."  if value:    return 'yes'  return Nonedef _prepare_ref(refname, for_names, file_args):  """refname -> a string containing a dotted identifier. example:"foo.bar.bang"  for_names -> a list of active for sequences.  Returns a `value reference', a 3-Tupel made out of (refname, start, rest),   for fast access later.  """  # is the reference a string constant?  if refname[0] == '"':    return None, refname[1:-1], None  # if this is an include-argument, then just return the prepared ref  if refname[:3] == 'arg':    try:      idx = int(refname[3:])    except ValueError:      pass    else:      if idx < len(file_args):        return file_args[idx]  parts = string.split(refname, '.')  start = parts[0]  rest = parts[1:]  while rest and (start in for_names):    # check if the next part is also a "for name"    name = start + '.' + rest[0]    if name in for_names:      start = name      del rest[0]    else:      break  return refname, start, restdef _get_value((refname, start, rest), ctx):  """(refname, start, rest) -> a prepared `value reference' (see above).  ctx -> an execution context instance.  Does a name space lookup within the template name space.  Active   for blocks take precedence over data dictionary members with the   same name.  """  if rest is None:    # it was a string constant    return start  if ctx.for_index.has_key(start):    list, idx = ctx.for_index[start]    ob = list[idx]  elif ctx.data.has_key(start):    ob = ctx.data[start]  else:    raise UnknownReference(refname)  # walk the rest of the dotted reference  for attr in rest:    try:      ob = getattr(ob, attr)    except AttributeError:      raise UnknownReference(refname)  # make sure we return a string instead of some various Python types  if isinstance(ob, IntType) or isinstance(ob, FloatType):    return str(ob)  if ob is None:    return ''  # string or a sequence  return obclass _context:  """A container for the execution context"""class Reader:  "Abstract class which allows EZT to detect Reader objects."class _FileReader(Reader):  """Reads templates from the filesystem."""  def __init__(self, fname):    self.text = open(fname, 'rb').read()    self._dir = os.path.dirname(fname)  def read_other(self, relative):    return _FileReader(os.path.join(self._dir, relative))class _TextReader(Reader):  """'Reads' a template from provided text."""  def __init__(self, text):    self.text = text  def read_other(self, relative):    raise BaseUnavailableError()class EZTException(Exception):  """Parent class of all EZT exceptions."""class ArgCountSyntaxError(EZTException):  """A bracket directive got the wrong number of arguments."""class UnknownReference(EZTException):  """The template references an object not contained in the data dictionary."""class NeedSequenceError(EZTException):  """The object dereferenced by the template is no sequence (tuple or list)."""class UnclosedBlocksError(EZTException):  """This error may be simply a missing [end]."""class UnmatchedEndError(EZTException):  """This error may be caused by a misspelled if directive."""class BaseUnavailableError(EZTException):  """Base location is unavailable, which disables includes."""# --- standard test environment ---def test_parse():  assert _re_parse.split('[a]') == ['', '[a]', None, '']  assert _re_parse.split('[a] [b]') == \         ['', '[a]', None, ' ', '[b]', None, '']  assert _re_parse.split('[a c] [b]') == \         ['', '[a c]', None, ' ', '[b]', None, '']  assert _re_parse.split('x [a] y [b] z') == \         ['x ', '[a]', None, ' y ', '[b]', None, ' z']  assert _re_parse.split('[a "b" c "d"]') == \         ['', '[a "b" c "d"]', None, '']  assert _re_parse.split(r'["a \"b[foo]" c.d f]') == \         ['', '["a \\"b[foo]" c.d f]', None, '']def _test(argv):  import doctest, ezt             verbose = "-v" in argv  return doctest.testmod(ezt, verbose=verbose)if __name__ == "__main__":  # invoke unit test for this module:  import sys  sys.exit(_test(sys.argv)[0])

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -