@@ -312,6 +312,54 @@ class _FieldContainer(object):
312312 """
313313 __slots__ = ["fld" ]
314314
315+ def copy (self ):
316+ # type: () -> Any
317+ def _copy_attr (attr ):
318+ # type: (Any) -> Any
319+ if hasattr (attr , "copy" ):
320+ return attr .copy ()
321+ return attr
322+
323+ cls = self .__class__
324+ other = cls .__new__ (cls )
325+
326+ if hasattr (self , "__dict__" ):
327+ other .__dict__ = {
328+ key : _copy_attr (value )
329+ for key , value in self .__dict__ .items ()
330+ }
331+
332+ copied_slots = set ()
333+ for base in cls .__mro__ :
334+ slots = base .__dict__ .get ("__slots__" , ())
335+ if isinstance (slots , str ):
336+ slots = (slots ,)
337+ for slot in slots :
338+ if slot in ("__dict__" , "__weakref__" ) or slot in copied_slots :
339+ continue
340+ slot_descriptor = base .__dict__ .get (slot )
341+ if getattr (cls , slot , None ) is not slot_descriptor :
342+ continue
343+ copied_slots .add (slot )
344+ try :
345+ value = getattr (self , slot )
346+ except AttributeError :
347+ continue
348+ setattr (other , slot , _copy_attr (value ))
349+
350+ return other
351+
352+ def __setattr__ (self , attr , value ):
353+ # type: (str, Any) -> None
354+ try :
355+ object .__setattr__ (self , attr , value )
356+ except AttributeError as ex :
357+ try :
358+ fld = object .__getattribute__ (self , "fld" )
359+ except AttributeError :
360+ raise ex
361+ setattr (fld , attr , value )
362+
315363 def __getattr__ (self , attr ):
316364 # type: (str) -> Any
317365 return getattr (self .fld , attr )
0 commit comments