Skip to content

Commit

Permalink
Preserve call arguments of generate_packet_map
Browse files Browse the repository at this point in the history
The generate_packet_map function is using `functools.lru_cache` to
preserve the results, however this decorator returns a
`_lru_cache_wrapper` type, which only preserves the return type from the
original function, without preserving call arguments (or overloads).

This overrides `lru_cache` function during `TYPE_CHECKING`, and gives it
a signature that preserves this information. This does however mean
losing on the information that this function is cached, however for us,
it's much more important to preserve call parameters and overloads so
that calls to it are actually checked.

So while this is absolutely a hack and it's not ideal, it's the lesser
evil when the alternative is losing on the type info from all
parameters.
  • Loading branch information
ItsDrike committed Aug 8, 2023
1 parent 902e903 commit 54d5fd0
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 2 deletions.
1 change: 1 addition & 0 deletions changes/170.bugfix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Preserve the call parameters and overloads in the typing signature of `mcproto.packets.packet_map.generate_packet_map` function. (This wasn't the case before, since `functools.lru_cache` doesn't preserve this data). Note that this loses on the typing information about the cache itself, as now it will appear to be a regular uncached function to the type-checker. We deemed this approach better to the alternative of no typing info for call arguments or overloads, but preserving cache info.
19 changes: 17 additions & 2 deletions mcproto/packets/packet_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,27 @@
import importlib
import pkgutil
from collections.abc import Iterator, Mapping, Sequence
from functools import lru_cache
from types import MappingProxyType, ModuleType
from typing import Literal, NamedTuple, NoReturn, overload
from typing import Literal, NamedTuple, NoReturn, TYPE_CHECKING, overload

from mcproto.packets.packet import ClientBoundPacket, GameState, Packet, PacketDirection, ServerBoundPacket

# lru_cache doesn't forward the call parameters in _lru_cache_wrapper type, only the return type,
# this fixes the issue, though it means losing the type info about the function being cached,
# that's annoying, but preserving the parameters is much more important to us, so this is the lesser
# evil from the two
if TYPE_CHECKING:
from typing import TypeVar

T = TypeVar("T")

def lru_cache(func: T, /) -> T:
...

else:
from functools import lru_cache


__all__ = ["generate_packet_map"]

MODULE_PATHS = {
Expand Down

0 comments on commit 54d5fd0

Please # to comment.