@@ -213,6 +213,7 @@ def cfg_to_args(path='setup.cfg'):
213213 raise DistutilsFileError (
214214 '%s from the extra_files option in setup.cfg does not '
215215 'exist' % filename )
216+
216217 # Unfortunately the only really sensible way to do this is to
217218 # monkey-patch the manifest_maker class
218219 @monkeypatch_method (manifest_maker )
@@ -536,19 +537,41 @@ def split_csv(value):
536537 return value
537538
538539
539- def monkeypatch_method (cls ):
540- """A function decorator to monkey-patch a method of the same name on the
541- given class.
542- """
540+ class MonkeyPatcher (object ):
541+ def __init__ (self ):
542+ self ._patched = set ()
543+
544+ def __call__ (self , cls ):
545+ """
546+ A function decorator to monkey-patch a method of the same name on the
547+ given class.
548+ """
543549
544- def wrapper (func ):
545- orig = getattr (cls , func .__name__ , None )
546- if orig and not hasattr (orig , '_orig' ): # Already patched
547- setattr (func , '_orig' , orig )
550+ def wrapper (func ):
551+ orig = getattr (cls , func .__name__ , None )
552+ if hasattr (orig , '_orig' ): # Already patched
553+ return orig
554+
555+ func ._orig = orig
548556 setattr (cls , func .__name__ , func )
549- return func
557+ self ._patched .add ((cls , orig ))
558+
559+ return func
560+
561+ return wrapper
562+
563+ def unpatch_all (self ):
564+ """
565+ Remove all monkey-patches.
566+ """
567+
568+ for cls , func in self ._patched :
569+ setattr (cls , func .__name__ , func )
570+
571+ self ._patched .clear ()
572+
550573
551- return wrapper
574+ monkeypatch_method = MonkeyPatcher ()
552575
553576
554577# The following classes are used to hack Distribution.command_options a bit
0 commit comments