[Python-checkins] python/dist/src/Lib copy.py,1.34,1.35

gvanrossum@users.sourceforge.net gvanrossum@users.sourceforge.net
Fri, 07 Feb 2003 09:30:22 -0800


Update of /cvsroot/python/python/dist/src/Lib
In directory sc8-pr-cvs1:/tmp/cvs-serv11280

Modified Files:
	copy.py 
Log Message:
Add support for copy_reg.dispatch_table.

Rewrote copy() and deepcopy() without avoidable try/except statements;
getattr(x, name, None) or dict.get() are much faster than try/except.


Index: copy.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/copy.py,v
retrieving revision 1.34
retrieving revision 1.35
diff -C2 -d -r1.34 -r1.35
*** copy.py	6 Feb 2003 22:57:00 -0000	1.34
--- copy.py	7 Feb 2003 17:30:16 -0000	1.35
***************
*** 49,56 ****
  """
  
- # XXX need to support copy_reg here too...
- 
  import types
! from copy_reg import _better_reduce
  
  class Error(Exception):
--- 49,54 ----
  """
  
  import types
! from copy_reg import _better_reduce, dispatch_table
  
  class Error(Exception):
***************
*** 71,93 ****
      """
  
!     try:
!         copierfunction = _copy_dispatch[type(x)]
!     except KeyError:
!         try:
!             copier = x.__copy__
!         except AttributeError:
!             try:
!                 reductor = x.__class__.__reduce__
!                 if reductor == object.__reduce__:
!                     reductor = _better_reduce
!             except AttributeError:
!                 raise Error("un(shallow)copyable object of type %s" % type(x))
!             else:
!                 y = _reconstruct(x, reductor(x), 0)
!         else:
!             y = copier()
!     else:
!         y = copierfunction(x)
!     return y
      
  
--- 69,91 ----
      """
  
!     cls = type(x)
! 
!     copier = _copy_dispatch.get(cls)
!     if copier:
!         return copier(x)
! 
!     copier = getattr(cls, "__copy__", None)
!     if copier:
!         return copier(x)
! 
!     reductor = dispatch_table.get(cls)
!     if not reductor:
!         reductor = getattr(cls, "__reduce__", None)
!         if reductor == object.__reduce__:
!             reductor = _better_reduce
!         elif not reductor:
!             raise Error("un(shallow)copyable object of type %s" % cls)
! 
!     return _reconstruct(x, reductor(x), 0)
      
  
***************
*** 154,158 ****
  del d
  
! def deepcopy(x, memo = None):
      """Deep copy operation on arbitrary Python objects.
  
--- 152,156 ----
  del d
  
! def deepcopy(x, memo=None, _nil=[]):
      """Deep copy operation on arbitrary Python objects.
  
***************
*** 162,194 ****
      if memo is None:
          memo = {}
      d = id(x)
!     if d in memo:
!         return memo[d]
!     try:
!         copierfunction = _deepcopy_dispatch[type(x)]
!     except KeyError:
          try:
!             issc = issubclass(type(x), type)
!         except TypeError:
              issc = 0
          if issc:
!             y = _deepcopy_dispatch[type](x, memo)
          else:
!             try:
!                 copier = x.__deepcopy__
!             except AttributeError:
!                 try:
!                     reductor = x.__class__.__reduce__
!                     if reductor == object.__reduce__:
!                         reductor = _better_reduce
!                 except AttributeError:
!                     raise Error("un(shallow)copyable object of type %s" %
!                                 type(x))
!                 else:
!                     y = _reconstruct(x, reductor(x), 1, memo)
!             else:
!                 y = copier(memo)
!     else:
!         y = copierfunction(x, memo)
      memo[d] = y
      _keep_alive(x, memo) # Make sure x lives at least as long as d
--- 160,196 ----
      if memo is None:
          memo = {}
+ 
      d = id(x)
!     y = memo.get(d, _nil)
!     if y is not _nil:
!         return y
! 
!     cls = type(x)
! 
!     copier = _deepcopy_dispatch.get(cls)
!     if copier:
!         y = copier(x, memo)
!     else:
          try:
!             issc = issubclass(cls, type)
!         except TypeError: # cls is not a class (old Boost; see SF #502085)
              issc = 0
          if issc:
!             copier = _deepcopy_atomic
          else:
!             copier = getattr(cls, "__deepcopy__", None)
! 
!         if copier:
!             y = copier(x, memo)
!         else:
!             reductor = dispatch_table.get(cls)
!             if not reductor:
!                 reductor = getattr(cls, "__reduce__", None)
!                 if reductor == object.__reduce__:
!                     reductor = _better_reduce
!                 elif not reductor:
!                     raise Error("un(deep)copyable object of type %s" % cls)
!             y = _reconstruct(x, reductor(x), 1, memo)
! 
      memo[d] = y
      _keep_alive(x, memo) # Make sure x lives at least as long as d
***************
*** 381,385 ****
              for key, value in state.iteritems():
                  setattr(self, key, value)
!         def __deepcopy__(self, memo = None):
              new = self.__class__(deepcopy(self.arg, memo))
              new.a = self.a
--- 383,387 ----
              for key, value in state.iteritems():
                  setattr(self, key, value)
!         def __deepcopy__(self, memo=None):
              new = self.__class__(deepcopy(self.arg, memo))
              new.a = self.a