class_docstr: EditableModule is a base class to enable classes that it inherits be
  converted to pure functions for higher order derivatives purpose.
  
  Usage
  -----
  To use this class, the user must implement the ``getparamnames`` method
  which returns a list of tensor names that affect the output of the method
  with name indicated in ``methodname``.
  
  Used in:
  
  - Classes of Density Functional Theory (DFT).
  
  - It can also be used in other classes that need to be converted to pure
    functions for higher order derivatives purpose.
  
  Examples
  --------
  >>> import torch
  >>> from deepchem.utils.differentiation_utils import EditableModule
  >>> class A(EditableModule):
  ...     def __init__(self, a):
  ...         self.b = a*a
  ...
  ...     def mult(self, x):
  ...         return self.b * x
  ...
  ...     def getparamnames(self, methodname, prefix=""):
  ...         if methodname == "mult":
  ...             return [prefix+"b"]
  ...         else:
  ...             raise KeyError()
  >>> a = torch.tensor(2.0).requires_grad_()
  >>> x = torch.tensor(0.4).requires_grad_()
  >>> alpha = A(a)
  >>> alpha.mult(x)
  tensor(1.6000, grad_fn=<MulBackward0>)
  >>> alpha.getparamnames("mult")
  ['b']
  >>> alpha.assertparams(alpha.mult, x)
  "mult" method check done
docstr: This method assert if method does not change the float tensor
  parameters of the object (i.e. it preserves the state of the object).
  
  Parameters
  ----------
  method: Callable
      The method of this class to be tested
  
  Raises
  ------
  KeyError
      If the method does not preserve the float tensors of the object.
docstr_tok: ["This","method","assert","if","method","does","not","change","the","float","tensor","parameters","of","the","object","(","i.e",".","it","preserves","the","state","of","the","object",")",".","Parameters","--","--","--","--","--","method",":","Callable","The","method","of","this","class","to","be","tested","Raises","--","--","--","KeyError","If","the","method","does","not","preserve","the","float","tensors","of","the","object","."]
code: def __assert_method_preserve(self, method, *args, **kwargs):
      """This method assert if method does not change the float tensor
      parameters of the object (i.e. it preserves the state of the object).
  
      Parameters
      ----------
      method: Callable
          The method of this class to be tested
  
      Raises
      ------
      KeyError
          If the method does not preserve the float tensors of the object.
  
      """
  
      all_params0, names0 = _get_tensors(self)
      all_params0 = [p.clone() for p in all_params0]
      method(*args, **kwargs)
      all_params1, names1 = _get_tensors(self)
  
      # now assert if all_params0 == all_params1
      clsname = method.__self__.__class__.__name__
      methodname = method.__name__
      msg = (
          "The method %s.%s does not preserve the object's float tensors: \n"
          % (clsname, methodname)
      )
      if len(all_params0) != len(all_params1):
          msg += "The number of parameters changed:\n"
          msg += "* number of object's parameters before: %d\n" % len(
              all_params0
          )
          msg += "* number of object's parameters after : %d\n" % len(
              all_params1
          )
          raise KeyError(msg)
  
      for pname, p0, p1 in zip(names0, all_params0, all_params1):
          if p0.shape != p1.shape:
              msg += "The shape of %s changed\n" % pname
              msg += "* (before) %s.shape: %s\n" % (pname, p0.shape)
              msg += "* (after ) %s.shape: %s\n" % (pname, p1.shape)
              raise KeyError(msg)
          if not torch.allclose(p0, p1):
              msg += "The value of %s changed\n" % pname
              msg += "* (before) %s: %s\n" % (pname, p0)
              msg += "* (after ) %s: %s\n" % (pname, p1)
              raise KeyError(msg)
  
imports: import inspect
  import warnings
  from abc import abstractmethod
  import copy
  import torch
  from typing import Sequence, Union, Dict, List, Callable, Any
  from deepchem.utils.attribute_utils import get_attr, set_attr, del_attr
label_desc: Use image node_id 9 for calling the EditableModule obj's underlying member method code with example usage: obj.__assert_method_preserve(method) without return types