Skip to content

Bad attribute access on a union type should be an error, not a warning #1656

@AlexWaygood

Description

@AlexWaygood

Summary

Consider the following examples:

def f(x: list[int] | None, y: None):
    x[0]  # error: [non-subscriptable]
    y[0]  # error: [non-subscriptable]

    for z in x: ...  # error: [not-iterable]
    for z in y: ...  # error: [not-iterable]

    x.index  # warning: [possibly-missing-attribute]
    y.index  # error: [unresolved-attribute]

When it comes to subscripting a union or iterating over a union, we issue a hard error if any element of the union does not support the operation. That's as it should be: these are serious typing errors where we're confident in our analysis. The user should definitely want these errors surfaced even if they didn't want any warnings displayed.

When it comes to attribute access on a union, however, we only emit a possibly-missing-attribute warning if some union elements do not have the attribute, rather than an unresolved-attribute error. I don't think this is correct; it's just as serious a typing error as attempting to subscript a union where some elements don't support subscription.

Ideally we would be able to distinguish attribute access on a union from something like this, which I think should remain a warning rather than an error:

def coinflip() -> bool:
    return False

class F:
    if coinflip():
        x = 42

F.x  # error: [possibly-missing-attribute]

Currently our member-lookup machinery conflates these cases

Metadata

Metadata

Assignees

Labels

attribute accessInstance attributes, class attributes, etc.diagnosticsRelated to reporting of diagnostics.

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions