fix unsoundness of overloading __new__ to return a different type

This commit is contained in:
Shiz 2021-06-25 18:13:06 +02:00
parent 7ee5d565bc
commit 577d5b8abb
2 changed files with 10 additions and 8 deletions

View File

@ -1,5 +1,5 @@
import struct
from typing import Optional as O, Union as U
from typing import Optional as O, Union as U, Generic as G, TypeVar
from ..core.base import Type, Context, PossibleDynamic
from ..core.io import Stream, Endian
from .transforms import Mapped
@ -64,9 +64,11 @@ uint64le = uint64 = Int(64, endian=Endian.Little, signed=False)
uint64be = Int(64, endian=Endian.Big, signed=False)
class Bool(Type[bool]):
def __new__(self, child: Type, true_value: int = 1, false_value: int = 0) -> Mapped:
return Mapped(child, {true_value: True, false_value: False},
T = TypeVar('T')
class Bool(G[T], Mapped[T, bool]):
def __init__(self, child: Type[T], true_value: T = 1, false_value: T = 0) -> None:
super().__init__(child, {true_value: True, false_value: False},
str='bool',
repr=f'<{__name__}.Bool({child!r}, true: {true_value!r}, false: {false_value!r})>',
)

View File

@ -185,12 +185,12 @@ class Transform(G[T, V], Type[V]):
return f'<{__name__}.{self.__class__.__name__}({self.child!r}, parse: {self.on_parse!r}, dump: {self.on_dump!r})>'
class Mapped(G[T, V], Type[T]):
def __new__(self, child: Type[T], mapping: Mapping[T, V], str: O[str] = None, repr: O[str] = None) -> Transform:
class Mapped(G[T, V], Transform[T, V]):
def __init__(self, child: Type[T], mapping: Mapping[T, V], str: O[str] = None, repr: O[str] = None) -> None:
reverse = {v: k for k, v in mapping.items()}
return Transform(child,
super().__init__(child,
parse=mapping.__getitem__,
dump=reverse.__getitem__,
str=str or f'{mapping}[{child}]',
repr=repr or f'<{__name__}.Mapped({child!r}, {mapping!r}'
repr=repr or f'<{__name__}.Mapped({child!r}, {mapping!r})>'
)