Rules for subclassing of Any

(And may I suggest slowing down some of the other aspects of the discussion? You don’t have to reply to every post that you find something to disagree in.)

2 Likes

Keep in mind that this also includes uptyped bases without a further change suggested by @Liz above to formally have something with less powerful behavior for that. I’m not taking a position that there’s only a possible interpretation here, just that we need to pick a behavior here.

Even the case this was accepted for ,unnittest.Mock-likes, originally didn’t demonstrate what happens when Any comes After an interface.

Sorry, but I don’t know what “uptyped bases” are and I tuned out of the Any-in-intersections discussions sometime after the first hundred messages. Can you clarify with code samples what the issue is about here?

Any doesn’t have to be a literal Any in code to end up as a base class, it can be the result of importing a type that a type checker does not have types or stubs for.

Yes,

from untyped_library import SomeBaseClass  # type checker sees `Any`

class SerialMixin:
    def serialize(self) -> bytes:    ...

class Ours(SomeBaseClass, SerialMixin):
    foo: int

Now there are reasonable arguments to what the behavior should be here in both directions.

Ours().foo must be an int, that’s after the unknown (Any) in MRO

SomeBaseClass is gradually typed (Any in the type system)

The specification says Any is consistent with all types, so a reasonable interpretation is that while .serialize() is defined in a known context, Any comes before SerialMixin, and provides infinitely many possible definitions for .serialize(), for example .serialize(endianness="le"), so .serialize() from SerialMixin only provides a minimum bound, not an exact bound on type.

The current behavior of type checkers is also relatively reasonable from the perspective of type safety as having a diamond pattern here coming from untyped code is admittedly something people should want to provide stronger types for to prevent issues with. I have no issues with this choice, only thatI think if we want as type system behavior, the specification needs further clarification.

The intersection discussion had multiple people vehement that because of gradual typing and the definitions we have for Any, that intersections could not ignore that untyped code could change an interface, and I was persuaded by those arguments to the point that I took the time to go back to the drawing board on multiple occasions until I had something consistent with that in terms of behavior, only to find as I was creating examples of how to teach that, that this isn’t clear enough right now.

Will make an attempt to do better at. This feels like all of the related issues have been dragging on for months and that a significant portion of it has been caused by Any’s behavior being something people want to ignore and say people shouldn’t use if they care about typing, rather than fix inconsistencies about, so I’ve been a little too sharp with pointing out parts that are still ignoring the issue.

I understand the process on the specification is a work in progress and it is expected that there are growing pains on this. I want to be crystal clear that I’m not suggesting that the work on intersections having gone a certain way should dictate a specific outcome, and I would have no issue with reworking through that again under updated definitions to arrive at something consistent.

I think we need to examine this for the behavior we want in the system, and it would be reasonable to say that Any as a base class is not the top type, but has a different definition of provided compatibility if this better matches people’s desired level of tradeoffs between type safety and gradual typing.

I also think it would be reasonable to keep Any as the top type everywhere to have less special-ness about it.

I don’t have a personal preference beyond having a clear and agreed-upon behavior that other things can be built to be consistent with, my own uses of Any are intentionally limited with very clearly defined boundaries. My code will not be effected one way or another.

3 Likes

Doing this makes things easier to think through. if it were up to me alone, I would pick this, If people want untyped code to behave as it currently does, we could add another special type (I called it Unknown above) to convey unknown types that shouldn’t have the full behavior of Any, but should allow some flexibility for gradual typing. We can then still decide which gradual typing interaction is better by having type checkers treat untyped things as Unknown, and not Any.

That should also be transparent for current users hit by this when Any comes from an unknown import and not direct subclassing of actually Any at runtime for Mocks right? Type checkers do both changes at once and users see no behavior changes?

(And may I suggest slowing down some of the other aspects of the discussion? You don’t have to reply to every post that you find something to disagree in.)

I’d like to add to what Jelle said. Threads like this one are exhausting to follow, and they often fail to converge.

Here are some concrete suggestions for the participants in this thread to help us all be more efficient and effective.

  1. Avoid long, drawn-out discussions that debate minutiae.
  2. Do not feel like you need to respond to every post even if you disagree with some aspect of what someone has said. The point of these discussions is to gather feedback so you can craft a sound and well-informed proposal.
  3. Take your time to compose well-reasoned and easy-to-follow posts. Make them as succinct as possible while still being clear. You don’t get any extra credit for responding quickly.

Here’s a general rule of thumb. If you find that you have personally posted to a discussion thread more than three times, that’s a sign that something has gone wrong. The rest of the community (including the TC members) have probably already tuned out that discussion. @mikeshardmind, you’ve already posted 11 times in this thread. @Daverball, you’ve posted 7 times. You’ve flooded many inboxes (including mine) with dozens of notifications. I personally tuned out this thread long ago.

Here’s a formula that I’ve found to be successful in these public discussion forums:

When you create a new topic, start by writing a clear post with a clear statement of the problem, some supporting examples (including the reasons why it should be a priority for the typing community at this time), and a menu of potential solutions. Wait a few days for others to weigh in, but don’t respond during this time period. Then, if necessary, write a second follow-up post that clarifies some points or attempts to summarize the feedback you’ve received so far. After a few more days, write a third post that summarizes the feedback, proposes a resolution, and provides next steps (e.g. a link to a PR that includes updated text in the typing spec and/or a PR in mypy that implements the proposed change along with a mypy_primer report).

If you are not the creator of a topic but feel like you have some feedback to add to the thread, respond only once (at most twice) with your feedback. Don’t feel like you need to respond to every thread in the typing forum. Respond only to those where you have relevant expertise, insights, or passion.

Keep in mind that members of the typing community – including the type checker maintainers and TC members – have limited time. We want to spend that time as efficiently and effectively as possible to maximize our impact.

As for this particular thread, I suggest that we mark it as “closed” and start again following the above guidelines.

10 Likes

If a member of the typing council, or another maintainer involved in actually building what comes up in these discussions, flags a topic explaining that it’s become unhelpfully long or off topic, or isn’t listening to maintainer feedback, I’m happy to close it, or set slow mode, or set a timer for eventual closure. This topic isn’t even a particularly long example of the issue that these topics tend to get.

I’m setting a timer on this one to give people a little more time to respond, given it’s the first time this issue with topics has been brought up publicly.

5 Likes

I’ll keep that in mind going forward. I was under the impression that part of the move to discourse from mailing lists was to improve the situation with notifications. As a much more modern platform, I don’t get every message in my inbox, I just get a notification of new topics in categories I am speficially interested in and then get around to reading and responding as I have interest or knowledge as well as time.

The limits on available time are part of why I try to respond to clear things up quickly, rather than wait a few days when possible. I don’t always have a week’s worth of afternoons to work on things, so if a point where something is possible to clear up faster, it (in theory) should mean getting to a productive solution sooner. Clearly that’s not the case if people are tuning out as a result, but just presenting a solution directly in this case also appeared to be ruled out since I had received previously conflicting signals from stakeholders.

1 Like

I would second that sentiment.

Maybe this is a signal that we would benefit from a subcategory for the “Typing Spec”, so that discussions that are meant to be more formal and slow, so they’re easy for members of the typing council to follow, can go there and leave the rest of the typing category open for more informal quick discussions. Maybe this category could even have slow-mode on by default.

This will also allow people to have different notification settings for those categories.

This topic was automatically closed after 36 hours. New replies are no longer allowed.