parameters: (self, stacklevel=2)
return_statement: return False
docstring: stacklevel is the depth a which this function is called, to
              issue useful warnings to the user.
docstring_summary: stacklevel is the depth a which this function is called, to
              issue useful warnings to the user.
docstring_tokens: stacklevel is the depth a which this function is called to issue useful warnings to the user .
function: def _check_previous_func_code(self, stacklevel=2):
          """
              stacklevel is the depth a which this function is called, to
              issue useful warnings to the user.
          """
          # First check if our function is in the in-memory store.
          # Using the in-memory store not only makes things faster, but it
          # also renders us robust to variations of the files when the
          # in-memory version of the code does not vary
          try:
              if self.func in _FUNCTION_HASHES:
                  # We use as an identifier the id of the function and its
                  # hash. This is more likely to falsely change than have hash
                  # collisions, thus we are on the safe side.
                  func_hash = self._hash_func()
                  if func_hash == _FUNCTION_HASHES[self.func]:
                      return True
          except TypeError:
              # Some callables are not hashable
              pass
  
          # Here, we go through some effort to be robust to dynamically
          # changing code and collision. We cannot inspect.getsource
          # because it is not reliable when using IPython's magic "%run".
          func_code, source_file, first_line = self.func_code_info
          func_id = _build_func_identifier(self.func)
  
          try:
              old_func_code, old_first_line =\
                  extract_first_line(
                      self.store_backend.get_cached_func_code([func_id]))
          except (IOError, OSError):  # some backend can also raise OSError
              self._write_func_code(func_code, first_line)
              return False
          if old_func_code == func_code:
              return True
  
          # We have differing code, is this because we are referring to
          # different functions, or because the function we are referring to has
          # changed?
  
          _, func_name = get_func_name(self.func, resolv_alias=False,
                                       win_characters=False)
          if old_first_line == first_line == -1 or func_name == '<lambda>':
              if not first_line == -1:
                  func_description = ("{0} ({1}:{2})"
                                      .format(func_name, source_file,
                                              first_line))
              else:
                  func_description = func_name
              warnings.warn(JobLibCollisionWarning(
                  "Cannot detect name collisions for function '{0}'"
                  .format(func_description)), stacklevel=stacklevel)
  
          # Fetch the code at the old location and compare it. If it is the
          # same than the code store, we have a collision: the code in the
          # file has not changed, but the name we have is pointing to a new
          # code block.
          if not old_first_line == first_line and source_file is not None:
              possible_collision = False
              if os.path.exists(source_file):
                  _, func_name = get_func_name(self.func, resolv_alias=False)
                  num_lines = len(func_code.split('\n'))
                  with open_py_source(source_file) as f:
                      on_disk_func_code = f.readlines()[
                          old_first_line - 1:old_first_line - 1 + num_lines - 1]
                  on_disk_func_code = ''.join(on_disk_func_code)
                  possible_collision = (on_disk_func_code.rstrip() ==
                                        old_func_code.rstrip())
              else:
                  possible_collision = source_file.startswith('<doctest ')
              if possible_collision:
                  warnings.warn(JobLibCollisionWarning(
                      'Possible name collisions between functions '
                      "'%s' (%s:%i) and '%s' (%s:%i)" %
                      (func_name, source_file, old_first_line,
                       func_name, source_file, first_line)),
                      stacklevel=stacklevel)
  
          # The function has changed, wipe the cache directory.
          # XXX: Should be using warnings, and giving stacklevel
          if self._verbose > 10:
              _, func_name = get_func_name(self.func, resolv_alias=False)
              self.warn("Function {0} (identified by {1}) has changed"
                        ".".format(func_name, func_id))
          self.clear(warn=True)
          return False
function_tokens: def _check_previous_func_code ( self , stacklevel = 2 ) : # First check if our function is in the in-memory store. # Using the in-memory store not only makes things faster, but it # also renders us robust to variations of the files when the # in-memory version of the code does not vary try : if self . func in _FUNCTION_HASHES : # We use as an identifier the id of the function and its # hash. This is more likely to falsely change than have hash # collisions, thus we are on the safe side. func_hash = self . _hash_func ( ) if func_hash == _FUNCTION_HASHES [ self . func ] : return True except TypeError : # Some callables are not hashable pass # Here, we go through some effort to be robust to dynamically # changing code and collision. We cannot inspect.getsource # because it is not reliable when using IPython's magic "%run". func_code , source_file , first_line = self . func_code_info func_id = _build_func_identifier ( self . func ) try : old_func_code , old_first_line = extract_first_line ( self . store_backend . get_cached_func_code ( [ func_id ] ) ) except ( IOError , OSError ) : # some backend can also raise OSError self . _write_func_code ( func_code , first_line ) return False if old_func_code == func_code : return True # We have differing code, is this because we are referring to # different functions, or because the function we are referring to has # changed? _ , func_name = get_func_name ( self . func , resolv_alias = False , win_characters = False ) if old_first_line == first_line == - 1 or func_name == '<lambda>' : if not first_line == - 1 : func_description = ( "{0} ({1}:{2})" . format ( func_name , source_file , first_line ) ) else : func_description = func_name warnings . warn ( JobLibCollisionWarning ( "Cannot detect name collisions for function '{0}'" . format ( func_description ) ) , stacklevel = stacklevel ) # Fetch the code at the old location and compare it. If it is the # same than the code store, we have a collision: the code in the # file has not changed, but the name we have is pointing to a new # code block. if not old_first_line == first_line and source_file is not None : possible_collision = False if os . path . exists ( source_file ) : _ , func_name = get_func_name ( self . func , resolv_alias = False ) num_lines = len ( func_code . split ( '\n' ) ) with open_py_source ( source_file ) as f : on_disk_func_code = f . readlines ( ) [ old_first_line - 1 : old_first_line - 1 + num_lines - 1 ] on_disk_func_code = '' . join ( on_disk_func_code ) possible_collision = ( on_disk_func_code . rstrip ( ) == old_func_code . rstrip ( ) ) else : possible_collision = source_file . startswith ( '<doctest ' ) if possible_collision : warnings . warn ( JobLibCollisionWarning ( 'Possible name collisions between functions ' "'%s' (%s:%i) and '%s' (%s:%i)" % ( func_name , source_file , old_first_line , func_name , source_file , first_line ) ) , stacklevel = stacklevel ) # The function has changed, wipe the cache directory. # XXX: Should be using warnings, and giving stacklevel if self . _verbose > 10 : _ , func_name = get_func_name ( self . func , resolv_alias = False ) self . warn ( "Function {0} (identified by {1}) has changed" "." . format ( func_name , func_id ) ) self . clear ( warn = True ) return False