mirror of
https://github.com/python/cpython.git
synced 2025-10-03 21:55:41 +00:00
Add support for static and class methods.
This commit is contained in:
parent
88470ec348
commit
9a7e77401b
1 changed files with 36 additions and 3 deletions
|
@ -65,6 +65,7 @@ def xreload(mod):
|
||||||
for name in newnames - oldnames:
|
for name in newnames - oldnames:
|
||||||
modns[name] = tmpns[name]
|
modns[name] = tmpns[name]
|
||||||
# Delete names that are no longer current
|
# Delete names that are no longer current
|
||||||
|
# XXX What to do about renamed objects?
|
||||||
for name in oldnames - newnames - {"__name__"}:
|
for name in oldnames - newnames - {"__name__"}:
|
||||||
del modns[name]
|
del modns[name]
|
||||||
# Now update the rest in place
|
# Now update the rest in place
|
||||||
|
@ -86,6 +87,9 @@ def _update(oldobj, newobj):
|
||||||
Returns:
|
Returns:
|
||||||
either oldobj, updated in place, or newobj.
|
either oldobj, updated in place, or newobj.
|
||||||
"""
|
"""
|
||||||
|
if oldobj is newobj:
|
||||||
|
# Probably something imported
|
||||||
|
return newobj
|
||||||
if type(oldobj) is not type(newobj):
|
if type(oldobj) is not type(newobj):
|
||||||
# Cop-out: if the type changed, give up
|
# Cop-out: if the type changed, give up
|
||||||
return newobj
|
return newobj
|
||||||
|
@ -98,11 +102,18 @@ def _update(oldobj, newobj):
|
||||||
return _update_function(oldobj, newobj)
|
return _update_function(oldobj, newobj)
|
||||||
if isinstance(newobj, types.MethodType):
|
if isinstance(newobj, types.MethodType):
|
||||||
return _update_method(oldobj, newobj)
|
return _update_method(oldobj, newobj)
|
||||||
# XXX Support class methods, static methods, other decorators
|
if isinstance(newobj, classmethod):
|
||||||
|
return _update_classmethod(oldobj, newobj)
|
||||||
|
if isinstance(newobj, staticmethod):
|
||||||
|
return _update_staticmethod(oldobj, newobj)
|
||||||
|
# XXX How to support decorators?
|
||||||
# Not something we recognize, just give up
|
# Not something we recognize, just give up
|
||||||
return newobj
|
return newobj
|
||||||
|
|
||||||
|
|
||||||
|
# All of the following functions have the same signature as _update()
|
||||||
|
|
||||||
|
|
||||||
def _update_function(oldfunc, newfunc):
|
def _update_function(oldfunc, newfunc):
|
||||||
"""Update a function object."""
|
"""Update a function object."""
|
||||||
oldfunc.__doc__ = newfunc.__doc__
|
oldfunc.__doc__ = newfunc.__doc__
|
||||||
|
@ -116,7 +127,7 @@ def _update_function(oldfunc, newfunc):
|
||||||
def _update_method(oldmeth, newmeth):
|
def _update_method(oldmeth, newmeth):
|
||||||
"""Update a method object."""
|
"""Update a method object."""
|
||||||
# XXX What if im_func is not a function?
|
# XXX What if im_func is not a function?
|
||||||
_update_function(oldmeth.im_func, newmeth.im_func)
|
_update(oldmeth.im_func, newmeth.im_func)
|
||||||
return oldmeth
|
return oldmeth
|
||||||
|
|
||||||
|
|
||||||
|
@ -132,5 +143,27 @@ def _update_class(oldclass, newclass):
|
||||||
for name in oldnames - newnames:
|
for name in oldnames - newnames:
|
||||||
delattr(oldclass, name)
|
delattr(oldclass, name)
|
||||||
for name in oldnames & newnames - {"__dict__", "__doc__"}:
|
for name in oldnames & newnames - {"__dict__", "__doc__"}:
|
||||||
setattr(oldclass, name, newdict[name])
|
setattr(oldclass, name, _update(olddict[name], newdict[name]))
|
||||||
return oldclass
|
return oldclass
|
||||||
|
|
||||||
|
|
||||||
|
def _update_classmethod(oldcm, newcm):
|
||||||
|
"""Update a classmethod update."""
|
||||||
|
# While we can't modify the classmethod object itself (it has no
|
||||||
|
# mutable attributes), we *can* extract the underlying function
|
||||||
|
# (by calling __get__(), which returns a method object) and update
|
||||||
|
# it in-place. We don't have the class available to pass to
|
||||||
|
# __get__() but any object except None will do.
|
||||||
|
_update(oldcm.__get__(0), newcm.__get__(0))
|
||||||
|
return newcm
|
||||||
|
|
||||||
|
|
||||||
|
def _update_staticmethod(oldsm, newsm):
|
||||||
|
"""Update a staticmethod update."""
|
||||||
|
# While we can't modify the staticmethod object itself (it has no
|
||||||
|
# mutable attributes), we *can* extract the underlying function
|
||||||
|
# (by calling __get__(), which returns it) and update it in-place.
|
||||||
|
# We don't have the class available to pass to __get__() but any
|
||||||
|
# object except None will do.
|
||||||
|
_update(oldsm.__get__(0), newsm.__get__(0))
|
||||||
|
return newsm
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue