6868ImportError exception, it is silently ignored.
6969"""
7070
71+ import atexit
7172import sys
7273import os
7374import re
8687USER_BASE = None
8788
8889
90+ _no_builtin = object ()
91+
92+ def _patch_builtins (** items ):
93+ # When patching builtins, we make some objects almost immortal
94+ # (builtins are only reclaimed at the very end of the interpreter
95+ # shutdown sequence). To avoid keeping to many references alive,
96+ # we register callbacks to undo our builtins additions.
97+ old_items = {k : getattr (builtins , k , _no_builtin ) for k in items }
98+ def unpatch (old_items = old_items ):
99+ for k , v in old_items .items ():
100+ if v is _no_builtin :
101+ delattr (builtins , k )
102+ else :
103+ setattr (builtins , k , v )
104+ for k , v in items .items ():
105+ setattr (builtins , k , v )
106+ atexit .register (unpatch )
107+
108+
89109def makepath (* paths ):
90110 dir = os .path .join (* paths )
91111 try :
@@ -357,8 +377,7 @@ def __call__(self, code=None):
357377 except :
358378 pass
359379 raise SystemExit (code )
360- builtins .quit = Quitter ('quit' )
361- builtins .exit = Quitter ('exit' )
380+ _patch_builtins (quit = Quitter ('quit' ), exit = Quitter ('exit' ))
362381
363382
364383class _Printer (object ):
@@ -423,20 +442,20 @@ def __call__(self):
423442
424443def setcopyright ():
425444 """Set 'copyright' and 'credits' in builtins"""
426- builtins . copyright = _Printer ("copyright" , sys .copyright )
445+ _patch_builtins ( copyright = _Printer ("copyright" , sys .copyright ) )
427446 if sys .platform [:4 ] == 'java' :
428- builtins . credits = _Printer (
447+ _patch_builtins ( credits = _Printer (
429448 "credits" ,
430- "Jython is maintained by the Jython developers (www.jython.org)." )
449+ "Jython is maintained by the Jython developers (www.jython.org)." ))
431450 else :
432- builtins . credits = _Printer ("credits" , """\
451+ _patch_builtins ( credits = _Printer ("credits" , """\
433452 Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands
434- for supporting Python development. See www.python.org for more information.""" )
453+ for supporting Python development. See www.python.org for more information.""" ))
435454 here = os .path .dirname (os .__file__ )
436- builtins . license = _Printer (
455+ _patch_builtins ( license = _Printer (
437456 "license" , "See http://www.python.org/%.3s/license.html" % sys .version ,
438457 ["LICENSE.txt" , "LICENSE" ],
439- [os .path .join (here , os .pardir ), here , os .curdir ])
458+ [os .path .join (here , os .pardir ), here , os .curdir ]))
440459
441460
442461class _Helper (object ):
@@ -453,7 +472,7 @@ def __call__(self, *args, **kwds):
453472 return pydoc .help (* args , ** kwds )
454473
455474def sethelper ():
456- builtins . help = _Helper ()
475+ _patch_builtins ( help = _Helper () )
457476
458477def enablerlcompleter ():
459478 """Enable default readline configuration on interactive prompts, by
0 commit comments