xref: /aosp_15_r20/prebuilts/build-tools/common/py3-stdlib/_sitebuiltins.py (revision cda5da8d549138a6648c5ee6d7a49cf8f4a657be)
1*cda5da8dSAndroid Build Coastguard Worker"""
2*cda5da8dSAndroid Build Coastguard WorkerThe objects used by the site module to add custom builtins.
3*cda5da8dSAndroid Build Coastguard Worker"""
4*cda5da8dSAndroid Build Coastguard Worker
5*cda5da8dSAndroid Build Coastguard Worker# Those objects are almost immortal and they keep a reference to their module
6*cda5da8dSAndroid Build Coastguard Worker# globals.  Defining them in the site module would keep too many references
7*cda5da8dSAndroid Build Coastguard Worker# alive.
8*cda5da8dSAndroid Build Coastguard Worker# Note this means this module should also avoid keep things alive in its
9*cda5da8dSAndroid Build Coastguard Worker# globals.
10*cda5da8dSAndroid Build Coastguard Worker
11*cda5da8dSAndroid Build Coastguard Workerimport sys
12*cda5da8dSAndroid Build Coastguard Worker
13*cda5da8dSAndroid Build Coastguard Workerclass Quitter(object):
14*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, name, eof):
15*cda5da8dSAndroid Build Coastguard Worker        self.name = name
16*cda5da8dSAndroid Build Coastguard Worker        self.eof = eof
17*cda5da8dSAndroid Build Coastguard Worker    def __repr__(self):
18*cda5da8dSAndroid Build Coastguard Worker        return 'Use %s() or %s to exit' % (self.name, self.eof)
19*cda5da8dSAndroid Build Coastguard Worker    def __call__(self, code=None):
20*cda5da8dSAndroid Build Coastguard Worker        # Shells like IDLE catch the SystemExit, but listen when their
21*cda5da8dSAndroid Build Coastguard Worker        # stdin wrapper is closed.
22*cda5da8dSAndroid Build Coastguard Worker        try:
23*cda5da8dSAndroid Build Coastguard Worker            sys.stdin.close()
24*cda5da8dSAndroid Build Coastguard Worker        except:
25*cda5da8dSAndroid Build Coastguard Worker            pass
26*cda5da8dSAndroid Build Coastguard Worker        raise SystemExit(code)
27*cda5da8dSAndroid Build Coastguard Worker
28*cda5da8dSAndroid Build Coastguard Worker
29*cda5da8dSAndroid Build Coastguard Workerclass _Printer(object):
30*cda5da8dSAndroid Build Coastguard Worker    """interactive prompt objects for printing the license text, a list of
31*cda5da8dSAndroid Build Coastguard Worker    contributors and the copyright notice."""
32*cda5da8dSAndroid Build Coastguard Worker
33*cda5da8dSAndroid Build Coastguard Worker    MAXLINES = 23
34*cda5da8dSAndroid Build Coastguard Worker
35*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, name, data, files=(), dirs=()):
36*cda5da8dSAndroid Build Coastguard Worker        import os
37*cda5da8dSAndroid Build Coastguard Worker        self.__name = name
38*cda5da8dSAndroid Build Coastguard Worker        self.__data = data
39*cda5da8dSAndroid Build Coastguard Worker        self.__lines = None
40*cda5da8dSAndroid Build Coastguard Worker        self.__filenames = [os.path.join(dir, filename)
41*cda5da8dSAndroid Build Coastguard Worker                            for dir in dirs
42*cda5da8dSAndroid Build Coastguard Worker                            for filename in files]
43*cda5da8dSAndroid Build Coastguard Worker
44*cda5da8dSAndroid Build Coastguard Worker    def __setup(self):
45*cda5da8dSAndroid Build Coastguard Worker        if self.__lines:
46*cda5da8dSAndroid Build Coastguard Worker            return
47*cda5da8dSAndroid Build Coastguard Worker        data = None
48*cda5da8dSAndroid Build Coastguard Worker        for filename in self.__filenames:
49*cda5da8dSAndroid Build Coastguard Worker            try:
50*cda5da8dSAndroid Build Coastguard Worker                with open(filename, encoding='utf-8') as fp:
51*cda5da8dSAndroid Build Coastguard Worker                    data = fp.read()
52*cda5da8dSAndroid Build Coastguard Worker                break
53*cda5da8dSAndroid Build Coastguard Worker            except OSError:
54*cda5da8dSAndroid Build Coastguard Worker                pass
55*cda5da8dSAndroid Build Coastguard Worker        if not data:
56*cda5da8dSAndroid Build Coastguard Worker            data = self.__data
57*cda5da8dSAndroid Build Coastguard Worker        self.__lines = data.split('\n')
58*cda5da8dSAndroid Build Coastguard Worker        self.__linecnt = len(self.__lines)
59*cda5da8dSAndroid Build Coastguard Worker
60*cda5da8dSAndroid Build Coastguard Worker    def __repr__(self):
61*cda5da8dSAndroid Build Coastguard Worker        self.__setup()
62*cda5da8dSAndroid Build Coastguard Worker        if len(self.__lines) <= self.MAXLINES:
63*cda5da8dSAndroid Build Coastguard Worker            return "\n".join(self.__lines)
64*cda5da8dSAndroid Build Coastguard Worker        else:
65*cda5da8dSAndroid Build Coastguard Worker            return "Type %s() to see the full %s text" % ((self.__name,)*2)
66*cda5da8dSAndroid Build Coastguard Worker
67*cda5da8dSAndroid Build Coastguard Worker    def __call__(self):
68*cda5da8dSAndroid Build Coastguard Worker        self.__setup()
69*cda5da8dSAndroid Build Coastguard Worker        prompt = 'Hit Return for more, or q (and Return) to quit: '
70*cda5da8dSAndroid Build Coastguard Worker        lineno = 0
71*cda5da8dSAndroid Build Coastguard Worker        while 1:
72*cda5da8dSAndroid Build Coastguard Worker            try:
73*cda5da8dSAndroid Build Coastguard Worker                for i in range(lineno, lineno + self.MAXLINES):
74*cda5da8dSAndroid Build Coastguard Worker                    print(self.__lines[i])
75*cda5da8dSAndroid Build Coastguard Worker            except IndexError:
76*cda5da8dSAndroid Build Coastguard Worker                break
77*cda5da8dSAndroid Build Coastguard Worker            else:
78*cda5da8dSAndroid Build Coastguard Worker                lineno += self.MAXLINES
79*cda5da8dSAndroid Build Coastguard Worker                key = None
80*cda5da8dSAndroid Build Coastguard Worker                while key is None:
81*cda5da8dSAndroid Build Coastguard Worker                    key = input(prompt)
82*cda5da8dSAndroid Build Coastguard Worker                    if key not in ('', 'q'):
83*cda5da8dSAndroid Build Coastguard Worker                        key = None
84*cda5da8dSAndroid Build Coastguard Worker                if key == 'q':
85*cda5da8dSAndroid Build Coastguard Worker                    break
86*cda5da8dSAndroid Build Coastguard Worker
87*cda5da8dSAndroid Build Coastguard Worker
88*cda5da8dSAndroid Build Coastguard Workerclass _Helper(object):
89*cda5da8dSAndroid Build Coastguard Worker    """Define the builtin 'help'.
90*cda5da8dSAndroid Build Coastguard Worker
91*cda5da8dSAndroid Build Coastguard Worker    This is a wrapper around pydoc.help that provides a helpful message
92*cda5da8dSAndroid Build Coastguard Worker    when 'help' is typed at the Python interactive prompt.
93*cda5da8dSAndroid Build Coastguard Worker
94*cda5da8dSAndroid Build Coastguard Worker    Calling help() at the Python prompt starts an interactive help session.
95*cda5da8dSAndroid Build Coastguard Worker    Calling help(thing) prints help for the python object 'thing'.
96*cda5da8dSAndroid Build Coastguard Worker    """
97*cda5da8dSAndroid Build Coastguard Worker
98*cda5da8dSAndroid Build Coastguard Worker    def __repr__(self):
99*cda5da8dSAndroid Build Coastguard Worker        return "Type help() for interactive help, " \
100*cda5da8dSAndroid Build Coastguard Worker               "or help(object) for help about object."
101*cda5da8dSAndroid Build Coastguard Worker    def __call__(self, *args, **kwds):
102*cda5da8dSAndroid Build Coastguard Worker        import pydoc
103*cda5da8dSAndroid Build Coastguard Worker        return pydoc.help(*args, **kwds)
104