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