1# mako/compat.py
2# Copyright 2006-2023 the Mako authors and contributors <see AUTHORS file>
3#
4# This module is part of Mako and is released under
5# the MIT License: http://www.opensource.org/licenses/mit-license.php
6
7import collections
8from importlib import metadata as importlib_metadata
9from importlib import util
10import inspect
11import sys
12
13win32 = sys.platform.startswith("win")
14pypy = hasattr(sys, "pypy_version_info")
15
16ArgSpec = collections.namedtuple(
17    "ArgSpec", ["args", "varargs", "keywords", "defaults"]
18)
19
20
21def inspect_getargspec(func):
22    """getargspec based on fully vendored getfullargspec from Python 3.3."""
23
24    if inspect.ismethod(func):
25        func = func.__func__
26    if not inspect.isfunction(func):
27        raise TypeError(f"{func!r} is not a Python function")
28
29    co = func.__code__
30    if not inspect.iscode(co):
31        raise TypeError(f"{co!r} is not a code object")
32
33    nargs = co.co_argcount
34    names = co.co_varnames
35    nkwargs = co.co_kwonlyargcount
36    args = list(names[:nargs])
37
38    nargs += nkwargs
39    varargs = None
40    if co.co_flags & inspect.CO_VARARGS:
41        varargs = co.co_varnames[nargs]
42        nargs = nargs + 1
43    varkw = None
44    if co.co_flags & inspect.CO_VARKEYWORDS:
45        varkw = co.co_varnames[nargs]
46
47    return ArgSpec(args, varargs, varkw, func.__defaults__)
48
49
50def load_module(module_id, path):
51    spec = util.spec_from_file_location(module_id, path)
52    module = util.module_from_spec(spec)
53    spec.loader.exec_module(module)
54    return module
55
56
57def exception_as():
58    return sys.exc_info()[1]
59
60
61def exception_name(exc):
62    return exc.__class__.__name__
63
64
65def importlib_metadata_get(group):
66    ep = importlib_metadata.entry_points()
67    if hasattr(ep, "select"):
68        return ep.select(group=group)
69    else:
70        return ep.get(group, ())
71