text: from rope.base import ast, evaluate, builtins, pyobjects
  from rope.refactor import patchedast, occurrences
  
  
  class Wildcard(object):
  
      def get_name(self):
          """Return the name of this wildcard"""
  
      def matches(self, suspect, arg):
          """Return `True` if `suspect` matches this wildcard"""
  
  
  class Suspect(object):
  
      def __init__(self, pymodule, node, name):
          self.name = name
          self.pymodule = pymodule
          self.node = node
  
  
  class DefaultWildcard(object):
      """The default restructuring wildcard
  
      The argument passed to this wildcard is in the
      ``key1=value1,key2=value2,...`` format.  Possible keys are:
  
      * name - for checking the reference
      * type - for checking the type
      * object - for checking the object
      * instance - for checking types but similar to builtin isinstance
      * exact - matching only occurrences with the same name as the wildcard
      * unsure - matching unsure occurrences
  
      """
  
      def __init__(self, project):
          self.project = project
  
      def get_name(self):
          return 'default'
  
      def matches(self, suspect, arg=''):
          args = parse_arg(arg)
  
          if not self._check_exact(args, suspect):
              return False
          if not self._check_object(args, suspect):
              return False
          return True
  
      def _check_object(self, args, suspect):
          kind = None
          expected = None
          unsure = args.get('unsure', False)
          for check in ['name', 'object', 'type', 'instance']:
              if check in args:
                  kind = check
                  expected = args[check]
              if expected is not None:
                  checker = _CheckObject(self.project, expected,
                                         kind, unsure=unsure)
                  return checker(suspect.pymodule, suspect.node)
          return True
  
      def _check_exact(self, args, suspect):
          node = suspect.node
          if args.get('exact'):
              if not isinstance(node, ast.Name) or not node.id == suspect.name:
                  return False
          else:
              if not isinstance(node, ast.expr):
                  return False
          return True
  
  
  def parse_arg(arg):
      if isinstance(arg, dict):
          return arg
      result = {}
      tokens = arg.split(',')
      for token in tokens:
          if '=' in token:
              parts = token.split('=', 1)
              result[parts[0].strip()] = parts[1].strip()
          else:
              result[token.strip()] = True
      return result
  
  
  class _CheckObject(object):
  
      def __init__(self, project, expected, kind='object', unsure=False):
          self.project = project
          self.kind = kind
          self.unsure = unsure
          self.expected = self._evaluate(expected)
  
      def __call__(self, pymodule, node):
          pyname = self._evaluate_node(pymodule, node)
          if pyname is None or self.expected is None:
              return self.unsure
          if self._unsure_pyname(pyname, unbound=self.kind == 'name'):
              return True
          if self.kind == 'name':
              return self._same_pyname(self.expected, pyname)
          else:
              pyobject = pyname.get_object()
              if self.kind == 'object':
                  objects = [pyobject]
              if self.kind == 'type':
                  objects = [pyobject.get_type()]
              if self.kind == 'instance':
                  objects = [pyobject]
                  objects.extend(self._get_super_classes(pyobject))
                  objects.extend(self._get_super_classes(pyobject.get_type()))
              for pyobject in objects:
                  if self._same_pyobject(self.expected.get_object(), pyobject):
                      return True
              return False
  
      def _get_super_classes(self, pyobject):
          result = []
          if isinstance(pyobject, pyobjects.AbstractClass):
              for superclass in pyobject.get_superclasses():
                  result.append(superclass)
                  result.extend(self._get_super_classes(superclass))
          return result
  
      def _same_pyobject(self, expected, pyobject):
          return expected == pyobject
  
      def _same_pyname(self, expected, pyname):
          return occurrences.same_pyname(expected, pyname)
  
      def _unsure_pyname(self, pyname, unbound=True):
          return self.unsure and occurrences.unsure_pyname(pyname, unbound)
  
      def _split_name(self, name):
          parts = name.split('.')
          expression, kind = parts[0], parts[-1]
          if len(parts) == 1:
              kind = 'name'
          return expression, kind
  
      def _evaluate_node(self, pymodule, node):
          scope = pymodule.get_scope().get_inner_scope_for_line(node.lineno)
          expression = node
          if isinstance(expression, ast.Name) and \
             isinstance(expression.ctx, ast.Store):
              start, end = patchedast.node_region(expression)
              text = pymodule.source_code[start:end]
              return evaluate.eval_str(scope, text)
          else:
              return evaluate.eval_node(scope, expression)
  
      def _evaluate(self, code):
          attributes = code.split('.')
          pyname = None
          if attributes[0] in ('__builtin__', '__builtins__'):
              class _BuiltinsStub(object):
                  def get_attribute(self, name):
                      return builtins.builtins[name]
  
                  def __getitem__(self, name):
                      return builtins.builtins[name]
  
                  def __contains__(self, name):
                      return name in builtins.builtins
              pyobject = _BuiltinsStub()
          else:
              pyobject = self.project.pycore.get_module(attributes[0])
          for attribute in attributes[1:]:
              pyname = pyobject[attribute]
              if pyname is None:
                  return None
              pyobject = pyname.get_object()
          return pyname
  