66import inspect
77
88PY2 = sys .version_info [0 ] == 2
9- PY3 = sys .version_info [0 ] == 3
109
11- if PY3 :
12- string_types = str ,
13- else :
10+ if PY2 :
1411 string_types = basestring ,
12+ else :
13+ string_types = str ,
1514
1615def with_metaclass (meta , * bases ):
1716 """Create a base class with a metaclass."""
@@ -117,7 +116,7 @@ def __dir__(self):
117116 def __str__ (self ):
118117 return str (self .__wrapped__ )
119118
120- if PY3 :
119+ if not PY2 :
121120 def __bytes__ (self ):
122121 return bytes (self .__wrapped__ )
123122
@@ -130,10 +129,14 @@ def __repr__(self):
130129 def __reversed__ (self ):
131130 return reversed (self .__wrapped__ )
132131
133- if PY3 :
132+ if not PY2 :
134133 def __round__ (self ):
135134 return round (self .__wrapped__ )
136135
136+ if sys .hexversion >= 0x03070000 :
137+ def __mro_entries__ (self , bases ):
138+ return (self .__wrapped__ ,)
139+
137140 def __lt__ (self , other ):
138141 return self .__wrapped__ < other
139142
@@ -736,33 +739,34 @@ def resolve_path(module, name):
736739 path = name .split ('.' )
737740 attribute = path [0 ]
738741
739- original = getattr (parent , attribute )
740- for attribute in path [1 :]:
741- parent = original
742-
743- # We can't just always use getattr() because in doing
744- # that on a class it will cause binding to occur which
745- # will complicate things later and cause some things not
746- # to work. For the case of a class we therefore access
747- # the __dict__ directly. To cope though with the wrong
748- # class being given to us, or a method being moved into
749- # a base class, we need to walk the class hierarchy to
750- # work out exactly which __dict__ the method was defined
751- # in, as accessing it from __dict__ will fail if it was
752- # not actually on the class given. Fallback to using
753- # getattr() if we can't find it. If it truly doesn't
754- # exist, then that will fail.
755-
756- if inspect .isclass (original ):
757- for cls in inspect .getmro (original ):
742+ # We can't just always use getattr() because in doing
743+ # that on a class it will cause binding to occur which
744+ # will complicate things later and cause some things not
745+ # to work. For the case of a class we therefore access
746+ # the __dict__ directly. To cope though with the wrong
747+ # class being given to us, or a method being moved into
748+ # a base class, we need to walk the class hierarchy to
749+ # work out exactly which __dict__ the method was defined
750+ # in, as accessing it from __dict__ will fail if it was
751+ # not actually on the class given. Fallback to using
752+ # getattr() if we can't find it. If it truly doesn't
753+ # exist, then that will fail.
754+
755+ def lookup_attribute (parent , attribute ):
756+ if inspect .isclass (parent ):
757+ for cls in inspect .getmro (parent ):
758758 if attribute in vars (cls ):
759- original = vars (cls )[attribute ]
760- break
759+ return vars (cls )[attribute ]
761760 else :
762- original = getattr (original , attribute )
763-
761+ return getattr (parent , attribute )
764762 else :
765- original = getattr (original , attribute )
763+ return getattr (parent , attribute )
764+
765+ original = lookup_attribute (parent , attribute )
766+
767+ for attribute in path [1 :]:
768+ parent = original
769+ original = lookup_attribute (parent , attribute )
766770
767771 return (parent , attribute , original )
768772
0 commit comments