old_contents: """ Processing of docstrings, which means parsing for types. """
  
  import re
  
  import evaluate
  import parsing
  
  DOCSTRING_PARAM_PATTERNS = [
      r'\s*:type\s+%s:\s*([^\n]+)', # Sphinx
      r'\s*@type\s+%s:\s*([^\n]+)', # Epidoc
  ]
  
  DOCSTRING_RETURN_PATTERNS = [
          re.compile(r'\s*:rtype:\s*([^\n]+)', re.M), # Sphinx
          re.compile(r'\s*@rtype:\s*([^\n]+)', re.M), # Epidoc
  ]
  
  #@cache.memoize_default()  # TODO add
  def follow_param(param):
      func = param.parent_function
      #print func, param, param.parent_function
      param_str = search_param_in_docstr(func.docstr, str(param.get_name()))
      user_position = (1, 0)
  
      if param_str is not None:
  
          # Try to import module part in dotted name.
          # (e.g., 'threading' in 'threading.Thread').
          if '.' in param_str:
              param_str = 'import {0}\n{1}'.format(
                  param_str.rsplit('.', 1)[0],
                  param_str)
              user_position = (2, 0)
  
          p = parsing.PyFuzzyParser(param_str, None, user_position,
                                    no_docstr=True)
          p.user_stmt.parent = func
          return evaluate.follow_statement(p.user_stmt)
      return []
  
  
  def search_param_in_docstr(docstr, param_str):
      # look at #40 to see definitions of those params
      patterns = [ re.compile(p % re.escape(param_str)) for p in DOCSTRING_PARAM_PATTERNS ]
      for pattern in patterns:
          match = pattern.search(docstr)
          if match:
              return match.group(1)
  
      return None
  
  
  def find_return_types(func):
      if isinstance(func, evaluate.InstanceElement):
          func = func.var
  
      if isinstance(func, evaluate.Function):
          func = func.base_func
  
      type_str = search_return_in_docstr(func.docstr)
      if not type_str:
          return []
  
      p = parsing.PyFuzzyParser(type_str, None, (1, 0), no_docstr=True)
      p.user_stmt.parent = func
      return list(evaluate.follow_statement(p.user_stmt))
  
  def search_return_in_docstr(code):
      for p in DOCSTRING_RETURN_PATTERNS:
          match = p.search(code)
          if match:
              return match.group(1)
  
new_contents: """ Processing of docstrings, which means parsing for types. """
  
  import re
  
  import evaluate
  import parsing
  
  DOCSTRING_PARAM_PATTERNS = [
      r'\s*:type\s+%s:\s*([^\n]+)', # Sphinx
      r'\s*@type\s+%s:\s*([^\n]+)', # Epidoc
  ]
  
  DOCSTRING_RETURN_PATTERNS = [
          re.compile(r'\s*:rtype:\s*([^\n]+)', re.M), # Sphinx
          re.compile(r'\s*@rtype:\s*([^\n]+)', re.M), # Epidoc
  ]
  
  #@cache.memoize_default()  # TODO add
  def follow_param(param):
      func = param.parent_function
      #print func, param, param.parent_function
      param_str = search_param_in_docstr(func.docstr, str(param.get_name()))
      user_position = (1, 0)
  
      if param_str is not None:
  
          # Try to import module part in dotted name.
          # (e.g., 'threading' in 'threading.Thread').
          if '.' in param_str:
              param_str = 'import {0}\n{1}'.format(
                  param_str.rsplit('.', 1)[0],
                  param_str)
              user_position = (2, 0)
  
          p = parsing.PyFuzzyParser(param_str, None, user_position,
                                    no_docstr=True)
          return evaluate.follow_statement(p.user_stmt)
      return []
  
  
  def search_param_in_docstr(docstr, param_str):
      # look at #40 to see definitions of those params
      patterns = [ re.compile(p % re.escape(param_str)) for p in DOCSTRING_PARAM_PATTERNS ]
      for pattern in patterns:
          match = pattern.search(docstr)
          if match:
              return match.group(1)
  
      return None
  
  
  def find_return_types(func):
      if isinstance(func, evaluate.InstanceElement):
          func = func.var
  
      if isinstance(func, evaluate.Function):
          func = func.base_func
  
      type_str = search_return_in_docstr(func.docstr)
      if not type_str:
          return []
  
      p = parsing.PyFuzzyParser(type_str, None, (1, 0), no_docstr=True)
      p.user_stmt.parent = func
      return list(evaluate.follow_statement(p.user_stmt))
  
  def search_return_in_docstr(code):
      for p in DOCSTRING_RETURN_PATTERNS:
          match = p.search(code)
          if match:
              return match.group(1)
  
subject: Make the failing test pass; dotted type works now