Better reflect non-datetime uses with tzinfo#9862
Better reflect non-datetime uses with tzinfo#9862pganssle wants to merge 3 commits intopython:mainfrom
Conversation
This comment has been minimized.
This comment has been minimized.
|
Hmm...
Not sure I fully understand the situation here. It seems like And the cases in the subclass are: Seems compatible to me. If it's the |
|
If a superclass says that it will accept a class Foo:
def method(self, obj: str | None) -> None:
if obj is not None:
print(obj.upper())
class Bar(Foo):
def method(self, obj: str) -> None:
print(obj.upper())
foo_instance: Foo = Bar()
foo_instance.method(None) # Oh noNote that the |
The actual tzinfo interface allows for passing a `time` as well as `None` to the three main abstract methods, and it expects that when you pass it a `datetime` you will *always* get a valid answer (whereas for `time` and `None` it depends on whether or not the zone represents a fixed offset).
This comment has been minimized.
This comment has been minimized.
454e8de to
6664a16
Compare
This comment has been minimized.
This comment has been minimized.
OK, so in this case I think that this will just be a breaking change, since the actual Not sure why that's not considered compatible, since the subclass does accept |
|
In general, typeshed is okay with forcing people who subclass types to update when we improve the types, so the two new primer hits from that in sphinx and mongodb aren't the worst. That said, there's definitely a mypy bug here. If we fix that, it'll be the happiest way forward, but I'm fine with type ignore and moving on. I filed python/mypy#15121 for this |
| @overload | ||
| def tzname(self, __dt: datetime) -> str: ... | ||
| @overload | ||
| def tzname(self, __dt: time | None) -> str: ... |
There was a problem hiding this comment.
| def tzname(self, __dt: time | None) -> str: ... | |
| def tzname(self, __dt: time | None) -> str | None: ... |
Currently the two overloads return the same type
|
Diff from mypy_primer, showing the effect of this PR on open source code: streamlit (https://github.com/streamlit/streamlit)
+ lib/tests/streamlit/runtime/caching/hashing_test.py:32: note: ... from here:
+ scripts/pypi_nightly_create_tag.py:24: note: ... from here:
+ lib/tests/streamlit/runtime/caching/hashing_test.py:32: note: ... from here:
+ scripts/pypi_nightly_create_tag.py:24: note: In module imported here:
mongo-python-driver (https://github.com/mongodb/mongo-python-driver)
+ bson/tz_util.py:42: error: Signature of "utcoffset" incompatible with supertype "tzinfo" [override]
+ bson/tz_util.py:42: note: Superclass:
+ bson/tz_util.py:42: note: @overload
+ bson/tz_util.py:42: note: def utcoffset(self, datetime, /) -> timedelta
+ bson/tz_util.py:42: note: @overload
+ bson/tz_util.py:42: note: def utcoffset(self, Optional[time], /) -> Optional[timedelta]
+ bson/tz_util.py:42: note: Subclass:
+ bson/tz_util.py:42: note: def utcoffset(self, dt: Optional[datetime]) -> timedelta
+ bson/tz_util.py:45: error: Signature of "tzname" incompatible with supertype "tzinfo" [override]
+ bson/tz_util.py:45: note: Superclass:
+ bson/tz_util.py:45: note: @overload
+ bson/tz_util.py:45: note: def tzname(self, datetime, /) -> str
+ bson/tz_util.py:45: note: @overload
+ bson/tz_util.py:45: note: def tzname(self, Optional[time], /) -> Optional[str]
+ bson/tz_util.py:45: note: Subclass:
+ bson/tz_util.py:45: note: def tzname(self, dt: Optional[datetime]) -> str
+ bson/tz_util.py:48: error: Argument 1 of "dst" is incompatible with supertype "tzinfo"; supertype defines the argument type as "Union[datetime, time, None]" [override]
+ bson/tz_util.py:48: note: This violates the Liskov substitution principle
+ bson/tz_util.py:48: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#incompatible-overrides
+ bson/json_util.py:925: error: Unused "type: ignore" comment [unused-ignore]
|
|
Thanks for contributing! I'm closing this PR for now, because it still |
The actual tzinfo interface allows for passing a
timeas well asNoneto the three main abstract methods, and it expects that when you pass it adatetimeyou will always get a valid answer (whereas fortimeandNoneit depends on whether or not the zone represents a fixed offset).I am not sure if this is the right way to stack
overloadandabstractmethoddecorators.