AST factory function for attributes, such as :code:`numpy.pi`. Other than the attribute handle these are always treated similar to :code:`_name()`. An attribute has a .value node which is a Name, and .value.id is the module/class reference. Then .attr is the attribute refere
(self: NumExpr, node: ast.AST)
| 1156 | |
| 1157 | |
| 1158 | def _attribute(self: NumExpr, node: ast.AST) -> NumReg: |
| 1159 | ''' |
| 1160 | AST factory function for attributes, such as :code:`numpy.pi`. Other |
| 1161 | than the attribute handle these are always treated similar to |
| 1162 | :code:`_name()`. |
| 1163 | |
| 1164 | An attribute has a .value node which is a Name, and .value.id is the |
| 1165 | module/class reference. Then .attr is the attribute reference that |
| 1166 | we need to resolve. |
| 1167 | |
| 1168 | **Only a single deference level is supported** To go deeper would require |
| 1169 | a recursive solution. |
| 1170 | |
| 1171 | :code:`.real` and :code:`.imag` need special handling because they are actually |
| 1172 | mapped to function calls. |
| 1173 | ''' |
| 1174 | if node.attr == 'imag' or node.attr == 'real': |
| 1175 | return _real_imag(self, node) |
| 1176 | |
| 1177 | className = node.value.id |
| 1178 | attrName = ''.join( [className, '.', node.attr] ) |
| 1179 | |
| 1180 | if attrName in self.registers: |
| 1181 | register = self.registers[attrName] |
| 1182 | regToken = register.token |
| 1183 | else: |
| 1184 | regToken = next(self._regCount) |
| 1185 | # Get address |
| 1186 | arr = None |
| 1187 | |
| 1188 | if className in self.local_dict: |
| 1189 | classRef = self.local_dict[className] |
| 1190 | if node.attr in classRef.__dict__: |
| 1191 | arr = self.local_dict[className].__dict__[node.attr] |
| 1192 | # Globals is, as usual, slower than the locals, so we prefer not to |
| 1193 | # search it. |
| 1194 | elif className in self._global_dict: |
| 1195 | classRef = self._global_dict[className] |
| 1196 | if node.attr in classRef.__dict__: |
| 1197 | arr = self._global_dict[className].__dict__[node.attr] |
| 1198 | |
| 1199 | if np.isscalar(arr): |
| 1200 | # Build tuple and add to the namesReg |
| 1201 | dchar = np.asarray(arr).dtype.char |
| 1202 | self.registers[attrName] = register = NumReg(regToken, attrName, arr, dchar, _KIND_ARRAY) |
| 1203 | else: |
| 1204 | self.registers[attrName] = register = NumReg(regToken, attrName, weakref.ref(arr), arr.dtype.char, _KIND_ARRAY ) |
| 1205 | return register |
| 1206 | |
| 1207 | def _real_imag(self: NumExpr, node: ast.AST) -> NumReg: |
| 1208 | ''' |
nothing calls this directly
no test coverage detected
searching dependent graphs…