• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# This is the Python adaptation and derivative work of Myia (https://github.com/mila-iqia/myia/).
2#
3# Copyright 2020 Huawei Technologies Co., Ltd
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16# ============================================================================
17"""Define the namespace of parse."""
18
19import builtins
20
21from mindspore import log as logger
22
23
24class Namespace:
25    """
26    Base class of namespace for resolve variables.
27
28    Args:
29        name (str): The namespace's name.
30        dicts (dict): A list of dict containing the namespace's variable.
31    """
32    def __init__(self, name, *dicts):
33        self.name = name
34        self.dicts = dicts
35
36    def __contains__(self, name):
37        for d in self.dicts:
38            if name in d:
39                return True
40        return False
41
42    def __getitem__(self, name):
43        for d in self.dicts:
44            if name in d:
45                return d[name]
46        raise NameError(name)
47
48    def __repr__(self):
49        return f'Namespace:{self.name}'
50
51
52class CellNamespace(Namespace):
53    """
54    Namespace for Cell object.
55
56    Args:
57        name (str): Valid module name, it can be imported.
58    """
59    def __init__(self, name):
60        mod_dict = vars(__import__(name, fromlist=['_']))
61        builtins_dict = vars(builtins)
62        super().__init__(name, mod_dict, builtins_dict)
63
64    def __getstate__(self):
65        return (self.name,)
66
67    def __setstate__(self, state):
68        name, = state
69        mod_dict = vars(__import__(name, fromlist=['_']))
70        builtins_dict = vars(builtins)
71        super().__init__(name, mod_dict, builtins_dict)
72
73
74class ClosureNamespace(Namespace):
75    """
76    Namespace for function closure.
77
78    Args:
79        fn (Function): A python function.
80    """
81    def __init__(self, fn):
82        name = f'{fn.__module__}..<{fn.__name__}>'
83        names = fn.__code__.co_freevars
84        cells = fn.__closure__
85        ns = dict(zip(names, cells or ()))
86        super().__init__(name, ns)
87
88    def __getitem__(self, name):
89        d, = self.dicts
90        try:
91            return d[name].cell_contents
92        except ValueError:
93            raise UnboundLocalError(name)
94
95
96class ClassMemberNamespace(Namespace):
97    """
98    Namespace of a class's closure.
99
100    Args:
101        obj (Object): A python class object.
102    """
103    def __init__(self, obj):
104        self.__class_member_namespace__ = True
105        label = f'{obj.__module__}..<{obj.__class__.__name__}::{id(obj)}>'
106        super().__init__(label, obj)
107
108    def __getitem__(self, name):
109        d, = self.dicts
110        if name == "self":
111            return d
112        if name == "namespace":
113            return self
114        try:
115            if hasattr(d, name):
116                return getattr(d, name)
117            return d.__dict__[name]
118        except ValueError:
119            raise UnboundLocalError(name)
120        except KeyError:
121            logger.info(f"'{d.__class__.__name__ }' object has no attribute or method: '{name}', so will return None.")
122            raise AttributeError(name)
123