1# (C) Copyright 2020 by Rocky Bernstein
2#
3#  This program is free software; you can redistribute it and/or
4#  modify it under the terms of the GNU General Public License
5#  as published by the Free Software Foundation; either version 2
6#  of the License, or (at your option) any later version.
7#
8#  This program is distributed in the hope that it will be useful,
9#  but WITHOUT ANY WARRANTY; without even the implied warranty of
10#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11#  GNU General Public License for more details.
12#
13#  You should have received a copy of the GNU General Public License
14#  along with this program; if not, write to the Free Software
15#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
16
17import inspect
18
19def iscode(obj):
20    """A replacement for inspect.iscode() which we can't used because we may be
21    using a different version of Python than the version of Python used
22    in creating the byte-compiled objects. Here, the code types may mismatch.
23    """
24    return inspect.iscode(obj) or isinstance(obj, CodeBase)
25
26
27def code_has_star_arg(code):
28    """Return True iff
29    the code object has a variable positional parameter (*args-like)"""
30    return (code.co_flags & 4) != 0
31
32
33def code_has_star_star_arg(code):
34    """Return True iff
35    The code object has a variable keyword parameter (**kwargs-like)."""
36    return (code.co_flags & 8) != 0
37
38class CodeBase(object):
39
40    # Mimic Python 3 code access functions
41    def __len__(self):
42        return len(self.co_code)
43
44    def __getitem__(self, i):
45        op = self.co_code[i]
46        if isinstance(op, str):
47            op = ord(op)
48        return op
49
50    def __repr__(self):
51        msg = "<%s code object %s at 0x%x, file %s>" % (
52            (self.__class__.__name__, self.co_name, id(self), self.co_filename)
53        )
54        if hasattr(self, "co_firstlineno"):
55            msg += ", line %d" % self.co_firstlineno
56
57        return msg
58