Best Python code snippet using autotest_python
jsontemplate.py
Source:jsontemplate.py  
...245      func = _DoSection246    else:247      raise AssertionError('Invalid token type %s' % token_type)248    self._NewSection(func, new_block)249  def NewOrClause(self, pred_str):250    """251    {.or ...} Can appear inside predicate blocks or section blocks, with252    slightly different meaning.253    """254    if pred_str:255      pred = self._GetPredicate(pred_str)256    else:257      pred = None258    self.current_block.NewOrClause(pred)259  def AlternatesWith(self):260    self.current_block.AlternatesWith()261  def NewPredicateSection(self, pred_str):262    """For chains of predicate clauses."""263    pred = self._GetPredicate(pred_str)264    block = _PredicateSection()265    block.NewOrClause(pred)266    self._NewSection(_DoPredicates, block)267  def EndSection(self):268    self.stack.pop()269    self.current_block = self.stack[-1]270  def Root(self):271    # It's assumed that we call this at the end of the program272    return self.current_block273class _AbstractSection(object):274  def __init__(self):275    # Pairs of func, args, or a literal string276    self.current_clause = []277  def Append(self, statement):278    """Append a statement to this block."""279    self.current_clause.append(statement)280  def AlternatesWith(self):281    raise TemplateSyntaxError(282        '{.alternates with} can only appear with in {.repeated section ...}')283  def NewOrClause(self):284    raise NotImplementedError285class _Section(_AbstractSection):286  """Represents a (repeated) section."""287  def __init__(self, section_name=None):288    """289    Args:290      section_name: name given as an argument to the section291      token_type: The token type that created this section (e.g.292          PREDICATE_TOKEN)293    """294    _AbstractSection.__init__(self)295    self.section_name = section_name296    # Clauses is just a string and a list of statements.297    self.statements = {'default': self.current_clause}298  def __repr__(self):299    return '<Section %s>' % self.section_name300  def Statements(self, clause='default'):301    return self.statements.get(clause, [])302  def NewOrClause(self, pred):303    if pred:304      raise TemplateSyntaxError(305          '{.or} clause only takes a predicate inside predicate blocks')306    self.current_clause = []307    self.statements['or'] = self.current_clause308class _RepeatedSection(_Section):309  """Repeated section is like section, but it supports {.alternates with}"""310  def AlternatesWith(self):311    self.current_clause = []312    self.statements['alternates with'] = self.current_clause313class _PredicateSection(_AbstractSection):314  """Represents a sequence of predicate clauses."""315  def __init__(self):316    _AbstractSection.__init__(self)317    # List of func, statements318    self.clauses = []319  def NewOrClause(self, pred):320    # {.or} always executes if reached321    pred = pred or (lambda x: True, None, SIMPLE_FUNC)  # 3-tuple322    self.current_clause = []323    self.clauses.append((pred, self.current_clause))324class _Frame(object):325  """A stack frame."""326  def __init__(self, context, index=-1):327    # Public attributes328    self.context = context329    self.index = index   # An iteration index.  -1 means we're NOT iterating.330  def __str__(self):331    return 'Frame %s (%s)' % (self.context, self.index)332class _ScopedContext(object):333  """Allows scoped lookup of variables.334  If the variable isn't in the current context, then we search up the stack.335  """336  def __init__(self, context, undefined_str):337    """338    Args:339      context: The root context340      undefined_str: See Template() constructor.341    """342    self.stack = [_Frame(context)]343    self.undefined_str = undefined_str344  def PushSection(self, name):345    """Given a section name, push it on the top of the stack.346    Returns:347      The new section, or None if there is no such section.348    """349    if name == '@':350      new_context = self.stack[-1].context351    else:352      new_context = self.stack[-1].context.get(name)353    self.stack.append(_Frame(new_context))354    return new_context355  def Pop(self):356    self.stack.pop()357  def Next(self):358    """Advance to the next item in a repeated section.359    Raises:360      StopIteration if there are no more elements361    """362    stacktop = self.stack[-1]363    # Now we're iterating -- push a new mutable object onto the stack364    if stacktop.index == -1:365      stacktop = _Frame(None, index=0)366      self.stack.append(stacktop)367    context_array = self.stack[-2].context368    if stacktop.index == len(context_array):369      self.stack.pop()370      raise StopIteration371    stacktop.context = context_array[stacktop.index]372    stacktop.index += 1373    return True  # OK, we mutated the stack374  def _Undefined(self, name):375    if self.undefined_str is None:376      raise UndefinedVariable('%r is not defined' % name)377    else:378      return self.undefined_str379  def _LookUpStack(self, name):380    """Look up the stack for the given name."""381    i = len(self.stack) - 1382    while 1:383      frame = self.stack[i]384      if name == '@index':385        if frame.index != -1:  # -1 is undefined386          return frame.index  # @index is 1-based387      else:388        context = frame.context389        if hasattr(context, 'get'):  # Can't look up names in a list or atom390          try:391            return context[name]392          except KeyError:393            pass394      i -= 1  # Next frame395      if i <= -1:  # Couldn't find it anywhere396        return self._Undefined(name)397  def Lookup(self, name):398    """Get the value associated with a name in the current context.399    The current context could be an dictionary in a list, or a dictionary400    outside a list.401    Args:402      name: name to lookup, e.g. 'foo' or 'foo.bar.baz'403    Returns:404      The value, or self.undefined_str405    Raises:406      UndefinedVariable if self.undefined_str is not set407    """408    if name == '@':409      return self.stack[-1].context410    parts = name.split('.')411    value = self._LookUpStack(parts[0])412    # Now do simple lookups of the rest of the parts413    for part in parts[1:]:414      try:415        value = value[part]416      except (KeyError, TypeError):  # TypeError for non-dictionaries417        return self._Undefined(part)418    return value419def _ToString(x):420  # Some cross-language values for primitives421  if x is None:422    return 'null'423  if isinstance(x, basestring):424    return x425  return pprint.pformat(x)426def _HtmlAttrValue(x):427  return cgi.escape(x, quote=True)428def _AbsUrl(relative_url, context, unused_args):429  """Returns an absolute URL, given the current node as a relative URL.430  Assumes that the context has a value named 'base-url'.  This is a little like431  the HTML <base> tag, but implemented with HTML generation.432  Raises:433    UndefinedVariable if 'base-url' doesn't exist434  """435  # urljoin is flexible about trailing/leading slashes -- it will add or de-dupe436  # them437  return urlparse.urljoin(context.Lookup('base-url'), relative_url)438# See http://google-ctemplate.googlecode.com/svn/trunk/doc/howto.html for more439# escape types.440#441# Also, we might want to take a look at Django filters.442#443# This is a *public* constant, so that callers can use it construct their own444# formatter lookup dictionaries, and pass them in to Template.445_DEFAULT_FORMATTERS = {446    'html': cgi.escape,447    # The 'htmltag' name is deprecated.  The html-attr-value name is preferred448    # because it can be read with "as":449    #   {url|html-attr-value} means:450    #   "substitute 'url' as an HTML attribute value"451    'html-attr-value': _HtmlAttrValue,452    'htmltag': _HtmlAttrValue,453    'raw': lambda x: x,454    # Used for the length of a list.  Can be used for the size of a dictionary455    # too, though I haven't run into that use case.456    'size': lambda value: str(len(value)),457    # The argument is a dictionary, and we get a a=1&b=2 string back.458    'url-params': urlencode,459    # The argument is an atom, and it takes 'Search query?' -> 'Search+query%3F'460    'url-param-value': quote_plus,  # param is an atom461    # The default formatter, when no other default is specifier.  For debugging,462    # this could be lambda x: json.dumps(x, indent=2), but here we want to be463    # compatible to Python 2.4.464    'str': _ToString,465    # Just show a plain URL on an HTML page (without anchor text).466    'plain-url': lambda x: '<a href="%s">%s</a>' % (467        cgi.escape(x, quote=True), cgi.escape(x)),468    # A context formatter469    'AbsUrl': _AbsUrl,470    # Placeholders for "standard names".  We're not including them by default471    # since they require additional dependencies.  We can provide a part of the472    # "lookup chain" in formatters.py for people people want the dependency.473    # 'json' formats arbitrary data dictionary nodes as JSON strings.  'json'474    # and 'js-string' are identical (since a JavaScript string *is* JSON).  The475    # latter is meant to be serve as extra documentation when you want a string476    # argument only, which is a common case.477    'json': None,478    'js-string': None,479    }480def _Pluralize(value, unused_context, args):481  """Formatter to pluralize words."""482  if len(args) == 0:483    s, p = '', 's'484  elif len(args) == 1:485    s, p = '', args[0]486  elif len(args) == 2:487    s, p = args488  else:489    # Should have been checked at compile time490    raise AssertionError491  if value > 1:492    return p493  else:494    return s495def _Cycle(value, unused_context, args):496  """Cycle between various values on consecutive integers."""497  # @index starts from 1, so used 1-based indexing498  return args[(value - 1) % len(args)]499def _IsDebugMode(unused_value, context, unused_args):500  try:501    return bool(context.Lookup('debug'))502  except UndefinedVariable:503    return False504_DEFAULT_PREDICATES = {505    'singular?': lambda x: x == 1,506    'plural?': lambda x: x > 1,507    'Debug?': _IsDebugMode,508    }509def SplitMeta(meta):510  """Split and validate metacharacters.511  Example: '{}' -> ('{', '}')512  This is public so the syntax highlighter and other tools can use it.513  """514  n = len(meta)515  if n % 2 == 1:516    raise ConfigurationError(517        '%r has an odd number of metacharacters' % meta)518  return meta[:n//2], meta[n//2:]519_token_re_cache = {}520def MakeTokenRegex(meta_left, meta_right):521  """Return a (compiled) regular expression for tokenization.522  Args:523    meta_left, meta_right: e.g. '{' and '}'524  - The regular expressions are memoized.525  - This function is public so the syntax highlighter can use it.526  """527  key = meta_left, meta_right528  if key not in _token_re_cache:529    # - Need () grouping for re.split530    # - For simplicity, we allow all characters except newlines inside531    #   metacharacters ({} / [])532    _token_re_cache[key] = re.compile(533        r'(' +534        re.escape(meta_left) +535        r'.+?' +536        re.escape(meta_right) +537        r')')538  return _token_re_cache[key]539# Examples:540( LITERAL_TOKEN,  # "Hi"541  SUBSTITUTION_TOKEN,  # {var|html}542  SECTION_TOKEN,  # {.section name}543  REPEATED_SECTION_TOKEN,  # {.repeated section name}544  PREDICATE_TOKEN,  # {.predicate?}545  ALTERNATES_TOKEN,  # {.or}546  OR_TOKEN,  # {.or}547  END_TOKEN,  # {.end}548  ) = list(range(8))549def _MatchDirective(token):550  """Helper function for matching certain directives."""551  if token.startswith('.'):552    token = token[1:]553  else:554    return None, None  # Must start with .555  if token == 'alternates with':556    return ALTERNATES_TOKEN, token557  if token.startswith('or'):558    if token.strip() == 'or':559      return OR_TOKEN, None560    else:561      pred_str = token[2:].strip()562      return OR_TOKEN, pred_str563  if token == 'end':564    return END_TOKEN, None565  match = _SECTION_RE.match(token)566  if match:567    repeated, section_name = match.groups()568    if repeated:569      return REPEATED_SECTION_TOKEN, section_name570    else:571      return SECTION_TOKEN, section_name572  # {.if plural?} and {.plural?} are synonyms.  The ".if" will read better for573  # expressions, for people who like that kind of dirty thing...574  if token.startswith('if '):575    return PREDICATE_TOKEN, token[3:].strip()576  if token.endswith('?'):577    return PREDICATE_TOKEN, token578  return None, None  # no match579def _Tokenize(template_str, meta_left, meta_right):580  """Yields tokens, which are 2-tuples (TOKEN_TYPE, token_string)."""581  trimlen = len(meta_left)582  token_re = MakeTokenRegex(meta_left, meta_right)583  for line in template_str.splitlines(True):  # retain newlines584    tokens = token_re.split(line)585    # Check for a special case first.  If a comment or "block" directive is on a586    # line by itself (with only space surrounding it), then the space is587    # omitted.  For simplicity, we don't handle the case where we have 2588    # directives, say '{.end} # {#comment}' on a line.589    if len(tokens) == 3:590      # ''.isspace() == False, so work around that591      if (tokens[0].isspace() or not tokens[0]) and \592         (tokens[2].isspace() or not tokens[2]):593        token = tokens[1][trimlen : -trimlen]594        if token.startswith('#'):595          continue  # The whole line is omitted596        token_type, token = _MatchDirective(token)597        if token_type is not None:598          yield token_type, token  # Only yield the token, not space599          continue600    # The line isn't special; process it normally.601    for i, token in enumerate(tokens):602      if i % 2 == 0:603        yield LITERAL_TOKEN, token604      else:  # It's a "directive" in metachracters605        assert token.startswith(meta_left), repr(token)606        assert token.endswith(meta_right), repr(token)607        token = token[trimlen : -trimlen]608        # It's a comment609        if token.startswith('#'):610          continue611        if token.startswith('.'):612          literal = {613              '.meta-left': meta_left,614              '.meta-right': meta_right,615              '.space': ' ',616              '.tab': '\t',617              '.newline': '\n',618              }.get(token)619          if literal is not None:620            yield LITERAL_TOKEN, literal621            continue622          token_type, token = _MatchDirective(token)623          if token_type is not None:624            yield token_type, token625        else:  # Now we know the directive is a substitution.626          yield SUBSTITUTION_TOKEN, token627def CompileTemplate(628    template_str, builder=None, meta='{}', format_char='|',629    more_formatters=lambda x: None, more_predicates=lambda x: None,630    default_formatter='str'):631  """Compile the template string, calling methods on the 'program builder'.632  Args:633    template_str: The template string.  It should not have any compilation634        options in the header -- those are parsed by FromString/FromFile635    builder: The interface of _ProgramBuilder isn't fixed.  Use at your own636        risk.637    meta: The metacharacters to use, e.g. '{}', '[]'.638    more_formatters:639        Something that can map format strings to formatter functions.  One of:640          - A plain dictionary of names -> functions  e.g. {'html': cgi.escape}641          - A higher-order function which takes format strings and returns642            formatter functions.  Useful for when formatters have parsed643            arguments.644          - A FunctionRegistry instance for the most control.  This allows645            formatters which takes contexts as well.646    more_predicates:647        Like more_formatters, but for predicates.648    default_formatter: The formatter to use for substitutions that are missing a649        formatter.  The 'str' formatter the "default default" -- it just tries650        to convert the context value to a string in some unspecified manner.651  Returns:652    The compiled program (obtained from the builder)653  Raises:654    The various subclasses of CompilationError.  For example, if655    default_formatter=None, and a variable is missing a formatter, then656    MissingFormatter is raised.657  This function is public so it can be used by other tools, e.g. a syntax658  checking tool run before submitting a template to source control.659  """660  builder = builder or _ProgramBuilder(more_formatters, more_predicates)661  meta_left, meta_right = SplitMeta(meta)662  # : is meant to look like Python 3000 formatting {foo:.3f}.  According to663  # PEP 3101, that's also what .NET uses.664  # | is more readable, but, more importantly, reminiscent of pipes, which is665  # useful for multiple formatters, e.g. {name|js-string|html}666  if format_char not in (':', '|'):667    raise ConfigurationError(668        'Only format characters : and | are accepted (got %r)' % format_char)669  # If we go to -1, then we got too many {end}.  If end at 1, then we're missing670  # an {end}.671  balance_counter = 0672  for token_type, token in _Tokenize(template_str, meta_left, meta_right):673    if token_type == LITERAL_TOKEN:674      if token:675        builder.Append(token)676      continue677    if token_type in (SECTION_TOKEN, REPEATED_SECTION_TOKEN):678      builder.NewSection(token_type, token)679      balance_counter += 1680      continue681    if token_type == PREDICATE_TOKEN:682      # Everything of the form {.predicate?} starts a new predicate section683      block_made = builder.NewPredicateSection(token)684      balance_counter += 1685      continue686    if token_type == OR_TOKEN:687      builder.NewOrClause(token)688      continue689    if token_type == ALTERNATES_TOKEN:690      builder.AlternatesWith()691      continue692    if token_type == END_TOKEN:693      balance_counter -= 1694      if balance_counter < 0:695        # TODO: Show some context for errors696        raise TemplateSyntaxError(697            'Got too many %send%s statements.  You may have mistyped an '698            "earlier 'section' or 'repeated section' directive."699            % (meta_left, meta_right))700      builder.EndSection()701      continue...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
