Ignore anything in /tmp and improve coverage.
[mailman.git] / src / mailman / utilities / interact.py
blob3cc5dddc613e7ae7ef1fd4368da300373600f3c2
1 # Copyright (C) 2006-2016 by the Free Software Foundation, Inc.
3 # This file is part of GNU Mailman.
5 # GNU Mailman is free software: you can redistribute it and/or modify it under
6 # the terms of the GNU General Public License as published by the Free
7 # Software Foundation, either version 3 of the License, or (at your option)
8 # any later version.
10 # GNU Mailman is distributed in the hope that it will be useful, but WITHOUT
11 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 # more details.
15 # You should have received a copy of the GNU General Public License along with
16 # GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
18 """Provide an interactive prompt, mimicking the Python interpreter."""
20 import os
21 import sys
22 import code
24 from mailman import public
27 DEFAULT_BANNER = object()
30 @public
31 def interact(upframe=True, banner=DEFAULT_BANNER, overrides=None):
32 """Start an interactive interpreter prompt.
34 :param upframe: Whether or not to populate the interpreter's globals with
35 the locals from the frame that called this function.
36 :type upframe: bool
37 :param banner: The banner to print before the interpreter starts.
38 :type banner: string
39 :param overrides: Additional interpreter globals to add.
40 :type overrides: dict
41 """
42 # The interactive prompt's namespace.
43 namespace = dict()
44 # Populate the console's with the locals of the frame that called this
45 # function (i.e. one up from here).
46 if upframe:
47 frame = sys._getframe(1)
48 namespace.update(frame.f_globals)
49 namespace.update(frame.f_locals)
50 if overrides is not None:
51 namespace.update(overrides)
52 interp = code.InteractiveConsole(namespace)
53 # Try to import the readline module, but don't worry if it's unavailable.
54 try:
55 import readline # noqa
56 except ImportError: # pragma: no cover
57 pass
58 # Mimic the real interactive interpreter's loading of any $PYTHONSTARTUP
59 # file. Note that if the startup file is not prepared to be exec'd more
60 # than once, this could cause a problem.
61 startup = os.environ.get('PYTHONSTARTUP')
62 if startup:
63 with open(startup, 'r', encoding='utf-8') as fp:
64 interp.runcode(compile(fp.read(), startup, 'exec'))
65 # We don't want the funky console object in parentheses in the banner.
66 if banner is DEFAULT_BANNER:
67 banner = '''\
68 Python %s on %s
69 Type "help", "copyright", "credits" or "license" for more information.''' % (
70 sys.version, sys.platform)
71 interp.interact(banner)