code: def _strategy(codes, context, is_unicode):
      """Convert SRE regex parse tree to strategy that generates strings matching
      that regex represented by that parse tree.
  
      `codes` is either a list of SRE regex elements representations or a
      particular element representation. Each element is a tuple of element code
      (as string) and parameters. E.g. regex 'ab[0-9]+' compiles to following
      elements:
  
          [
              (LITERAL, 97),
              (LITERAL, 98),
              (MAX_REPEAT, (1, 4294967295, [
                  (IN, [
                      (RANGE, (48, 57))
                  ])
              ]))
          ]
  
      The function recursively traverses regex element tree and converts each
      element to strategy that generates strings that match that element.
  
      Context stores
      1. List of groups (for backreferences)
      2. Active regex flags (e.g. IGNORECASE, DOTALL, UNICODE, they affect
         behavior of various inner strategies)
      """
  
      def recurse(codes):
          return _strategy(codes, context, is_unicode)
  
      if is_unicode:
          empty = ""
          to_char = hunichr
      else:
          empty = b""
          to_char = int_to_byte
          binary_char = st.binary(min_size=1, max_size=1)
  
      if not isinstance(codes, tuple):
          # List of codes
          strategies = []
  
          i = 0
          while i < len(codes):
              if (
                  codes[i][0] == sre.LITERAL
                  and not context.flags & re.IGNORECASE
              ):
                  # Merge subsequent "literals" into one `just()` strategy
                  # that generates corresponding text if no IGNORECASE
                  j = i + 1
                  while j < len(codes) and codes[j][0] == sre.LITERAL:
                      j += 1
  
                  if i + 1 < j:
                      strategies.append(
                          st.just(
                              empty.join(
                                  [
                                      to_char(charcode)
                                      for (_, charcode) in codes[i:j]
                                  ]
                              )
                          )
                      )
  
                      i = j
                      continue
  
              strategies.append(recurse(codes[i]))
              i += 1
  
          # We handle this separately at the top level, but some regex can
          # contain empty lists internally, so we need to handle this here too.
          if not strategies:
              return st.just(empty)
  
          if len(strategies) == 1:
              return strategies[0]
          return st.tuples(*strategies).map(empty.join)
      else:
          # Single code
          code, value = codes
          if code == sre.LITERAL:
              # Regex 'a' (single char)
              c = to_char(value)
              if (
                  context.flags & re.IGNORECASE
                  and c != c.swapcase()
                  and re.match(
                      re.escape(c), c.swapcase(), re.IGNORECASE
                  )
                  is not None
              ):
                  # We do the explicit check for swapped-case matching because
                  # eg 'ß'.upper() == 'SS' and ignorecase doesn't match it.
                  return st.sampled_from([c, c.swapcase()])
              return st.just(c)
  
          elif code == sre.NOT_LITERAL:
              # Regex '[^a]' (negation of a single char)
              c = to_char(value)
              blacklist = set(c)
              if (
                  context.flags & re.IGNORECASE
                  and re.match(
                      re.escape(c), c.swapcase(), re.IGNORECASE
                  )
                  is not None
              ):
                  blacklist |= set(c.swapcase())
              if is_unicode:
                  return st.characters(blacklist_characters=blacklist)
              else:
                  return binary_char.filter(
                      lambda c: c not in blacklist
                  )
  
          elif code == sre.IN:
              # Regex '[abc0-9]' (set of characters)
              negate = value[0][0] == sre.NEGATE
              if is_unicode:
                  builder = CharactersBuilder(negate, context.flags)
              else:
                  builder = BytesBuilder(negate, context.flags)
  
              for charset_code, charset_value in value:
                  if charset_code == sre.NEGATE:
                      # Regex '[^...]' (negation)
                      # handled by builder = CharactersBuilder(...) above
                      pass
                  elif charset_code == sre.LITERAL:
                      # Regex '[a]' (single char)
                      builder.add_char(charset_value)
                  elif charset_code == sre.RANGE:
                      # Regex '[a-z]' (char range)
                      low, high = charset_value
                      for char_code in hrange(low, high + 1):
                          builder.add_char(char_code)
                  elif charset_code == sre.CATEGORY:
                      # Regex '[\w]' (char category)
                      builder.add_category(charset_value)
                  else:  # pragma: no cover
                      # Currently there are no known code points other than
                      # handled here. This code is just future proofing
                      raise AssertionError(
                          "Unknown charset code: %s" % charset_code
                      )
              return builder.strategy
  
          elif code == sre.ANY:
              # Regex '.' (any char)
              if is_unicode:
                  if context.flags & re.DOTALL:
                      return st.characters()
                  return st.characters(blacklist_characters="\n")
              else:
                  if context.flags & re.DOTALL:
                      return binary_char
                  return binary_char.filter(lambda c: c != b"\n")
  
          elif code == sre.AT:
              # Regexes like '^...', '...$', '\bfoo', '\Bfoo'
              # An empty string (or newline) will match the token itself, but
              # we don't and can't check the position (eg '%' at the end)
              return st.just(empty)
  
          elif code == sre.SUBPATTERN:
              # Various groups: '(...)', '(:...)' or '(?P<name>...)'
              old_flags = context.flags
              if HAS_SUBPATTERN_FLAGS:  # pragma: no cover
                  # This feature is available only in specific Python versions
                  context.flags = (context.flags | value[1]) & ~value[2]
  
              strat = _strategy(value[-1], context, is_unicode)
  
              context.flags = old_flags
  
              if value[0]:
                  strat = update_group(value[0], strat)
  
              return strat
  
          elif code == sre.GROUPREF:
              # Regex '\\1' or '(?P=name)' (group reference)
              return reuse_group(value)
  
          elif code == sre.ASSERT:
              # Regex '(?=...)' or '(?<=...)' (positive lookahead/lookbehind)
              return recurse(value[1])
  
          elif code == sre.ASSERT_NOT:
              # Regex '(?!...)' or '(?<!...)' (negative lookahead/lookbehind)
              return st.just(empty)
  
          elif code == sre.BRANCH:
              # Regex 'a|b|c' (branch)
              return st.one_of([recurse(branch) for branch in value[1]])
  
          elif code in [sre.MIN_REPEAT, sre.MAX_REPEAT]:
              # Regexes 'a?', 'a*', 'a+' and their non-greedy variants
              # (repeaters)
              at_least, at_most, subregex = value
              if at_most == sre.MAXREPEAT:
                  at_most = None
              if at_least == 0 and at_most == 1:
                  return st.just(empty) | recurse(subregex)
              return st.lists(
                  recurse(subregex), min_size=at_least, max_size=at_most
              ).map(empty.join)
  
          elif code == sre.GROUPREF_EXISTS:
              # Regex '(?(id/name)yes-pattern|no-pattern)'
              # (if group exists choice)
              return group_conditional(
                  value[0],
                  recurse(value[1]),
                  recurse(value[2]) if value[2] else st.just(empty),
              )
  
          else:  # pragma: no cover
              # Currently there are no known code points other than handled here.
              # This code is just future proofing
              raise AssertionError(
                  "Unknown code point: %s" % repr(code)
              )
  
imports: from __future__ import absolute_import, division, print_function
  import operator
  import re
  import sre_constants
  import sre_parse
  import sys
  import hypothesis.strategies
  from hypothesis import reject
  from hypothesis.internal.charmap import as_general_categories, categories
  from hypothesis.internal.compat import PY3, hrange, hunichr, int_to_byte, text_type
label_desc: Use image node_id 8 for calling a global function with example usage: _strategy(codes, context, is_unicode) and returns: _strategy, st, st, strategies, st, st, st, binary_char, builder, st, binary_char, st, st, binary_char, strat, reuse_group, recurse, st, st, st, unknown, group_conditional