(builder: IRBuilder, expr: MemberExpr)
| 235 | |
| 236 | |
| 237 | def transform_member_expr(builder: IRBuilder, expr: MemberExpr) -> Value: |
| 238 | # Special Cases |
| 239 | if expr.fullname in ("typing.TYPE_CHECKING", "typing_extensions.TYPE_CHECKING"): |
| 240 | return builder.false(expr.line) |
| 241 | |
| 242 | # First check if this is maybe a final attribute. |
| 243 | final = builder.get_final_ref(expr) |
| 244 | if final is not None: |
| 245 | fullname, final_var, native = final |
| 246 | final_type = builder.types.get(expr) or final_var.type |
| 247 | if final_type is None: |
| 248 | final_type = AnyType(TypeOfAny.special_form) |
| 249 | value = builder.emit_load_final( |
| 250 | final_var, fullname, final_var.name, native, final_type, expr.line |
| 251 | ) |
| 252 | if value is not None: |
| 253 | return value |
| 254 | |
| 255 | math_literal = transform_math_literal(builder, expr.fullname, expr.line) |
| 256 | if math_literal is not None: |
| 257 | return math_literal |
| 258 | |
| 259 | if isinstance(expr.node, MypyFile) and expr.node.fullname in builder.imports: |
| 260 | return builder.load_module(expr.node.fullname) |
| 261 | |
| 262 | can_borrow = builder.is_native_attr_ref(expr) |
| 263 | obj = builder.accept(expr.expr, can_borrow=can_borrow) |
| 264 | rtype = builder.node_type(expr) |
| 265 | |
| 266 | if ( |
| 267 | is_object_rprimitive(obj.type) |
| 268 | and expr.name == "__name__" |
| 269 | and builder.options.capi_version >= (3, 11) |
| 270 | ): |
| 271 | return builder.primitive_op(name_op, [obj], expr.line) |
| 272 | |
| 273 | if isinstance(obj.type, RInstance) and expr.name == "__class__": |
| 274 | # A non-native class could override "__class__" using "__getattribute__", so |
| 275 | # only apply to RInstance types. |
| 276 | return builder.primitive_op(type_op, [obj], expr.line) |
| 277 | |
| 278 | # Special case: for named tuples transform attribute access to faster index access. |
| 279 | typ = get_proper_type(builder.types.get(expr.expr)) |
| 280 | if isinstance(typ, TupleType) and typ.partial_fallback.type.is_named_tuple: |
| 281 | fields = typ.partial_fallback.type.metadata["namedtuple"]["fields"] |
| 282 | if expr.name in fields: |
| 283 | index = builder.builder.load_int(fields.index(expr.name)) |
| 284 | return builder.gen_method_call(obj, "__getitem__", [index], rtype, expr.line) |
| 285 | |
| 286 | check_instance_attribute_access_through_class(builder, expr, typ) |
| 287 | |
| 288 | borrow = can_borrow and builder.can_borrow |
| 289 | return builder.builder.get_attr(obj, expr.name, rtype, expr.line, borrow=borrow) |
| 290 | |
| 291 | |
| 292 | def check_instance_attribute_access_through_class( |
no test coverage detected
searching dependent graphs…