Take 2: Rules for subclassing Any

Disclaimer: I did not yet read any of the discussion before this thread.

It seems like another option has not been explored yet. If we see Any as a placeholder, like an unbounded type variable, in the inheritance hierarchy, we cannot know whether a certain member will be defined or not. In that case, isn’t the only viable result a Union of the resulting types of both cases (member defined or not defined)? This would be consistent with a similar case where the type system is missing information:

from typing import Any
obj: Any = object()

def test(val: int):  # return type: Any | Literal[0]
    if val > 0:
        return obj
    return 0

This would make the type annotation correct for the information that we currently have - it does not hide any defined contracts but also does not ignore the option for non-LSP-conform overrides. I’m still not sure about it, but doesn’t this prevent false negatives entirely?

The typecheckers could add a configuration option that could change the behaviour to “Any honours LSP” for suggestions in IDEs and users who know that all their class hierarchies are LSP-conform to prevent false positives where they are too annoying. This flag should also make things backwards-compatible to the current state, right?

Maybe it might even make sense to introduce a separate typing statement LSPCompatible[T1, ..., TN], which tells the type system that a set of types has no LSP conflicts (and if it has no LSP conflicts, inheritance is basically unordered, right?)? This would allow users to easily circumvent the pervasive Union annotation of members that could be overridden by Any, by including Any in the set of types T1...TN.
However, I do not think such a statement should be always global, as Any might be a replacement for different untyped Baseclasses in different classes. Maybe this should be a class decorator to better control the scope of the annotation? It could be a no-op at runtime, similar to typing.cast. When a class is annotated with this decorator, the meaning of Any in an inheritance hierarchy for the type system would change from “really any type” to “any LSP-compatible type”. For fully specified classes, typecheckers could raise a warning to help with (the transition away from) gradual typing. The decorator would also get us around introducing additional types for an LSP-conform Any (if inheritance is the only issue where such a type would be needed).