environment.py 1.6 KB
Newer Older
dugupeiwen's avatar
dugupeiwen committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import weakref
import importlib

from numba import _dynfunc


class Environment(_dynfunc.Environment):
    """Stores globals and constant pyobjects for runtime.

    It is often needed to convert b/w nopython objects and pyobjects.
    """
    __slots__ = ('env_name', '__weakref__')
    # A weak-value dictionary to store live environment with env_name as the
    # key.
    _memo = weakref.WeakValueDictionary()

    @classmethod
    def from_fndesc(cls, fndesc):
        try:
            # Avoid creating new Env
            return cls._memo[fndesc.env_name]
        except KeyError:
            inst = cls(fndesc.lookup_globals())
            inst.env_name = fndesc.env_name
            cls._memo[fndesc.env_name] = inst
            return inst

    def can_cache(self):
        is_dyn = '__name__' not in self.globals
        return not is_dyn

    def __reduce__(self):
        return _rebuild_env, (
            self.globals.get('__name__'),
            self.consts,
            self.env_name,
        )

    def __del__(self):
        return

    def __repr__(self):
        return f"<Environment {self.env_name!r} >"


def _rebuild_env(modname, consts, env_name):
    env = lookup_environment(env_name)
    if env is not None:
        return env

    mod = importlib.import_module(modname)
    env = Environment(mod.__dict__)
    env.consts[:] = consts
    env.env_name = env_name
    # Cache loaded object
    Environment._memo[env_name] = env
    return env


def lookup_environment(env_name):
    """Returns the Environment object for the given name;
    or None if not found
    """
    return Environment._memo.get(env_name)