@@ -826,3 +826,61 @@ private def assertPyError (source errSubstr : String) : IO Unit := do
826826
827827-- @classmethod + @override stacking (leanSpec pattern)
828828#eval assertPy "from abc import ABC, abstractmethod\n from typing import override\n class SSZType(ABC):\n @classmethod\n @abstractmethod\n def is_fixed_size(cls):\n pass\n @classmethod\n @abstractmethod\n def get_byte_length(cls):\n pass\n class BaseUint(int, SSZType):\n __slots__ = ()\n BITS = 64\n def __new__(cls, value):\n return super().__new__(cls, int(value))\n @classmethod\n @override\n def is_fixed_size(cls):\n return True\n @classmethod\n @override\n def get_byte_length(cls):\n return cls.BITS // 8\n class Uint64(BaseUint):\n BITS = 64\n print(Uint64.is_fixed_size())\n print(Uint64.get_byte_length())" "True\n 8\n "
829+
830+ -- ============================================================
831+ -- Phase 9a continued: int/bytes subclass interop with builtins
832+ -- ============================================================
833+
834+ -- hex() on int subclass instance
835+ #eval assertPy "class BaseUint(int):\n def __new__(cls, value):\n return super().__new__(cls, int(value))\n class Uint64(BaseUint):\n pass\n print(hex(Uint64(42)))\n print(hex(Uint64(255)))" "0x2a\n 0xff\n "
836+
837+ -- bin() on int subclass instance
838+ #eval assertPy "class BaseUint(int):\n def __new__(cls, value):\n return super().__new__(cls, int(value))\n class Uint8(BaseUint):\n pass\n print(bin(Uint8(42)))" "0b101010\n "
839+
840+ -- oct() on int subclass instance
841+ #eval assertPy "class BaseUint(int):\n def __new__(cls, value):\n return super().__new__(cls, int(value))\n class Uint8(BaseUint):\n pass\n print(oct(Uint8(42)))" "0o52\n "
842+
843+ -- range() with int subclass instances
844+ #eval assertPy "class BaseUint(int):\n def __new__(cls, value):\n return super().__new__(cls, int(value))\n class Uint8(BaseUint):\n pass\n result = list(range(Uint8(5)))\n print(result)" "[0, 1, 2, 3, 4]\n "
845+
846+ -- range(start, stop, step) with int subclass instances
847+ #eval assertPy "class BaseUint(int):\n def __new__(cls, value):\n return super().__new__(cls, int(value))\n class Uint8(BaseUint):\n pass\n result = list(range(Uint8(2), Uint8(8), Uint8(2)))\n print(result)" "[2, 4, 6]\n "
848+
849+ -- divmod() with int subclass instances
850+ #eval assertPy "class BaseUint(int):\n def __new__(cls, value):\n return super().__new__(cls, int(value))\n class Uint64(BaseUint):\n pass\n result = divmod(Uint64(100), Uint64(3))\n print(result[0])\n print(result[1])" "33\n 1\n "
851+
852+ -- List indexing with int subclass instance
853+ #eval assertPy "class BaseUint(int):\n def __new__(cls, value):\n return super().__new__(cls, int(value))\n class Uint64(BaseUint):\n pass\n data = ['a', 'b', 'c', 'd', 'e']\n print(data[Uint64(2)])\n print(data[Uint64(0)])\n print(data[Uint64(4)])" "c\n a\n e\n "
854+
855+ -- Slice with int subclass instances
856+ #eval assertPy "class BaseUint(int):\n def __new__(cls, value):\n return super().__new__(cls, int(value))\n class Uint8(BaseUint):\n pass\n data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n print(data[Uint8(2):Uint8(7)])" "[2, 3, 4, 5, 6]\n "
857+
858+ -- repr() and str() on int subclass via Python-defined __repr__ /__str__
859+ #eval assertPy "class BaseUint(int):\n def __new__(cls, value):\n return super().__new__(cls, int(value))\n def __repr__(self):\n return type(self).__name__ + '(' + str(int(self)) + ')'\n def __str__(self):\n return str(int(self))\n class Uint64(BaseUint):\n pass\n x = Uint64(42)\n print(repr(x))\n print(str(x))" "Uint64(42)\n 42\n "
860+
861+ -- int() conversion of int subclass instance
862+ #eval assertPy "class BaseUint(int):\n def __new__(cls, value):\n return super().__new__(cls, int(value))\n class Uint64(BaseUint):\n pass\n x = Uint64(42)\n result = int(x)\n print(result)\n print(result == 42)" "42\n True\n "
863+
864+ -- bytes.__radd__ : b"\xff" + bytes_subclass_instance
865+ #eval assertPy "class BaseBytes(bytes):\n def __new__(cls, value=b''):\n return super().__new__(cls, value)\n class Bytes4(BaseBytes):\n pass\n x = Bytes4(b'\\ x01\\ x02\\ x03\\ x04')\n result = b'\\ xff' + x\n print(len(result))\n print(result[0])\n print(result[4])" "5\n 255\n 4\n "
866+
867+ -- sorted() on bytes subclass instances (lexicographic)
868+ #eval assertPy "class BaseBytes(bytes):\n def __new__(cls, value=b''):\n return super().__new__(cls, value)\n class Bytes4(BaseBytes):\n pass\n a = Bytes4(b'\\ x00\\ x00\\ x00\\ x02')\n b = Bytes4(b'\\ x00\\ x00\\ x00\\ x01')\n c = Bytes4(b'\\ xff\\ xff\\ xff\\ xff')\n result = sorted([c, a, b])\n print(bytes(result[0]).hex())\n print(bytes(result[1]).hex())\n print(bytes(result[2]).hex())" "00000001\n 00000002\n ffffffff\n "
869+
870+ -- In-place operators: x += Uint64(5)
871+ #eval assertPy "class BaseUint(int):\n def __new__(cls, value):\n return super().__new__(cls, int(value))\n def __add__(self, other):\n return type(self)(int(self) + int(other))\n class Uint64(BaseUint):\n pass\n x = Uint64(10)\n y = x\n x += Uint64(5)\n print(int(x))\n print(type(x).__name__)\n print(int(y))" "15\n Uint64\n 10\n "
872+
873+ -- Reverse operators: plain int + Uint raises TypeError when __radd__ checks type
874+ #eval assertPy "class BaseUint(int):\n def __new__(cls, value):\n return super().__new__(cls, int(value))\n def __radd__(self, other):\n if not isinstance(other, BaseUint):\n raise TypeError('bad type for +')\n return type(self)(int(other) + int(self))\n class Uint64(BaseUint):\n pass\n try:\n result = 100 + Uint64(3)\n print('no error')\n except TypeError as e:\n print(str(e))" "bad type for +\n "
875+
876+ -- io.BytesIO seek and read round-trip
877+ #eval assertPy "import io\n stream = io.BytesIO()\n stream.write(b'\\ x01\\ x02\\ x03\\ x04')\n stream.seek(0)\n data = stream.read()\n print(len(data))\n print(data[0])\n print(data[3])" "4\n 1\n 4\n "
878+
879+ -- BaseBytes __add__ returns raw bytes
880+ #eval assertPy "class BaseBytes(bytes):\n def __new__(cls, value=b''):\n return super().__new__(cls, value)\n class Bytes4(BaseBytes):\n pass\n a = Bytes4(b'\\ x01\\ x02\\ x03\\ x04')\n b = Bytes4(b'\\ x05\\ x06\\ x07\\ x08')\n result = a + b\n print(len(result))\n print(result[0])\n print(result[7])" "8\n 1\n 8\n "
881+
882+ -- Boolean type: construction, validation, arithmetic rejection
883+ #eval assertPy "class Boolean(int):\n def __new__(cls, value):\n if not isinstance(value, int):\n raise TypeError('Expected bool or int')\n if value not in (0, 1):\n raise ValueError('Boolean value must be 0 or 1')\n return super().__new__(cls, value)\n def __add__(self, other):\n raise TypeError('Arithmetic not supported for Boolean.')\n def __eq__(self, other):\n return isinstance(other, int) and int(self) == int(other)\n bt = Boolean(True)\n bf = Boolean(False)\n print(int(bt))\n print(int(bf))\n print(bt == 1)\n print(bf == 0)\n try:\n bt + bf\n except TypeError as e:\n print(str(e))" "1\n 0\n True\n True\n Arithmetic not supported for Boolean.\n "
884+
885+ -- Boolean rejects invalid values
886+ #eval assertPyError "class Boolean(int):\n def __new__(cls, value):\n if value not in (0, 1):\n raise ValueError('must be 0 or 1')\n return super().__new__(cls, value)\n Boolean(2)" "must be 0 or 1"
0 commit comments