ethereum.base_types
Integer and array types which are used by—but not unique to—Ethereum.
[Uint
] represents non-negative integers of arbitrary size, while subclasses
of [FixedUint
] (like [U256
] or [U32
]) represent non-negative integers of
particular sizes.
Similarly, [Bytes
] represents arbitrarily long byte sequences, while
subclasses of [FixedBytes
] (like [Bytes0
] or [Bytes64
]) represent
sequences containing an exact number of bytes.
1""" 2Integer and array types which are used by—but not unique to—Ethereum. 3 4[`Uint`] represents non-negative integers of arbitrary size, while subclasses 5of [`FixedUint`] (like [`U256`] or [`U32`]) represent non-negative integers of 6particular sizes. 7 8Similarly, [`Bytes`] represents arbitrarily long byte sequences, while 9subclasses of [`FixedBytes`] (like [`Bytes0`] or [`Bytes64`]) represent 10sequences containing an exact number of bytes. 11 12[`Uint`]: ref:ethereum.base_types.Uint 13[`FixedUint`]: ref:ethereum.base_types.FixedUint 14[`U32`]: ref:ethereum.base_types.U32 15[`U256`]: ref:ethereum.base_types.U256 16[`Bytes`]: ref:ethereum.base_types.Bytes 17[`FixedBytes`]: ref:ethereum.base_types.FixedBytes 18[`Bytes0`]: ref:ethereum.base_types.Bytes0 19[`Bytes64`]: ref:ethereum.base_types.Bytes64 20""" 21 22from dataclasses import is_dataclass, replace 23from typing import ( 24 Any, 25 Callable, 26 ClassVar, 27 Optional, 28 Protocol, 29 Tuple, 30 Type, 31 TypeVar, 32 runtime_checkable, 33) 34 35 36@runtime_checkable 37class SlottedFreezable(Protocol): 38 """ 39 A [`Protocol`] implemented by data classes annotated with 40 [`@slotted_freezable`]. 41 42 [`@slotted_freezable`]: ref:ethereum.base_types.slotted_freezable 43 [`Protocol`]: https://docs.python.org/library/typing.html#typing.Protocol 44 """ 45 46 _frozen: bool 47 48 49U255_CEIL_VALUE = 2**255 50""" 51Smallest value that requires 256 bits to represent. Mostly used in signed 52arithmetic operations, like [`sdiv`]. 53 54[`sdiv`]: ref:ethereum.frontier.vm.instructions.arithmetic.sdiv 55""" 56 57U256_CEIL_VALUE = 2**256 58""" 59Smallest value that requires 257 bits to represent. Used when converting a 60[`U256`] in two's complement format to a regular `int` in [`U256.to_signed`]. 61 62[`U256`]: ref:ethereum.base_types.U256 63[`U256.to_signed`]: ref:ethereum.base_types.U256.to_signed 64""" 65 66 67class Uint(int): 68 """ 69 Unsigned integer of arbitrary size. 70 """ 71 72 __slots__ = () 73 74 @classmethod 75 def from_be_bytes(cls: Type, buffer: "Bytes") -> "Uint": 76 """ 77 Converts a sequence of bytes into an arbitrarily sized unsigned integer 78 from its big endian representation. 79 """ 80 return cls(int.from_bytes(buffer, "big")) 81 82 @classmethod 83 def from_le_bytes(cls: Type, buffer: "Bytes") -> "Uint": 84 """ 85 Converts a sequence of bytes into an arbitrarily sized unsigned integer 86 from its little endian representation. 87 """ 88 return cls(int.from_bytes(buffer, "little")) 89 90 def __init__(self, value: int) -> None: 91 if not isinstance(value, int): 92 raise TypeError() 93 94 if value < 0: 95 raise ValueError() 96 97 def __radd__(self, left: int) -> "Uint": 98 return self.__add__(left) 99 100 def __add__(self, right: int) -> "Uint": 101 if not isinstance(right, int): 102 return NotImplemented 103 104 if right < 0: 105 raise ValueError() 106 107 return int.__new__(self.__class__, int.__add__(self, right)) 108 109 def __iadd__(self, right: int) -> "Uint": 110 return self.__add__(right) 111 112 def __sub__(self, right: int) -> "Uint": 113 if not isinstance(right, int): 114 return NotImplemented 115 116 if right < 0 or self < right: 117 raise ValueError() 118 119 return int.__new__(self.__class__, int.__sub__(self, right)) 120 121 def __rsub__(self, left: int) -> "Uint": 122 if not isinstance(left, int): 123 return NotImplemented 124 125 if left < 0 or self > left: 126 raise ValueError() 127 128 return int.__new__(self.__class__, int.__rsub__(self, left)) 129 130 def __isub__(self, right: int) -> "Uint": 131 return self.__sub__(right) 132 133 def __mul__(self, right: int) -> "Uint": 134 if not isinstance(right, int): 135 return NotImplemented 136 137 if right < 0: 138 raise ValueError() 139 140 return int.__new__(self.__class__, int.__mul__(self, right)) 141 142 def __rmul__(self, left: int) -> "Uint": 143 return self.__mul__(left) 144 145 def __imul__(self, right: int) -> "Uint": 146 return self.__mul__(right) 147 148 # Explicitly don't override __truediv__, __rtruediv__, and __itruediv__ 149 # since they return floats anyway. 150 151 def __floordiv__(self, right: int) -> "Uint": 152 if not isinstance(right, int): 153 return NotImplemented 154 155 if right < 0: 156 raise ValueError() 157 158 return int.__new__(self.__class__, int.__floordiv__(self, right)) 159 160 def __rfloordiv__(self, left: int) -> "Uint": 161 if not isinstance(left, int): 162 return NotImplemented 163 164 if left < 0: 165 raise ValueError() 166 167 return int.__new__(self.__class__, int.__rfloordiv__(self, left)) 168 169 def __ifloordiv__(self, right: int) -> "Uint": 170 return self.__floordiv__(right) 171 172 def __mod__(self, right: int) -> "Uint": 173 if not isinstance(right, int): 174 return NotImplemented 175 176 if right < 0: 177 raise ValueError() 178 179 return int.__new__(self.__class__, int.__mod__(self, right)) 180 181 def __rmod__(self, left: int) -> "Uint": 182 if not isinstance(left, int): 183 return NotImplemented 184 185 if left < 0: 186 raise ValueError() 187 188 return int.__new__(self.__class__, int.__rmod__(self, left)) 189 190 def __imod__(self, right: int) -> "Uint": 191 return self.__mod__(right) 192 193 def __divmod__(self, right: int) -> Tuple["Uint", "Uint"]: 194 if not isinstance(right, int): 195 return NotImplemented 196 197 if right < 0: 198 raise ValueError() 199 200 result = int.__divmod__(self, right) 201 return ( 202 int.__new__(self.__class__, result[0]), 203 int.__new__(self.__class__, result[1]), 204 ) 205 206 def __rdivmod__(self, left: int) -> Tuple["Uint", "Uint"]: 207 if not isinstance(left, int): 208 return NotImplemented 209 210 if left < 0: 211 raise ValueError() 212 213 result = int.__rdivmod__(self, left) 214 return ( 215 int.__new__(self.__class__, result[0]), 216 int.__new__(self.__class__, result[1]), 217 ) 218 219 def __pow__( # type: ignore[override] 220 self, right: int, modulo: Optional[int] = None 221 ) -> "Uint": 222 if modulo is not None: 223 if not isinstance(modulo, int): 224 return NotImplemented 225 226 if modulo < 0: 227 raise ValueError() 228 229 if not isinstance(right, int): 230 return NotImplemented 231 232 if right < 0: 233 raise ValueError() 234 235 return int.__new__(self.__class__, int.__pow__(self, right, modulo)) 236 237 def __rpow__( # type: ignore[misc] 238 self, left: int, modulo: Optional[int] = None 239 ) -> "Uint": 240 if modulo is not None: 241 if not isinstance(modulo, int): 242 return NotImplemented 243 244 if modulo < 0: 245 raise ValueError() 246 247 if not isinstance(left, int): 248 return NotImplemented 249 250 if left < 0: 251 raise ValueError() 252 253 return int.__new__(self.__class__, int.__rpow__(self, left, modulo)) 254 255 def __ipow__( # type: ignore[override] 256 self, right: int, modulo: Optional[int] = None 257 ) -> "Uint": 258 return self.__pow__(right, modulo) 259 260 def __xor__(self, right: int) -> "Uint": 261 if not isinstance(right, int): 262 return NotImplemented 263 264 if right < 0: 265 raise ValueError() 266 267 return int.__new__(self.__class__, int.__xor__(self, right)) 268 269 def __rxor__(self, left: int) -> "Uint": 270 if not isinstance(left, int): 271 return NotImplemented 272 273 if left < 0: 274 raise ValueError() 275 276 return int.__new__(self.__class__, int.__rxor__(self, left)) 277 278 def __ixor__(self, right: int) -> "Uint": 279 return self.__xor__(right) 280 281 # TODO: Implement and, or, neg, pos, abs, invert, ... 282 283 def to_be_bytes32(self) -> "Bytes32": 284 """ 285 Converts this arbitrarily sized unsigned integer into its big endian 286 representation with exactly 32 bytes. 287 """ 288 return Bytes32(self.to_bytes(32, "big")) 289 290 def to_be_bytes(self) -> "Bytes": 291 """ 292 Converts this arbitrarily sized unsigned integer into its big endian 293 representation, without padding. 294 """ 295 bit_length = self.bit_length() 296 byte_length = (bit_length + 7) // 8 297 return self.to_bytes(byte_length, "big") 298 299 def to_le_bytes(self, number_bytes: Optional[int] = None) -> "Bytes": 300 """ 301 Converts this arbitrarily sized unsigned integer into its little endian 302 representation, without padding. 303 """ 304 if number_bytes is None: 305 bit_length = self.bit_length() 306 number_bytes = (bit_length + 7) // 8 307 return self.to_bytes(number_bytes, "little") 308 309 310T = TypeVar("T", bound="FixedUint") 311 312 313class FixedUint(int): 314 """ 315 Superclass for fixed size unsigned integers. Not intended to be used 316 directly, but rather to be subclassed. 317 """ 318 319 MAX_VALUE: ClassVar["FixedUint"] 320 """ 321 Largest value that can be represented by this integer type. 322 """ 323 324 __slots__ = () 325 326 def __init__(self: T, value: int) -> None: 327 if not isinstance(value, int): 328 raise TypeError() 329 330 if value < 0 or value > self.MAX_VALUE: 331 raise ValueError() 332 333 def __radd__(self: T, left: int) -> T: 334 return self.__add__(left) 335 336 def __add__(self: T, right: int) -> T: 337 if not isinstance(right, int): 338 return NotImplemented 339 340 result = int.__add__(self, right) 341 342 if right < 0 or result > self.MAX_VALUE: 343 raise ValueError() 344 345 return int.__new__(self.__class__, result) 346 347 def wrapping_add(self: T, right: int) -> T: 348 """ 349 Return a new instance containing `self + right (mod N)`. 350 351 Passing a `right` value greater than [`MAX_VALUE`] or less than zero 352 will raise a `ValueError`, even if the result would fit in this integer 353 type. 354 355 [`MAX_VALUE`]: ref:ethereum.base_types.FixedUint.MAX_VALUE 356 """ 357 if not isinstance(right, int): 358 return NotImplemented 359 360 if right < 0 or right > self.MAX_VALUE: 361 raise ValueError() 362 363 # This is a fast way of ensuring that the result is < (2 ** 256) 364 return int.__new__( 365 self.__class__, int.__add__(self, right) & self.MAX_VALUE 366 ) 367 368 def __iadd__(self: T, right: int) -> T: 369 return self.__add__(right) 370 371 def __sub__(self: T, right: int) -> T: 372 if not isinstance(right, int): 373 return NotImplemented 374 375 if right < 0 or right > self.MAX_VALUE or self < right: 376 raise ValueError() 377 378 return int.__new__(self.__class__, int.__sub__(self, right)) 379 380 def wrapping_sub(self: T, right: int) -> T: 381 """ 382 Return a new instance containing `self - right (mod N)`. 383 384 Passing a `right` value greater than [`MAX_VALUE`] or less than zero 385 will raise a `ValueError`, even if the result would fit in this integer 386 type. 387 388 [`MAX_VALUE`]: ref:ethereum.base_types.FixedUint.MAX_VALUE 389 """ 390 if not isinstance(right, int): 391 return NotImplemented 392 393 if right < 0 or right > self.MAX_VALUE: 394 raise ValueError() 395 396 # This is a fast way of ensuring that the result is < (2 ** 256) 397 return int.__new__( 398 self.__class__, int.__sub__(self, right) & self.MAX_VALUE 399 ) 400 401 def __rsub__(self: T, left: int) -> T: 402 if not isinstance(left, int): 403 return NotImplemented 404 405 if left < 0 or left > self.MAX_VALUE or self > left: 406 raise ValueError() 407 408 return int.__new__(self.__class__, int.__rsub__(self, left)) 409 410 def __isub__(self: T, right: int) -> T: 411 return self.__sub__(right) 412 413 def __mul__(self: T, right: int) -> T: 414 if not isinstance(right, int): 415 return NotImplemented 416 417 result = int.__mul__(self, right) 418 419 if right < 0 or result > self.MAX_VALUE: 420 raise ValueError() 421 422 return int.__new__(self.__class__, result) 423 424 def wrapping_mul(self: T, right: int) -> T: 425 """ 426 Return a new instance containing `self * right (mod N)`. 427 428 Passing a `right` value greater than [`MAX_VALUE`] or less than zero 429 will raise a `ValueError`, even if the result would fit in this integer 430 type. 431 432 [`MAX_VALUE`]: ref:ethereum.base_types.FixedUint.MAX_VALUE 433 """ 434 if not isinstance(right, int): 435 return NotImplemented 436 437 if right < 0 or right > self.MAX_VALUE: 438 raise ValueError() 439 440 # This is a fast way of ensuring that the result is < (2 ** 256) 441 return int.__new__( 442 self.__class__, int.__mul__(self, right) & self.MAX_VALUE 443 ) 444 445 def __rmul__(self: T, left: int) -> T: 446 return self.__mul__(left) 447 448 def __imul__(self: T, right: int) -> T: 449 return self.__mul__(right) 450 451 # Explicitly don't override __truediv__, __rtruediv__, and __itruediv__ 452 # since they return floats anyway. 453 454 def __floordiv__(self: T, right: int) -> T: 455 if not isinstance(right, int): 456 return NotImplemented 457 458 if right < 0 or right > self.MAX_VALUE: 459 raise ValueError() 460 461 return int.__new__(self.__class__, int.__floordiv__(self, right)) 462 463 def __rfloordiv__(self: T, left: int) -> T: 464 if not isinstance(left, int): 465 return NotImplemented 466 467 if left < 0 or left > self.MAX_VALUE: 468 raise ValueError() 469 470 return int.__new__(self.__class__, int.__rfloordiv__(self, left)) 471 472 def __ifloordiv__(self: T, right: int) -> T: 473 return self.__floordiv__(right) 474 475 def __mod__(self: T, right: int) -> T: 476 if not isinstance(right, int): 477 return NotImplemented 478 479 if right < 0 or right > self.MAX_VALUE: 480 raise ValueError() 481 482 return int.__new__(self.__class__, int.__mod__(self, right)) 483 484 def __rmod__(self: T, left: int) -> T: 485 if not isinstance(left, int): 486 return NotImplemented 487 488 if left < 0 or left > self.MAX_VALUE: 489 raise ValueError() 490 491 return int.__new__(self.__class__, int.__rmod__(self, left)) 492 493 def __imod__(self: T, right: int) -> T: 494 return self.__mod__(right) 495 496 def __divmod__(self: T, right: int) -> Tuple[T, T]: 497 if not isinstance(right, int): 498 return NotImplemented 499 500 if right < 0 or right > self.MAX_VALUE: 501 raise ValueError() 502 503 result = super(FixedUint, self).__divmod__(right) 504 return ( 505 int.__new__(self.__class__, result[0]), 506 int.__new__(self.__class__, result[1]), 507 ) 508 509 def __rdivmod__(self: T, left: int) -> Tuple[T, T]: 510 if not isinstance(left, int): 511 return NotImplemented 512 513 if left < 0 or left > self.MAX_VALUE: 514 raise ValueError() 515 516 result = super(FixedUint, self).__rdivmod__(left) 517 return ( 518 int.__new__(self.__class__, result[0]), 519 int.__new__(self.__class__, result[1]), 520 ) 521 522 def __pow__( # type: ignore[override] 523 self: T, right: int, modulo: Optional[int] = None 524 ) -> T: 525 if modulo is not None: 526 if not isinstance(modulo, int): 527 return NotImplemented 528 529 if modulo < 0 or modulo > self.MAX_VALUE: 530 raise ValueError() 531 532 if not isinstance(right, int): 533 return NotImplemented 534 535 result = int.__pow__(self, right, modulo) 536 537 if right < 0 or right > self.MAX_VALUE or result > self.MAX_VALUE: 538 raise ValueError() 539 540 return int.__new__(self.__class__, result) 541 542 def wrapping_pow(self: T, right: int, modulo: Optional[int] = None) -> T: 543 """ 544 Return a new instance containing `self ** right (mod modulo)`. 545 546 If omitted, `modulo` defaults to `Uint(self.MAX_VALUE) + 1`. 547 548 Passing a `right` or `modulo` value greater than [`MAX_VALUE`] or 549 less than zero will raise a `ValueError`, even if the result would fit 550 in this integer type. 551 552 [`MAX_VALUE`]: ref:ethereum.base_types.FixedUint.MAX_VALUE 553 """ 554 if modulo is not None: 555 if not isinstance(modulo, int): 556 return NotImplemented 557 558 if modulo < 0 or modulo > self.MAX_VALUE: 559 raise ValueError() 560 561 if not isinstance(right, int): 562 return NotImplemented 563 564 if right < 0 or right > self.MAX_VALUE: 565 raise ValueError() 566 567 # This is a fast way of ensuring that the result is < (2 ** 256) 568 return int.__new__( 569 self.__class__, int.__pow__(self, right, modulo) & self.MAX_VALUE 570 ) 571 572 def __rpow__( # type: ignore[misc] 573 self: T, left: int, modulo: Optional[int] = None 574 ) -> T: 575 if modulo is not None: 576 if not isinstance(modulo, int): 577 return NotImplemented 578 579 if modulo < 0 or modulo > self.MAX_VALUE: 580 raise ValueError() 581 582 if not isinstance(left, int): 583 return NotImplemented 584 585 if left < 0 or left > self.MAX_VALUE: 586 raise ValueError() 587 588 return int.__new__(self.__class__, int.__rpow__(self, left, modulo)) 589 590 def __ipow__( # type: ignore[override] 591 self: T, right: int, modulo: Optional[int] = None 592 ) -> T: 593 return self.__pow__(right, modulo) 594 595 def __and__(self: T, right: int) -> T: 596 if not isinstance(right, int): 597 return NotImplemented 598 599 if right < 0 or right > self.MAX_VALUE: 600 raise ValueError() 601 602 return int.__new__(self.__class__, int.__and__(self, right)) 603 604 def __or__(self: T, right: int) -> T: 605 if not isinstance(right, int): 606 return NotImplemented 607 608 if right < 0 or right > self.MAX_VALUE: 609 raise ValueError() 610 611 return int.__new__(self.__class__, int.__or__(self, right)) 612 613 def __xor__(self: T, right: int) -> T: 614 if not isinstance(right, int): 615 return NotImplemented 616 617 if right < 0 or right > self.MAX_VALUE: 618 raise ValueError() 619 620 return int.__new__(self.__class__, int.__xor__(self, right)) 621 622 def __rxor__(self: T, left: int) -> T: 623 if not isinstance(left, int): 624 return NotImplemented 625 626 if left < 0 or left > self.MAX_VALUE: 627 raise ValueError() 628 629 return int.__new__(self.__class__, int.__rxor__(self, left)) 630 631 def __ixor__(self: T, right: int) -> T: 632 return self.__xor__(right) 633 634 def __invert__(self: T) -> T: 635 return int.__new__( 636 self.__class__, int.__invert__(self) & self.MAX_VALUE 637 ) 638 639 def __rshift__(self: T, shift_by: int) -> T: 640 if not isinstance(shift_by, int): 641 return NotImplemented 642 return int.__new__(self.__class__, int.__rshift__(self, shift_by)) 643 644 def to_be_bytes(self) -> "Bytes": 645 """ 646 Converts this unsigned integer into its big endian representation, 647 omitting leading zero bytes. 648 """ 649 bit_length = self.bit_length() 650 byte_length = (bit_length + 7) // 8 651 return self.to_bytes(byte_length, "big") 652 653 # TODO: Implement neg, pos, abs ... 654 655 656class U256(FixedUint): 657 """ 658 Unsigned integer, which can represent `0` to `2 ** 256 - 1`, inclusive. 659 """ 660 661 MAX_VALUE: ClassVar["U256"] 662 """ 663 Largest value that can be represented by this integer type. 664 """ 665 666 __slots__ = () 667 668 @classmethod 669 def from_be_bytes(cls: Type, buffer: "Bytes") -> "U256": 670 """ 671 Converts a sequence of bytes into a fixed sized unsigned integer 672 from its big endian representation. 673 """ 674 if len(buffer) > 32: 675 raise ValueError() 676 677 return cls(int.from_bytes(buffer, "big")) 678 679 @classmethod 680 def from_signed(cls: Type, value: int) -> "U256": 681 """ 682 Creates an unsigned integer representing `value` using two's 683 complement. 684 """ 685 if value >= 0: 686 return cls(value) 687 688 return cls(value & cls.MAX_VALUE) 689 690 def to_be_bytes32(self) -> "Bytes32": 691 """ 692 Converts this 256-bit unsigned integer into its big endian 693 representation with exactly 32 bytes. 694 """ 695 return Bytes32(self.to_bytes(32, "big")) 696 697 def to_signed(self) -> int: 698 """ 699 Decodes a signed integer from its two's complement representation. 700 """ 701 if self.bit_length() < 256: 702 # This means that the sign bit is 0 703 return int(self) 704 705 # -1 * (2's complement of U256 value) 706 return int(self) - U256_CEIL_VALUE 707 708 709U256.MAX_VALUE = int.__new__(U256, (2**256) - 1) 710 711 712class U32(FixedUint): 713 """ 714 Unsigned positive integer, which can represent `0` to `2 ** 32 - 1`, 715 inclusive. 716 """ 717 718 MAX_VALUE: ClassVar["U32"] 719 """ 720 Largest value that can be represented by this integer type. 721 """ 722 723 __slots__ = () 724 725 @classmethod 726 def from_le_bytes(cls: Type, buffer: "Bytes") -> "U32": 727 """ 728 Converts a sequence of bytes into an arbitrarily sized unsigned integer 729 from its little endian representation. 730 """ 731 if len(buffer) > 4: 732 raise ValueError() 733 734 return cls(int.from_bytes(buffer, "little")) 735 736 def to_le_bytes4(self) -> "Bytes4": 737 """ 738 Converts this fixed sized unsigned integer into its little endian 739 representation, with exactly 4 bytes. 740 """ 741 return Bytes4(self.to_bytes(4, "little")) 742 743 def to_le_bytes(self) -> "Bytes": 744 """ 745 Converts this fixed sized unsigned integer into its little endian 746 representation, in the fewest bytes possible. 747 """ 748 bit_length = self.bit_length() 749 byte_length = (bit_length + 7) // 8 750 return self.to_bytes(byte_length, "little") 751 752 753U32.MAX_VALUE = int.__new__(U32, (2**32) - 1) 754 755 756class U64(FixedUint): 757 """ 758 Unsigned positive integer, which can represent `0` to `2 ** 64 - 1`, 759 inclusive. 760 """ 761 762 MAX_VALUE: ClassVar["U64"] 763 """ 764 Largest value that can be represented by this integer type. 765 """ 766 767 __slots__ = () 768 769 @classmethod 770 def from_le_bytes(cls: Type, buffer: "Bytes") -> "U64": 771 """ 772 Converts a sequence of bytes into an arbitrarily sized unsigned integer 773 from its little endian representation. 774 """ 775 if len(buffer) > 8: 776 raise ValueError() 777 778 return cls(int.from_bytes(buffer, "little")) 779 780 def to_le_bytes8(self) -> "Bytes8": 781 """ 782 Converts this fixed sized unsigned integer into its little endian 783 representation, with exactly 8 bytes. 784 """ 785 return Bytes8(self.to_bytes(8, "little")) 786 787 def to_le_bytes(self) -> "Bytes": 788 """ 789 Converts this fixed sized unsigned integer into its little endian 790 representation, in the fewest bytes possible. 791 """ 792 bit_length = self.bit_length() 793 byte_length = (bit_length + 7) // 8 794 return self.to_bytes(byte_length, "little") 795 796 @classmethod 797 def from_be_bytes(cls: Type, buffer: "Bytes") -> "U64": 798 """ 799 Converts a sequence of bytes into an unsigned 64 bit integer from its 800 big endian representation. 801 """ 802 if len(buffer) > 8: 803 raise ValueError() 804 805 return cls(int.from_bytes(buffer, "big")) 806 807 808U64.MAX_VALUE = int.__new__(U64, (2**64) - 1) 809 810 811B = TypeVar("B", bound="FixedBytes") 812 813 814class FixedBytes(bytes): 815 """ 816 Superclass for fixed sized byte arrays. Not intended to be used directly, 817 but should be subclassed. 818 """ 819 820 LENGTH: int 821 """ 822 Number of bytes in each instance of this class. 823 """ 824 825 __slots__ = () 826 827 def __new__(cls: Type[B], *args: Any, **kwargs: Any) -> B: 828 """ 829 Create a new instance, ensuring the result has the correct length. 830 """ 831 result = super(FixedBytes, cls).__new__(cls, *args, **kwargs) 832 if len(result) != cls.LENGTH: 833 raise ValueError( 834 f"expected {cls.LENGTH} bytes but got {len(result)}" 835 ) 836 return result 837 838 839class Bytes0(FixedBytes): 840 """ 841 Byte array of exactly zero elements. 842 """ 843 844 LENGTH = 0 845 """ 846 Number of bytes in each instance of this class. 847 """ 848 849 850class Bytes4(FixedBytes): 851 """ 852 Byte array of exactly four elements. 853 """ 854 855 LENGTH = 4 856 """ 857 Number of bytes in each instance of this class. 858 """ 859 860 861class Bytes8(FixedBytes): 862 """ 863 Byte array of exactly eight elements. 864 """ 865 866 LENGTH = 8 867 """ 868 Number of bytes in each instance of this class. 869 """ 870 871 872class Bytes20(FixedBytes): 873 """ 874 Byte array of exactly 20 elements. 875 """ 876 877 LENGTH = 20 878 """ 879 Number of bytes in each instance of this class. 880 """ 881 882 883class Bytes32(FixedBytes): 884 """ 885 Byte array of exactly 32 elements. 886 """ 887 888 LENGTH = 32 889 """ 890 Number of bytes in each instance of this class. 891 """ 892 893 894class Bytes64(FixedBytes): 895 """ 896 Byte array of exactly 64 elements. 897 """ 898 899 LENGTH = 64 900 """ 901 Number of bytes in each instance of this class. 902 """ 903 904 905class Bytes256(FixedBytes): 906 """ 907 Byte array of exactly 256 elements. 908 """ 909 910 LENGTH = 256 911 """ 912 Number of bytes in each instance of this class. 913 """ 914 915 916Bytes = bytes 917""" 918Sequence of bytes (octets) of arbitrary length. 919""" 920 921 922def _setattr_function(self: Any, attr: str, value: Any) -> None: 923 if getattr(self, "_frozen", None): 924 raise Exception("Mutating frozen dataclasses is not allowed.") 925 else: 926 object.__setattr__(self, attr, value) 927 928 929def _delattr_function(self: Any, attr: str) -> None: 930 if self._frozen: 931 raise Exception("Mutating frozen dataclasses is not allowed.") 932 else: 933 object.__delattr__(self, attr) 934 935 936def _make_init_function(f: Callable) -> Callable: 937 def init_function(self: Any, *args: Any, **kwargs: Any) -> None: 938 will_be_frozen = kwargs.pop("_frozen", True) 939 object.__setattr__(self, "_frozen", False) 940 f(self, *args, **kwargs) 941 self._frozen = will_be_frozen 942 943 return init_function 944 945 946def slotted_freezable(cls: Any) -> Any: 947 """ 948 Monkey patches a dataclass so it can be frozen by setting `_frozen` to 949 `True` and uses `__slots__` for efficiency. 950 951 Instances will be created frozen by default unless you pass `_frozen=False` 952 to `__init__`. 953 """ 954 cls.__slots__ = ("_frozen",) + tuple(cls.__annotations__) 955 cls.__init__ = _make_init_function(cls.__init__) 956 cls.__setattr__ = _setattr_function 957 cls.__delattr__ = _delattr_function 958 return type(cls)(cls.__name__, cls.__bases__, dict(cls.__dict__)) 959 960 961S = TypeVar("S") 962 963 964def modify(obj: S, f: Callable[[S], None]) -> S: 965 """ 966 Create a copy of `obj` (which must be [`@slotted_freezable`]), and modify 967 it by applying `f`. The returned copy will be frozen. 968 969 [`@slotted_freezable`]: ref:ethereum.base_types.slotted_freezable 970 """ 971 assert is_dataclass(obj) 972 assert isinstance(obj, SlottedFreezable) 973 new_obj = replace(obj, _frozen=False) 974 f(new_obj) 975 new_obj._frozen = True 976 return new_obj
37@runtime_checkable 38class SlottedFreezable(Protocol): 39 """ 40 A [`Protocol`] implemented by data classes annotated with 41 [`@slotted_freezable`]. 42 43 [`@slotted_freezable`]: ref:ethereum.base_types.slotted_freezable 44 [`Protocol`]: https://docs.python.org/library/typing.html#typing.Protocol 45 """ 46 47 _frozen: bool
A [Protocol
] implemented by data classes annotated with
[@slotted_freezable
].
Smallest value that requires 256 bits to represent. Mostly used in signed
arithmetic operations, like [sdiv
].
Smallest value that requires 257 bits to represent. Used when converting a
[U256
] in two's complement format to a regular int
in [U256.to_signed
].
68class Uint(int): 69 """ 70 Unsigned integer of arbitrary size. 71 """ 72 73 __slots__ = () 74 75 @classmethod 76 def from_be_bytes(cls: Type, buffer: "Bytes") -> "Uint": 77 """ 78 Converts a sequence of bytes into an arbitrarily sized unsigned integer 79 from its big endian representation. 80 """ 81 return cls(int.from_bytes(buffer, "big")) 82 83 @classmethod 84 def from_le_bytes(cls: Type, buffer: "Bytes") -> "Uint": 85 """ 86 Converts a sequence of bytes into an arbitrarily sized unsigned integer 87 from its little endian representation. 88 """ 89 return cls(int.from_bytes(buffer, "little")) 90 91 def __init__(self, value: int) -> None: 92 if not isinstance(value, int): 93 raise TypeError() 94 95 if value < 0: 96 raise ValueError() 97 98 def __radd__(self, left: int) -> "Uint": 99 return self.__add__(left) 100 101 def __add__(self, right: int) -> "Uint": 102 if not isinstance(right, int): 103 return NotImplemented 104 105 if right < 0: 106 raise ValueError() 107 108 return int.__new__(self.__class__, int.__add__(self, right)) 109 110 def __iadd__(self, right: int) -> "Uint": 111 return self.__add__(right) 112 113 def __sub__(self, right: int) -> "Uint": 114 if not isinstance(right, int): 115 return NotImplemented 116 117 if right < 0 or self < right: 118 raise ValueError() 119 120 return int.__new__(self.__class__, int.__sub__(self, right)) 121 122 def __rsub__(self, left: int) -> "Uint": 123 if not isinstance(left, int): 124 return NotImplemented 125 126 if left < 0 or self > left: 127 raise ValueError() 128 129 return int.__new__(self.__class__, int.__rsub__(self, left)) 130 131 def __isub__(self, right: int) -> "Uint": 132 return self.__sub__(right) 133 134 def __mul__(self, right: int) -> "Uint": 135 if not isinstance(right, int): 136 return NotImplemented 137 138 if right < 0: 139 raise ValueError() 140 141 return int.__new__(self.__class__, int.__mul__(self, right)) 142 143 def __rmul__(self, left: int) -> "Uint": 144 return self.__mul__(left) 145 146 def __imul__(self, right: int) -> "Uint": 147 return self.__mul__(right) 148 149 # Explicitly don't override __truediv__, __rtruediv__, and __itruediv__ 150 # since they return floats anyway. 151 152 def __floordiv__(self, right: int) -> "Uint": 153 if not isinstance(right, int): 154 return NotImplemented 155 156 if right < 0: 157 raise ValueError() 158 159 return int.__new__(self.__class__, int.__floordiv__(self, right)) 160 161 def __rfloordiv__(self, left: int) -> "Uint": 162 if not isinstance(left, int): 163 return NotImplemented 164 165 if left < 0: 166 raise ValueError() 167 168 return int.__new__(self.__class__, int.__rfloordiv__(self, left)) 169 170 def __ifloordiv__(self, right: int) -> "Uint": 171 return self.__floordiv__(right) 172 173 def __mod__(self, right: int) -> "Uint": 174 if not isinstance(right, int): 175 return NotImplemented 176 177 if right < 0: 178 raise ValueError() 179 180 return int.__new__(self.__class__, int.__mod__(self, right)) 181 182 def __rmod__(self, left: int) -> "Uint": 183 if not isinstance(left, int): 184 return NotImplemented 185 186 if left < 0: 187 raise ValueError() 188 189 return int.__new__(self.__class__, int.__rmod__(self, left)) 190 191 def __imod__(self, right: int) -> "Uint": 192 return self.__mod__(right) 193 194 def __divmod__(self, right: int) -> Tuple["Uint", "Uint"]: 195 if not isinstance(right, int): 196 return NotImplemented 197 198 if right < 0: 199 raise ValueError() 200 201 result = int.__divmod__(self, right) 202 return ( 203 int.__new__(self.__class__, result[0]), 204 int.__new__(self.__class__, result[1]), 205 ) 206 207 def __rdivmod__(self, left: int) -> Tuple["Uint", "Uint"]: 208 if not isinstance(left, int): 209 return NotImplemented 210 211 if left < 0: 212 raise ValueError() 213 214 result = int.__rdivmod__(self, left) 215 return ( 216 int.__new__(self.__class__, result[0]), 217 int.__new__(self.__class__, result[1]), 218 ) 219 220 def __pow__( # type: ignore[override] 221 self, right: int, modulo: Optional[int] = None 222 ) -> "Uint": 223 if modulo is not None: 224 if not isinstance(modulo, int): 225 return NotImplemented 226 227 if modulo < 0: 228 raise ValueError() 229 230 if not isinstance(right, int): 231 return NotImplemented 232 233 if right < 0: 234 raise ValueError() 235 236 return int.__new__(self.__class__, int.__pow__(self, right, modulo)) 237 238 def __rpow__( # type: ignore[misc] 239 self, left: int, modulo: Optional[int] = None 240 ) -> "Uint": 241 if modulo is not None: 242 if not isinstance(modulo, int): 243 return NotImplemented 244 245 if modulo < 0: 246 raise ValueError() 247 248 if not isinstance(left, int): 249 return NotImplemented 250 251 if left < 0: 252 raise ValueError() 253 254 return int.__new__(self.__class__, int.__rpow__(self, left, modulo)) 255 256 def __ipow__( # type: ignore[override] 257 self, right: int, modulo: Optional[int] = None 258 ) -> "Uint": 259 return self.__pow__(right, modulo) 260 261 def __xor__(self, right: int) -> "Uint": 262 if not isinstance(right, int): 263 return NotImplemented 264 265 if right < 0: 266 raise ValueError() 267 268 return int.__new__(self.__class__, int.__xor__(self, right)) 269 270 def __rxor__(self, left: int) -> "Uint": 271 if not isinstance(left, int): 272 return NotImplemented 273 274 if left < 0: 275 raise ValueError() 276 277 return int.__new__(self.__class__, int.__rxor__(self, left)) 278 279 def __ixor__(self, right: int) -> "Uint": 280 return self.__xor__(right) 281 282 # TODO: Implement and, or, neg, pos, abs, invert, ... 283 284 def to_be_bytes32(self) -> "Bytes32": 285 """ 286 Converts this arbitrarily sized unsigned integer into its big endian 287 representation with exactly 32 bytes. 288 """ 289 return Bytes32(self.to_bytes(32, "big")) 290 291 def to_be_bytes(self) -> "Bytes": 292 """ 293 Converts this arbitrarily sized unsigned integer into its big endian 294 representation, without padding. 295 """ 296 bit_length = self.bit_length() 297 byte_length = (bit_length + 7) // 8 298 return self.to_bytes(byte_length, "big") 299 300 def to_le_bytes(self, number_bytes: Optional[int] = None) -> "Bytes": 301 """ 302 Converts this arbitrarily sized unsigned integer into its little endian 303 representation, without padding. 304 """ 305 if number_bytes is None: 306 bit_length = self.bit_length() 307 number_bytes = (bit_length + 7) // 8 308 return self.to_bytes(number_bytes, "little")
Unsigned integer of arbitrary size.
75 @classmethod 76 def from_be_bytes(cls: Type, buffer: "Bytes") -> "Uint": 77 """ 78 Converts a sequence of bytes into an arbitrarily sized unsigned integer 79 from its big endian representation. 80 """ 81 return cls(int.from_bytes(buffer, "big"))
Converts a sequence of bytes into an arbitrarily sized unsigned integer from its big endian representation.
83 @classmethod 84 def from_le_bytes(cls: Type, buffer: "Bytes") -> "Uint": 85 """ 86 Converts a sequence of bytes into an arbitrarily sized unsigned integer 87 from its little endian representation. 88 """ 89 return cls(int.from_bytes(buffer, "little"))
Converts a sequence of bytes into an arbitrarily sized unsigned integer from its little endian representation.
284 def to_be_bytes32(self) -> "Bytes32": 285 """ 286 Converts this arbitrarily sized unsigned integer into its big endian 287 representation with exactly 32 bytes. 288 """ 289 return Bytes32(self.to_bytes(32, "big"))
Converts this arbitrarily sized unsigned integer into its big endian representation with exactly 32 bytes.
291 def to_be_bytes(self) -> "Bytes": 292 """ 293 Converts this arbitrarily sized unsigned integer into its big endian 294 representation, without padding. 295 """ 296 bit_length = self.bit_length() 297 byte_length = (bit_length + 7) // 8 298 return self.to_bytes(byte_length, "big")
Converts this arbitrarily sized unsigned integer into its big endian representation, without padding.
300 def to_le_bytes(self, number_bytes: Optional[int] = None) -> "Bytes": 301 """ 302 Converts this arbitrarily sized unsigned integer into its little endian 303 representation, without padding. 304 """ 305 if number_bytes is None: 306 bit_length = self.bit_length() 307 number_bytes = (bit_length + 7) // 8 308 return self.to_bytes(number_bytes, "little")
Converts this arbitrarily sized unsigned integer into its little endian representation, without padding.
Inherited Members
- builtins.int
- conjugate
- bit_length
- to_bytes
- from_bytes
- as_integer_ratio
- real
- imag
- numerator
- denominator
314class FixedUint(int): 315 """ 316 Superclass for fixed size unsigned integers. Not intended to be used 317 directly, but rather to be subclassed. 318 """ 319 320 MAX_VALUE: ClassVar["FixedUint"] 321 """ 322 Largest value that can be represented by this integer type. 323 """ 324 325 __slots__ = () 326 327 def __init__(self: T, value: int) -> None: 328 if not isinstance(value, int): 329 raise TypeError() 330 331 if value < 0 or value > self.MAX_VALUE: 332 raise ValueError() 333 334 def __radd__(self: T, left: int) -> T: 335 return self.__add__(left) 336 337 def __add__(self: T, right: int) -> T: 338 if not isinstance(right, int): 339 return NotImplemented 340 341 result = int.__add__(self, right) 342 343 if right < 0 or result > self.MAX_VALUE: 344 raise ValueError() 345 346 return int.__new__(self.__class__, result) 347 348 def wrapping_add(self: T, right: int) -> T: 349 """ 350 Return a new instance containing `self + right (mod N)`. 351 352 Passing a `right` value greater than [`MAX_VALUE`] or less than zero 353 will raise a `ValueError`, even if the result would fit in this integer 354 type. 355 356 [`MAX_VALUE`]: ref:ethereum.base_types.FixedUint.MAX_VALUE 357 """ 358 if not isinstance(right, int): 359 return NotImplemented 360 361 if right < 0 or right > self.MAX_VALUE: 362 raise ValueError() 363 364 # This is a fast way of ensuring that the result is < (2 ** 256) 365 return int.__new__( 366 self.__class__, int.__add__(self, right) & self.MAX_VALUE 367 ) 368 369 def __iadd__(self: T, right: int) -> T: 370 return self.__add__(right) 371 372 def __sub__(self: T, right: int) -> T: 373 if not isinstance(right, int): 374 return NotImplemented 375 376 if right < 0 or right > self.MAX_VALUE or self < right: 377 raise ValueError() 378 379 return int.__new__(self.__class__, int.__sub__(self, right)) 380 381 def wrapping_sub(self: T, right: int) -> T: 382 """ 383 Return a new instance containing `self - right (mod N)`. 384 385 Passing a `right` value greater than [`MAX_VALUE`] or less than zero 386 will raise a `ValueError`, even if the result would fit in this integer 387 type. 388 389 [`MAX_VALUE`]: ref:ethereum.base_types.FixedUint.MAX_VALUE 390 """ 391 if not isinstance(right, int): 392 return NotImplemented 393 394 if right < 0 or right > self.MAX_VALUE: 395 raise ValueError() 396 397 # This is a fast way of ensuring that the result is < (2 ** 256) 398 return int.__new__( 399 self.__class__, int.__sub__(self, right) & self.MAX_VALUE 400 ) 401 402 def __rsub__(self: T, left: int) -> T: 403 if not isinstance(left, int): 404 return NotImplemented 405 406 if left < 0 or left > self.MAX_VALUE or self > left: 407 raise ValueError() 408 409 return int.__new__(self.__class__, int.__rsub__(self, left)) 410 411 def __isub__(self: T, right: int) -> T: 412 return self.__sub__(right) 413 414 def __mul__(self: T, right: int) -> T: 415 if not isinstance(right, int): 416 return NotImplemented 417 418 result = int.__mul__(self, right) 419 420 if right < 0 or result > self.MAX_VALUE: 421 raise ValueError() 422 423 return int.__new__(self.__class__, result) 424 425 def wrapping_mul(self: T, right: int) -> T: 426 """ 427 Return a new instance containing `self * right (mod N)`. 428 429 Passing a `right` value greater than [`MAX_VALUE`] or less than zero 430 will raise a `ValueError`, even if the result would fit in this integer 431 type. 432 433 [`MAX_VALUE`]: ref:ethereum.base_types.FixedUint.MAX_VALUE 434 """ 435 if not isinstance(right, int): 436 return NotImplemented 437 438 if right < 0 or right > self.MAX_VALUE: 439 raise ValueError() 440 441 # This is a fast way of ensuring that the result is < (2 ** 256) 442 return int.__new__( 443 self.__class__, int.__mul__(self, right) & self.MAX_VALUE 444 ) 445 446 def __rmul__(self: T, left: int) -> T: 447 return self.__mul__(left) 448 449 def __imul__(self: T, right: int) -> T: 450 return self.__mul__(right) 451 452 # Explicitly don't override __truediv__, __rtruediv__, and __itruediv__ 453 # since they return floats anyway. 454 455 def __floordiv__(self: T, right: int) -> T: 456 if not isinstance(right, int): 457 return NotImplemented 458 459 if right < 0 or right > self.MAX_VALUE: 460 raise ValueError() 461 462 return int.__new__(self.__class__, int.__floordiv__(self, right)) 463 464 def __rfloordiv__(self: T, left: int) -> T: 465 if not isinstance(left, int): 466 return NotImplemented 467 468 if left < 0 or left > self.MAX_VALUE: 469 raise ValueError() 470 471 return int.__new__(self.__class__, int.__rfloordiv__(self, left)) 472 473 def __ifloordiv__(self: T, right: int) -> T: 474 return self.__floordiv__(right) 475 476 def __mod__(self: T, right: int) -> T: 477 if not isinstance(right, int): 478 return NotImplemented 479 480 if right < 0 or right > self.MAX_VALUE: 481 raise ValueError() 482 483 return int.__new__(self.__class__, int.__mod__(self, right)) 484 485 def __rmod__(self: T, left: int) -> T: 486 if not isinstance(left, int): 487 return NotImplemented 488 489 if left < 0 or left > self.MAX_VALUE: 490 raise ValueError() 491 492 return int.__new__(self.__class__, int.__rmod__(self, left)) 493 494 def __imod__(self: T, right: int) -> T: 495 return self.__mod__(right) 496 497 def __divmod__(self: T, right: int) -> Tuple[T, T]: 498 if not isinstance(right, int): 499 return NotImplemented 500 501 if right < 0 or right > self.MAX_VALUE: 502 raise ValueError() 503 504 result = super(FixedUint, self).__divmod__(right) 505 return ( 506 int.__new__(self.__class__, result[0]), 507 int.__new__(self.__class__, result[1]), 508 ) 509 510 def __rdivmod__(self: T, left: int) -> Tuple[T, T]: 511 if not isinstance(left, int): 512 return NotImplemented 513 514 if left < 0 or left > self.MAX_VALUE: 515 raise ValueError() 516 517 result = super(FixedUint, self).__rdivmod__(left) 518 return ( 519 int.__new__(self.__class__, result[0]), 520 int.__new__(self.__class__, result[1]), 521 ) 522 523 def __pow__( # type: ignore[override] 524 self: T, right: int, modulo: Optional[int] = None 525 ) -> T: 526 if modulo is not None: 527 if not isinstance(modulo, int): 528 return NotImplemented 529 530 if modulo < 0 or modulo > self.MAX_VALUE: 531 raise ValueError() 532 533 if not isinstance(right, int): 534 return NotImplemented 535 536 result = int.__pow__(self, right, modulo) 537 538 if right < 0 or right > self.MAX_VALUE or result > self.MAX_VALUE: 539 raise ValueError() 540 541 return int.__new__(self.__class__, result) 542 543 def wrapping_pow(self: T, right: int, modulo: Optional[int] = None) -> T: 544 """ 545 Return a new instance containing `self ** right (mod modulo)`. 546 547 If omitted, `modulo` defaults to `Uint(self.MAX_VALUE) + 1`. 548 549 Passing a `right` or `modulo` value greater than [`MAX_VALUE`] or 550 less than zero will raise a `ValueError`, even if the result would fit 551 in this integer type. 552 553 [`MAX_VALUE`]: ref:ethereum.base_types.FixedUint.MAX_VALUE 554 """ 555 if modulo is not None: 556 if not isinstance(modulo, int): 557 return NotImplemented 558 559 if modulo < 0 or modulo > self.MAX_VALUE: 560 raise ValueError() 561 562 if not isinstance(right, int): 563 return NotImplemented 564 565 if right < 0 or right > self.MAX_VALUE: 566 raise ValueError() 567 568 # This is a fast way of ensuring that the result is < (2 ** 256) 569 return int.__new__( 570 self.__class__, int.__pow__(self, right, modulo) & self.MAX_VALUE 571 ) 572 573 def __rpow__( # type: ignore[misc] 574 self: T, left: int, modulo: Optional[int] = None 575 ) -> T: 576 if modulo is not None: 577 if not isinstance(modulo, int): 578 return NotImplemented 579 580 if modulo < 0 or modulo > self.MAX_VALUE: 581 raise ValueError() 582 583 if not isinstance(left, int): 584 return NotImplemented 585 586 if left < 0 or left > self.MAX_VALUE: 587 raise ValueError() 588 589 return int.__new__(self.__class__, int.__rpow__(self, left, modulo)) 590 591 def __ipow__( # type: ignore[override] 592 self: T, right: int, modulo: Optional[int] = None 593 ) -> T: 594 return self.__pow__(right, modulo) 595 596 def __and__(self: T, right: int) -> T: 597 if not isinstance(right, int): 598 return NotImplemented 599 600 if right < 0 or right > self.MAX_VALUE: 601 raise ValueError() 602 603 return int.__new__(self.__class__, int.__and__(self, right)) 604 605 def __or__(self: T, right: int) -> T: 606 if not isinstance(right, int): 607 return NotImplemented 608 609 if right < 0 or right > self.MAX_VALUE: 610 raise ValueError() 611 612 return int.__new__(self.__class__, int.__or__(self, right)) 613 614 def __xor__(self: T, right: int) -> T: 615 if not isinstance(right, int): 616 return NotImplemented 617 618 if right < 0 or right > self.MAX_VALUE: 619 raise ValueError() 620 621 return int.__new__(self.__class__, int.__xor__(self, right)) 622 623 def __rxor__(self: T, left: int) -> T: 624 if not isinstance(left, int): 625 return NotImplemented 626 627 if left < 0 or left > self.MAX_VALUE: 628 raise ValueError() 629 630 return int.__new__(self.__class__, int.__rxor__(self, left)) 631 632 def __ixor__(self: T, right: int) -> T: 633 return self.__xor__(right) 634 635 def __invert__(self: T) -> T: 636 return int.__new__( 637 self.__class__, int.__invert__(self) & self.MAX_VALUE 638 ) 639 640 def __rshift__(self: T, shift_by: int) -> T: 641 if not isinstance(shift_by, int): 642 return NotImplemented 643 return int.__new__(self.__class__, int.__rshift__(self, shift_by)) 644 645 def to_be_bytes(self) -> "Bytes": 646 """ 647 Converts this unsigned integer into its big endian representation, 648 omitting leading zero bytes. 649 """ 650 bit_length = self.bit_length() 651 byte_length = (bit_length + 7) // 8 652 return self.to_bytes(byte_length, "big") 653 654 # TODO: Implement neg, pos, abs ...
Superclass for fixed size unsigned integers. Not intended to be used directly, but rather to be subclassed.
348 def wrapping_add(self: T, right: int) -> T: 349 """ 350 Return a new instance containing `self + right (mod N)`. 351 352 Passing a `right` value greater than [`MAX_VALUE`] or less than zero 353 will raise a `ValueError`, even if the result would fit in this integer 354 type. 355 356 [`MAX_VALUE`]: ref:ethereum.base_types.FixedUint.MAX_VALUE 357 """ 358 if not isinstance(right, int): 359 return NotImplemented 360 361 if right < 0 or right > self.MAX_VALUE: 362 raise ValueError() 363 364 # This is a fast way of ensuring that the result is < (2 ** 256) 365 return int.__new__( 366 self.__class__, int.__add__(self, right) & self.MAX_VALUE 367 )
Return a new instance containing self + right (mod N)
.
Passing a right
value greater than [MAX_VALUE
] or less than zero
will raise a ValueError
, even if the result would fit in this integer
type.
381 def wrapping_sub(self: T, right: int) -> T: 382 """ 383 Return a new instance containing `self - right (mod N)`. 384 385 Passing a `right` value greater than [`MAX_VALUE`] or less than zero 386 will raise a `ValueError`, even if the result would fit in this integer 387 type. 388 389 [`MAX_VALUE`]: ref:ethereum.base_types.FixedUint.MAX_VALUE 390 """ 391 if not isinstance(right, int): 392 return NotImplemented 393 394 if right < 0 or right > self.MAX_VALUE: 395 raise ValueError() 396 397 # This is a fast way of ensuring that the result is < (2 ** 256) 398 return int.__new__( 399 self.__class__, int.__sub__(self, right) & self.MAX_VALUE 400 )
Return a new instance containing self - right (mod N)
.
Passing a right
value greater than [MAX_VALUE
] or less than zero
will raise a ValueError
, even if the result would fit in this integer
type.
425 def wrapping_mul(self: T, right: int) -> T: 426 """ 427 Return a new instance containing `self * right (mod N)`. 428 429 Passing a `right` value greater than [`MAX_VALUE`] or less than zero 430 will raise a `ValueError`, even if the result would fit in this integer 431 type. 432 433 [`MAX_VALUE`]: ref:ethereum.base_types.FixedUint.MAX_VALUE 434 """ 435 if not isinstance(right, int): 436 return NotImplemented 437 438 if right < 0 or right > self.MAX_VALUE: 439 raise ValueError() 440 441 # This is a fast way of ensuring that the result is < (2 ** 256) 442 return int.__new__( 443 self.__class__, int.__mul__(self, right) & self.MAX_VALUE 444 )
Return a new instance containing self * right (mod N)
.
Passing a right
value greater than [MAX_VALUE
] or less than zero
will raise a ValueError
, even if the result would fit in this integer
type.
543 def wrapping_pow(self: T, right: int, modulo: Optional[int] = None) -> T: 544 """ 545 Return a new instance containing `self ** right (mod modulo)`. 546 547 If omitted, `modulo` defaults to `Uint(self.MAX_VALUE) + 1`. 548 549 Passing a `right` or `modulo` value greater than [`MAX_VALUE`] or 550 less than zero will raise a `ValueError`, even if the result would fit 551 in this integer type. 552 553 [`MAX_VALUE`]: ref:ethereum.base_types.FixedUint.MAX_VALUE 554 """ 555 if modulo is not None: 556 if not isinstance(modulo, int): 557 return NotImplemented 558 559 if modulo < 0 or modulo > self.MAX_VALUE: 560 raise ValueError() 561 562 if not isinstance(right, int): 563 return NotImplemented 564 565 if right < 0 or right > self.MAX_VALUE: 566 raise ValueError() 567 568 # This is a fast way of ensuring that the result is < (2 ** 256) 569 return int.__new__( 570 self.__class__, int.__pow__(self, right, modulo) & self.MAX_VALUE 571 )
Return a new instance containing self ** right (mod modulo)
.
If omitted, modulo
defaults to Uint(self.MAX_VALUE) + 1
.
Passing a right
or modulo
value greater than [MAX_VALUE
] or
less than zero will raise a ValueError
, even if the result would fit
in this integer type.
645 def to_be_bytes(self) -> "Bytes": 646 """ 647 Converts this unsigned integer into its big endian representation, 648 omitting leading zero bytes. 649 """ 650 bit_length = self.bit_length() 651 byte_length = (bit_length + 7) // 8 652 return self.to_bytes(byte_length, "big")
Converts this unsigned integer into its big endian representation, omitting leading zero bytes.
Inherited Members
- builtins.int
- conjugate
- bit_length
- to_bytes
- from_bytes
- as_integer_ratio
- real
- imag
- numerator
- denominator
657class U256(FixedUint): 658 """ 659 Unsigned integer, which can represent `0` to `2 ** 256 - 1`, inclusive. 660 """ 661 662 MAX_VALUE: ClassVar["U256"] 663 """ 664 Largest value that can be represented by this integer type. 665 """ 666 667 __slots__ = () 668 669 @classmethod 670 def from_be_bytes(cls: Type, buffer: "Bytes") -> "U256": 671 """ 672 Converts a sequence of bytes into a fixed sized unsigned integer 673 from its big endian representation. 674 """ 675 if len(buffer) > 32: 676 raise ValueError() 677 678 return cls(int.from_bytes(buffer, "big")) 679 680 @classmethod 681 def from_signed(cls: Type, value: int) -> "U256": 682 """ 683 Creates an unsigned integer representing `value` using two's 684 complement. 685 """ 686 if value >= 0: 687 return cls(value) 688 689 return cls(value & cls.MAX_VALUE) 690 691 def to_be_bytes32(self) -> "Bytes32": 692 """ 693 Converts this 256-bit unsigned integer into its big endian 694 representation with exactly 32 bytes. 695 """ 696 return Bytes32(self.to_bytes(32, "big")) 697 698 def to_signed(self) -> int: 699 """ 700 Decodes a signed integer from its two's complement representation. 701 """ 702 if self.bit_length() < 256: 703 # This means that the sign bit is 0 704 return int(self) 705 706 # -1 * (2's complement of U256 value) 707 return int(self) - U256_CEIL_VALUE
Unsigned integer, which can represent 0
to 2 ** 256 - 1
, inclusive.
Largest value that can be represented by this integer type.
669 @classmethod 670 def from_be_bytes(cls: Type, buffer: "Bytes") -> "U256": 671 """ 672 Converts a sequence of bytes into a fixed sized unsigned integer 673 from its big endian representation. 674 """ 675 if len(buffer) > 32: 676 raise ValueError() 677 678 return cls(int.from_bytes(buffer, "big"))
Converts a sequence of bytes into a fixed sized unsigned integer from its big endian representation.
680 @classmethod 681 def from_signed(cls: Type, value: int) -> "U256": 682 """ 683 Creates an unsigned integer representing `value` using two's 684 complement. 685 """ 686 if value >= 0: 687 return cls(value) 688 689 return cls(value & cls.MAX_VALUE)
Creates an unsigned integer representing value
using two's
complement.
691 def to_be_bytes32(self) -> "Bytes32": 692 """ 693 Converts this 256-bit unsigned integer into its big endian 694 representation with exactly 32 bytes. 695 """ 696 return Bytes32(self.to_bytes(32, "big"))
Converts this 256-bit unsigned integer into its big endian representation with exactly 32 bytes.
698 def to_signed(self) -> int: 699 """ 700 Decodes a signed integer from its two's complement representation. 701 """ 702 if self.bit_length() < 256: 703 # This means that the sign bit is 0 704 return int(self) 705 706 # -1 * (2's complement of U256 value) 707 return int(self) - U256_CEIL_VALUE
Decodes a signed integer from its two's complement representation.
Inherited Members
- builtins.int
- conjugate
- bit_length
- to_bytes
- from_bytes
- as_integer_ratio
- real
- imag
- numerator
- denominator
713class U32(FixedUint): 714 """ 715 Unsigned positive integer, which can represent `0` to `2 ** 32 - 1`, 716 inclusive. 717 """ 718 719 MAX_VALUE: ClassVar["U32"] 720 """ 721 Largest value that can be represented by this integer type. 722 """ 723 724 __slots__ = () 725 726 @classmethod 727 def from_le_bytes(cls: Type, buffer: "Bytes") -> "U32": 728 """ 729 Converts a sequence of bytes into an arbitrarily sized unsigned integer 730 from its little endian representation. 731 """ 732 if len(buffer) > 4: 733 raise ValueError() 734 735 return cls(int.from_bytes(buffer, "little")) 736 737 def to_le_bytes4(self) -> "Bytes4": 738 """ 739 Converts this fixed sized unsigned integer into its little endian 740 representation, with exactly 4 bytes. 741 """ 742 return Bytes4(self.to_bytes(4, "little")) 743 744 def to_le_bytes(self) -> "Bytes": 745 """ 746 Converts this fixed sized unsigned integer into its little endian 747 representation, in the fewest bytes possible. 748 """ 749 bit_length = self.bit_length() 750 byte_length = (bit_length + 7) // 8 751 return self.to_bytes(byte_length, "little")
Unsigned positive integer, which can represent 0
to 2 ** 32 - 1
,
inclusive.
726 @classmethod 727 def from_le_bytes(cls: Type, buffer: "Bytes") -> "U32": 728 """ 729 Converts a sequence of bytes into an arbitrarily sized unsigned integer 730 from its little endian representation. 731 """ 732 if len(buffer) > 4: 733 raise ValueError() 734 735 return cls(int.from_bytes(buffer, "little"))
Converts a sequence of bytes into an arbitrarily sized unsigned integer from its little endian representation.
737 def to_le_bytes4(self) -> "Bytes4": 738 """ 739 Converts this fixed sized unsigned integer into its little endian 740 representation, with exactly 4 bytes. 741 """ 742 return Bytes4(self.to_bytes(4, "little"))
Converts this fixed sized unsigned integer into its little endian representation, with exactly 4 bytes.
744 def to_le_bytes(self) -> "Bytes": 745 """ 746 Converts this fixed sized unsigned integer into its little endian 747 representation, in the fewest bytes possible. 748 """ 749 bit_length = self.bit_length() 750 byte_length = (bit_length + 7) // 8 751 return self.to_bytes(byte_length, "little")
Converts this fixed sized unsigned integer into its little endian representation, in the fewest bytes possible.
Inherited Members
- builtins.int
- conjugate
- bit_length
- to_bytes
- from_bytes
- as_integer_ratio
- real
- imag
- numerator
- denominator
757class U64(FixedUint): 758 """ 759 Unsigned positive integer, which can represent `0` to `2 ** 64 - 1`, 760 inclusive. 761 """ 762 763 MAX_VALUE: ClassVar["U64"] 764 """ 765 Largest value that can be represented by this integer type. 766 """ 767 768 __slots__ = () 769 770 @classmethod 771 def from_le_bytes(cls: Type, buffer: "Bytes") -> "U64": 772 """ 773 Converts a sequence of bytes into an arbitrarily sized unsigned integer 774 from its little endian representation. 775 """ 776 if len(buffer) > 8: 777 raise ValueError() 778 779 return cls(int.from_bytes(buffer, "little")) 780 781 def to_le_bytes8(self) -> "Bytes8": 782 """ 783 Converts this fixed sized unsigned integer into its little endian 784 representation, with exactly 8 bytes. 785 """ 786 return Bytes8(self.to_bytes(8, "little")) 787 788 def to_le_bytes(self) -> "Bytes": 789 """ 790 Converts this fixed sized unsigned integer into its little endian 791 representation, in the fewest bytes possible. 792 """ 793 bit_length = self.bit_length() 794 byte_length = (bit_length + 7) // 8 795 return self.to_bytes(byte_length, "little") 796 797 @classmethod 798 def from_be_bytes(cls: Type, buffer: "Bytes") -> "U64": 799 """ 800 Converts a sequence of bytes into an unsigned 64 bit integer from its 801 big endian representation. 802 """ 803 if len(buffer) > 8: 804 raise ValueError() 805 806 return cls(int.from_bytes(buffer, "big"))
Unsigned positive integer, which can represent 0
to 2 ** 64 - 1
,
inclusive.
770 @classmethod 771 def from_le_bytes(cls: Type, buffer: "Bytes") -> "U64": 772 """ 773 Converts a sequence of bytes into an arbitrarily sized unsigned integer 774 from its little endian representation. 775 """ 776 if len(buffer) > 8: 777 raise ValueError() 778 779 return cls(int.from_bytes(buffer, "little"))
Converts a sequence of bytes into an arbitrarily sized unsigned integer from its little endian representation.
781 def to_le_bytes8(self) -> "Bytes8": 782 """ 783 Converts this fixed sized unsigned integer into its little endian 784 representation, with exactly 8 bytes. 785 """ 786 return Bytes8(self.to_bytes(8, "little"))
Converts this fixed sized unsigned integer into its little endian representation, with exactly 8 bytes.
788 def to_le_bytes(self) -> "Bytes": 789 """ 790 Converts this fixed sized unsigned integer into its little endian 791 representation, in the fewest bytes possible. 792 """ 793 bit_length = self.bit_length() 794 byte_length = (bit_length + 7) // 8 795 return self.to_bytes(byte_length, "little")
Converts this fixed sized unsigned integer into its little endian representation, in the fewest bytes possible.
797 @classmethod 798 def from_be_bytes(cls: Type, buffer: "Bytes") -> "U64": 799 """ 800 Converts a sequence of bytes into an unsigned 64 bit integer from its 801 big endian representation. 802 """ 803 if len(buffer) > 8: 804 raise ValueError() 805 806 return cls(int.from_bytes(buffer, "big"))
Converts a sequence of bytes into an unsigned 64 bit integer from its big endian representation.
Inherited Members
- builtins.int
- conjugate
- bit_length
- to_bytes
- from_bytes
- as_integer_ratio
- real
- imag
- numerator
- denominator
815class FixedBytes(bytes): 816 """ 817 Superclass for fixed sized byte arrays. Not intended to be used directly, 818 but should be subclassed. 819 """ 820 821 LENGTH: int 822 """ 823 Number of bytes in each instance of this class. 824 """ 825 826 __slots__ = () 827 828 def __new__(cls: Type[B], *args: Any, **kwargs: Any) -> B: 829 """ 830 Create a new instance, ensuring the result has the correct length. 831 """ 832 result = super(FixedBytes, cls).__new__(cls, *args, **kwargs) 833 if len(result) != cls.LENGTH: 834 raise ValueError( 835 f"expected {cls.LENGTH} bytes but got {len(result)}" 836 ) 837 return result
Superclass for fixed sized byte arrays. Not intended to be used directly, but should be subclassed.
828 def __new__(cls: Type[B], *args: Any, **kwargs: Any) -> B: 829 """ 830 Create a new instance, ensuring the result has the correct length. 831 """ 832 result = super(FixedBytes, cls).__new__(cls, *args, **kwargs) 833 if len(result) != cls.LENGTH: 834 raise ValueError( 835 f"expected {cls.LENGTH} bytes but got {len(result)}" 836 ) 837 return result
Create a new instance, ensuring the result has the correct length.
Inherited Members
- builtins.bytes
- capitalize
- center
- count
- decode
- endswith
- expandtabs
- find
- fromhex
- hex
- index
- isalnum
- isalpha
- isascii
- isdigit
- islower
- isspace
- istitle
- isupper
- join
- ljust
- lower
- lstrip
- maketrans
- partition
- replace
- removeprefix
- removesuffix
- rfind
- rindex
- rjust
- rpartition
- rsplit
- rstrip
- split
- splitlines
- startswith
- strip
- swapcase
- title
- translate
- upper
- zfill
840class Bytes0(FixedBytes): 841 """ 842 Byte array of exactly zero elements. 843 """ 844 845 LENGTH = 0 846 """ 847 Number of bytes in each instance of this class. 848 """
Byte array of exactly zero elements.
828 def __new__(cls: Type[B], *args: Any, **kwargs: Any) -> B: 829 """ 830 Create a new instance, ensuring the result has the correct length. 831 """ 832 result = super(FixedBytes, cls).__new__(cls, *args, **kwargs) 833 if len(result) != cls.LENGTH: 834 raise ValueError( 835 f"expected {cls.LENGTH} bytes but got {len(result)}" 836 ) 837 return result
Create a new instance, ensuring the result has the correct length.
Inherited Members
- builtins.bytes
- capitalize
- center
- count
- decode
- endswith
- expandtabs
- find
- fromhex
- hex
- index
- isalnum
- isalpha
- isascii
- isdigit
- islower
- isspace
- istitle
- isupper
- join
- ljust
- lower
- lstrip
- maketrans
- partition
- replace
- removeprefix
- removesuffix
- rfind
- rindex
- rjust
- rpartition
- rsplit
- rstrip
- split
- splitlines
- startswith
- strip
- swapcase
- title
- translate
- upper
- zfill
851class Bytes4(FixedBytes): 852 """ 853 Byte array of exactly four elements. 854 """ 855 856 LENGTH = 4 857 """ 858 Number of bytes in each instance of this class. 859 """
Byte array of exactly four elements.
828 def __new__(cls: Type[B], *args: Any, **kwargs: Any) -> B: 829 """ 830 Create a new instance, ensuring the result has the correct length. 831 """ 832 result = super(FixedBytes, cls).__new__(cls, *args, **kwargs) 833 if len(result) != cls.LENGTH: 834 raise ValueError( 835 f"expected {cls.LENGTH} bytes but got {len(result)}" 836 ) 837 return result
Create a new instance, ensuring the result has the correct length.
Inherited Members
- builtins.bytes
- capitalize
- center
- count
- decode
- endswith
- expandtabs
- find
- fromhex
- hex
- index
- isalnum
- isalpha
- isascii
- isdigit
- islower
- isspace
- istitle
- isupper
- join
- ljust
- lower
- lstrip
- maketrans
- partition
- replace
- removeprefix
- removesuffix
- rfind
- rindex
- rjust
- rpartition
- rsplit
- rstrip
- split
- splitlines
- startswith
- strip
- swapcase
- title
- translate
- upper
- zfill
862class Bytes8(FixedBytes): 863 """ 864 Byte array of exactly eight elements. 865 """ 866 867 LENGTH = 8 868 """ 869 Number of bytes in each instance of this class. 870 """
Byte array of exactly eight elements.
828 def __new__(cls: Type[B], *args: Any, **kwargs: Any) -> B: 829 """ 830 Create a new instance, ensuring the result has the correct length. 831 """ 832 result = super(FixedBytes, cls).__new__(cls, *args, **kwargs) 833 if len(result) != cls.LENGTH: 834 raise ValueError( 835 f"expected {cls.LENGTH} bytes but got {len(result)}" 836 ) 837 return result
Create a new instance, ensuring the result has the correct length.
Inherited Members
- builtins.bytes
- capitalize
- center
- count
- decode
- endswith
- expandtabs
- find
- fromhex
- hex
- index
- isalnum
- isalpha
- isascii
- isdigit
- islower
- isspace
- istitle
- isupper
- join
- ljust
- lower
- lstrip
- maketrans
- partition
- replace
- removeprefix
- removesuffix
- rfind
- rindex
- rjust
- rpartition
- rsplit
- rstrip
- split
- splitlines
- startswith
- strip
- swapcase
- title
- translate
- upper
- zfill
873class Bytes20(FixedBytes): 874 """ 875 Byte array of exactly 20 elements. 876 """ 877 878 LENGTH = 20 879 """ 880 Number of bytes in each instance of this class. 881 """
Byte array of exactly 20 elements.
828 def __new__(cls: Type[B], *args: Any, **kwargs: Any) -> B: 829 """ 830 Create a new instance, ensuring the result has the correct length. 831 """ 832 result = super(FixedBytes, cls).__new__(cls, *args, **kwargs) 833 if len(result) != cls.LENGTH: 834 raise ValueError( 835 f"expected {cls.LENGTH} bytes but got {len(result)}" 836 ) 837 return result
Create a new instance, ensuring the result has the correct length.
Inherited Members
- builtins.bytes
- capitalize
- center
- count
- decode
- endswith
- expandtabs
- find
- fromhex
- hex
- index
- isalnum
- isalpha
- isascii
- isdigit
- islower
- isspace
- istitle
- isupper
- join
- ljust
- lower
- lstrip
- maketrans
- partition
- replace
- removeprefix
- removesuffix
- rfind
- rindex
- rjust
- rpartition
- rsplit
- rstrip
- split
- splitlines
- startswith
- strip
- swapcase
- title
- translate
- upper
- zfill
884class Bytes32(FixedBytes): 885 """ 886 Byte array of exactly 32 elements. 887 """ 888 889 LENGTH = 32 890 """ 891 Number of bytes in each instance of this class. 892 """
Byte array of exactly 32 elements.
828 def __new__(cls: Type[B], *args: Any, **kwargs: Any) -> B: 829 """ 830 Create a new instance, ensuring the result has the correct length. 831 """ 832 result = super(FixedBytes, cls).__new__(cls, *args, **kwargs) 833 if len(result) != cls.LENGTH: 834 raise ValueError( 835 f"expected {cls.LENGTH} bytes but got {len(result)}" 836 ) 837 return result
Create a new instance, ensuring the result has the correct length.
Inherited Members
- builtins.bytes
- capitalize
- center
- count
- decode
- endswith
- expandtabs
- find
- fromhex
- hex
- index
- isalnum
- isalpha
- isascii
- isdigit
- islower
- isspace
- istitle
- isupper
- join
- ljust
- lower
- lstrip
- maketrans
- partition
- replace
- removeprefix
- removesuffix
- rfind
- rindex
- rjust
- rpartition
- rsplit
- rstrip
- split
- splitlines
- startswith
- strip
- swapcase
- title
- translate
- upper
- zfill
895class Bytes64(FixedBytes): 896 """ 897 Byte array of exactly 64 elements. 898 """ 899 900 LENGTH = 64 901 """ 902 Number of bytes in each instance of this class. 903 """
Byte array of exactly 64 elements.
828 def __new__(cls: Type[B], *args: Any, **kwargs: Any) -> B: 829 """ 830 Create a new instance, ensuring the result has the correct length. 831 """ 832 result = super(FixedBytes, cls).__new__(cls, *args, **kwargs) 833 if len(result) != cls.LENGTH: 834 raise ValueError( 835 f"expected {cls.LENGTH} bytes but got {len(result)}" 836 ) 837 return result
Create a new instance, ensuring the result has the correct length.
Inherited Members
- builtins.bytes
- capitalize
- center
- count
- decode
- endswith
- expandtabs
- find
- fromhex
- hex
- index
- isalnum
- isalpha
- isascii
- isdigit
- islower
- isspace
- istitle
- isupper
- join
- ljust
- lower
- lstrip
- maketrans
- partition
- replace
- removeprefix
- removesuffix
- rfind
- rindex
- rjust
- rpartition
- rsplit
- rstrip
- split
- splitlines
- startswith
- strip
- swapcase
- title
- translate
- upper
- zfill
906class Bytes256(FixedBytes): 907 """ 908 Byte array of exactly 256 elements. 909 """ 910 911 LENGTH = 256 912 """ 913 Number of bytes in each instance of this class. 914 """
Byte array of exactly 256 elements.
828 def __new__(cls: Type[B], *args: Any, **kwargs: Any) -> B: 829 """ 830 Create a new instance, ensuring the result has the correct length. 831 """ 832 result = super(FixedBytes, cls).__new__(cls, *args, **kwargs) 833 if len(result) != cls.LENGTH: 834 raise ValueError( 835 f"expected {cls.LENGTH} bytes but got {len(result)}" 836 ) 837 return result
Create a new instance, ensuring the result has the correct length.
Inherited Members
- builtins.bytes
- capitalize
- center
- count
- decode
- endswith
- expandtabs
- find
- fromhex
- hex
- index
- isalnum
- isalpha
- isascii
- isdigit
- islower
- isspace
- istitle
- isupper
- join
- ljust
- lower
- lstrip
- maketrans
- partition
- replace
- removeprefix
- removesuffix
- rfind
- rindex
- rjust
- rpartition
- rsplit
- rstrip
- split
- splitlines
- startswith
- strip
- swapcase
- title
- translate
- upper
- zfill
Sequence of bytes (octets) of arbitrary length.
947def slotted_freezable(cls: Any) -> Any: 948 """ 949 Monkey patches a dataclass so it can be frozen by setting `_frozen` to 950 `True` and uses `__slots__` for efficiency. 951 952 Instances will be created frozen by default unless you pass `_frozen=False` 953 to `__init__`. 954 """ 955 cls.__slots__ = ("_frozen",) + tuple(cls.__annotations__) 956 cls.__init__ = _make_init_function(cls.__init__) 957 cls.__setattr__ = _setattr_function 958 cls.__delattr__ = _delattr_function 959 return type(cls)(cls.__name__, cls.__bases__, dict(cls.__dict__))
Monkey patches a dataclass so it can be frozen by setting _frozen
to
True
and uses __slots__
for efficiency.
Instances will be created frozen by default unless you pass _frozen=False
to __init__
.
965def modify(obj: S, f: Callable[[S], None]) -> S: 966 """ 967 Create a copy of `obj` (which must be [`@slotted_freezable`]), and modify 968 it by applying `f`. The returned copy will be frozen. 969 970 [`@slotted_freezable`]: ref:ethereum.base_types.slotted_freezable 971 """ 972 assert is_dataclass(obj) 973 assert isinstance(obj, SlottedFreezable) 974 new_obj = replace(obj, _frozen=False) 975 f(new_obj) 976 new_obj._frozen = True 977 return new_obj
Create a copy of obj
(which must be [@slotted_freezable
]), and modify
it by applying f
. The returned copy will be frozen.