types-bits 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
types_bits/__init__.py ADDED
@@ -0,0 +1,25 @@
1
+ """Rust-style sized integer types.
2
+
3
+ ``__init__.pyi`` shadows this module for type checkers; this is the runtime tier.
4
+ """
5
+
6
+ from types_bits._spec import MAX_BITS
7
+
8
+ __all__ = [ # pyright: ignore[reportUnsupportedDunderAll]
9
+ f"{prefix}{bits}" for prefix in ("u", "i") for bits in range(1, MAX_BITS + 1)
10
+ ]
11
+
12
+
13
+ def __getattr__(name: str) -> object:
14
+ if name not in __all__:
15
+ msg = f"module {__name__!r} has no attribute {name!r}"
16
+ raise AttributeError(msg)
17
+
18
+ from typing import Annotated
19
+
20
+ from annotated_types import Ge, Le
21
+
22
+ from types_bits._generate import Signed, Unsigned
23
+
24
+ width = Unsigned(int(name[1:])) if name[0] == "u" else Signed(int(name[1:]))
25
+ return Annotated[int, Ge(width.lo), Le(width.hi)]
@@ -0,0 +1,27 @@
1
+ # Generated by types_bits._generate — do not edit.
2
+ # variant=flat bits=10 kind=both
3
+
4
+ from typing import Literal
5
+
6
+ __all__ = ['u1', 'u2', 'u3', 'u4', 'u5', 'u6', 'u7', 'u8', 'u9', 'u10', 'i1', 'i2', 'i3', 'i4', 'i5', 'i6', 'i7', 'i8', 'i9', 'i10']
7
+
8
+ type u1 = Literal[0, 1]
9
+ type u2 = Literal[0, 1, 2, 3]
10
+ type u3 = Literal[0, 1, 2, 3, 4, 5, 6, 7]
11
+ type u4 = Literal[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
12
+ type u5 = Literal[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
13
+ type u6 = Literal[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63]
14
+ type u7 = Literal[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127]
15
+ type u8 = Literal[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255]
16
+ type u9 = Literal[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511]
17
+ type u10 = Literal[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023]
18
+ type i1 = Literal[-1, 0]
19
+ type i2 = Literal[-2, -1, 0, 1]
20
+ type i3 = Literal[-4, -3, -2, -1, 0, 1, 2, 3]
21
+ type i4 = Literal[-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7]
22
+ type i5 = Literal[-16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
23
+ type i6 = Literal[-32, -31, -30, -29, -28, -27, -26, -25, -24, -23, -22, -21, -20, -19, -18, -17, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
24
+ type i7 = Literal[-64, -63, -62, -61, -60, -59, -58, -57, -56, -55, -54, -53, -52, -51, -50, -49, -48, -47, -46, -45, -44, -43, -42, -41, -40, -39, -38, -37, -36, -35, -34, -33, -32, -31, -30, -29, -28, -27, -26, -25, -24, -23, -22, -21, -20, -19, -18, -17, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63]
25
+ type i8 = Literal[-128, -127, -126, -125, -124, -123, -122, -121, -120, -119, -118, -117, -116, -115, -114, -113, -112, -111, -110, -109, -108, -107, -106, -105, -104, -103, -102, -101, -100, -99, -98, -97, -96, -95, -94, -93, -92, -91, -90, -89, -88, -87, -86, -85, -84, -83, -82, -81, -80, -79, -78, -77, -76, -75, -74, -73, -72, -71, -70, -69, -68, -67, -66, -65, -64, -63, -62, -61, -60, -59, -58, -57, -56, -55, -54, -53, -52, -51, -50, -49, -48, -47, -46, -45, -44, -43, -42, -41, -40, -39, -38, -37, -36, -35, -34, -33, -32, -31, -30, -29, -28, -27, -26, -25, -24, -23, -22, -21, -20, -19, -18, -17, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127]
26
+ type i9 = Literal[-256, -255, -254, -253, -252, -251, -250, -249, -248, -247, -246, -245, -244, -243, -242, -241, -240, -239, -238, -237, -236, -235, -234, -233, -232, -231, -230, -229, -228, -227, -226, -225, -224, -223, -222, -221, -220, -219, -218, -217, -216, -215, -214, -213, -212, -211, -210, -209, -208, -207, -206, -205, -204, -203, -202, -201, -200, -199, -198, -197, -196, -195, -194, -193, -192, -191, -190, -189, -188, -187, -186, -185, -184, -183, -182, -181, -180, -179, -178, -177, -176, -175, -174, -173, -172, -171, -170, -169, -168, -167, -166, -165, -164, -163, -162, -161, -160, -159, -158, -157, -156, -155, -154, -153, -152, -151, -150, -149, -148, -147, -146, -145, -144, -143, -142, -141, -140, -139, -138, -137, -136, -135, -134, -133, -132, -131, -130, -129, -128, -127, -126, -125, -124, -123, -122, -121, -120, -119, -118, -117, -116, -115, -114, -113, -112, -111, -110, -109, -108, -107, -106, -105, -104, -103, -102, -101, -100, -99, -98, -97, -96, -95, -94, -93, -92, -91, -90, -89, -88, -87, -86, -85, -84, -83, -82, -81, -80, -79, -78, -77, -76, -75, -74, -73, -72, -71, -70, -69, -68, -67, -66, -65, -64, -63, -62, -61, -60, -59, -58, -57, -56, -55, -54, -53, -52, -51, -50, -49, -48, -47, -46, -45, -44, -43, -42, -41, -40, -39, -38, -37, -36, -35, -34, -33, -32, -31, -30, -29, -28, -27, -26, -25, -24, -23, -22, -21, -20, -19, -18, -17, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255]
27
+ type i10 = Literal[-512, -511, -510, -509, -508, -507, -506, -505, -504, -503, -502, -501, -500, -499, -498, -497, -496, -495, -494, -493, -492, -491, -490, -489, -488, -487, -486, -485, -484, -483, -482, -481, -480, -479, -478, -477, -476, -475, -474, -473, -472, -471, -470, -469, -468, -467, -466, -465, -464, -463, -462, -461, -460, -459, -458, -457, -456, -455, -454, -453, -452, -451, -450, -449, -448, -447, -446, -445, -444, -443, -442, -441, -440, -439, -438, -437, -436, -435, -434, -433, -432, -431, -430, -429, -428, -427, -426, -425, -424, -423, -422, -421, -420, -419, -418, -417, -416, -415, -414, -413, -412, -411, -410, -409, -408, -407, -406, -405, -404, -403, -402, -401, -400, -399, -398, -397, -396, -395, -394, -393, -392, -391, -390, -389, -388, -387, -386, -385, -384, -383, -382, -381, -380, -379, -378, -377, -376, -375, -374, -373, -372, -371, -370, -369, -368, -367, -366, -365, -364, -363, -362, -361, -360, -359, -358, -357, -356, -355, -354, -353, -352, -351, -350, -349, -348, -347, -346, -345, -344, -343, -342, -341, -340, -339, -338, -337, -336, -335, -334, -333, -332, -331, -330, -329, -328, -327, -326, -325, -324, -323, -322, -321, -320, -319, -318, -317, -316, -315, -314, -313, -312, -311, -310, -309, -308, -307, -306, -305, -304, -303, -302, -301, -300, -299, -298, -297, -296, -295, -294, -293, -292, -291, -290, -289, -288, -287, -286, -285, -284, -283, -282, -281, -280, -279, -278, -277, -276, -275, -274, -273, -272, -271, -270, -269, -268, -267, -266, -265, -264, -263, -262, -261, -260, -259, -258, -257, -256, -255, -254, -253, -252, -251, -250, -249, -248, -247, -246, -245, -244, -243, -242, -241, -240, -239, -238, -237, -236, -235, -234, -233, -232, -231, -230, -229, -228, -227, -226, -225, -224, -223, -222, -221, -220, -219, -218, -217, -216, -215, -214, -213, -212, -211, -210, -209, -208, -207, -206, -205, -204, -203, -202, -201, -200, -199, -198, -197, -196, -195, -194, -193, -192, -191, -190, -189, -188, -187, -186, -185, -184, -183, -182, -181, -180, -179, -178, -177, -176, -175, -174, -173, -172, -171, -170, -169, -168, -167, -166, -165, -164, -163, -162, -161, -160, -159, -158, -157, -156, -155, -154, -153, -152, -151, -150, -149, -148, -147, -146, -145, -144, -143, -142, -141, -140, -139, -138, -137, -136, -135, -134, -133, -132, -131, -130, -129, -128, -127, -126, -125, -124, -123, -122, -121, -120, -119, -118, -117, -116, -115, -114, -113, -112, -111, -110, -109, -108, -107, -106, -105, -104, -103, -102, -101, -100, -99, -98, -97, -96, -95, -94, -93, -92, -91, -90, -89, -88, -87, -86, -85, -84, -83, -82, -81, -80, -79, -78, -77, -76, -75, -74, -73, -72, -71, -70, -69, -68, -67, -66, -65, -64, -63, -62, -61, -60, -59, -58, -57, -56, -55, -54, -53, -52, -51, -50, -49, -48, -47, -46, -45, -44, -43, -42, -41, -40, -39, -38, -37, -36, -35, -34, -33, -32, -31, -30, -29, -28, -27, -26, -25, -24, -23, -22, -21, -20, -19, -18, -17, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511]
types_bits/__main__.py ADDED
@@ -0,0 +1,39 @@
1
+ """``python -m types_bits`` -- materialize a stub."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ from pathlib import Path
7
+ from typing import TYPE_CHECKING, cast
8
+
9
+ from types_bits._generate import KINDS, VARIANTS, write
10
+ from types_bits._spec import MAX_BITS
11
+
12
+ if TYPE_CHECKING:
13
+ from collections.abc import Sequence
14
+
15
+ from types_bits._generate import Kind, Variant
16
+
17
+ DEFAULT_OUT = Path(__file__).with_name("__init__.pyi")
18
+
19
+
20
+ def main(argv: Sequence[str] | None = None) -> int:
21
+ parser = argparse.ArgumentParser(prog="python -m types_bits", description=__doc__)
22
+ parser.add_argument("--bits", type=int, default=MAX_BITS)
23
+ parser.add_argument("--variant", choices=VARIANTS, default="flat")
24
+ parser.add_argument("--kind", choices=KINDS, default="both")
25
+ parser.add_argument("--out", type=Path, default=DEFAULT_OUT)
26
+ args = parser.parse_args(argv)
27
+
28
+ path = write(
29
+ cast("Path", args.out),
30
+ cast("int", args.bits),
31
+ cast("Variant", args.variant),
32
+ cast("Kind", args.kind),
33
+ )
34
+ print(f"wrote {path} ({path.stat().st_size:,} bytes)") # noqa: T201
35
+ return 0
36
+
37
+
38
+ if __name__ == "__main__":
39
+ raise SystemExit(main())
@@ -0,0 +1,216 @@
1
+ """Render exhaustive ``Literal`` stubs for Rust-style sized integer types.
2
+
3
+ Imported lazily by the runtime tier for the width algebra; never eagerly.
4
+ See ``python -m types_bits --help``.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import os
10
+ from typing import TYPE_CHECKING, Final, Literal, NamedTuple, assert_never
11
+
12
+ from types_bits._spec import MAX_BITS
13
+
14
+ if TYPE_CHECKING:
15
+ from collections.abc import Iterable
16
+ from pathlib import Path
17
+
18
+
19
+ class Unsigned(NamedTuple):
20
+ """A ``uN`` width.
21
+
22
+ >>> Unsigned(8).name, Unsigned(8).lo, Unsigned(8).hi
23
+ ('u8', 0, 255)
24
+ >>> Unsigned(4) == Signed(4)
25
+ False
26
+ """
27
+
28
+ bits: int
29
+ signed: Literal[False] = False
30
+
31
+ @property
32
+ def name(self) -> str:
33
+ return f"u{self.bits}"
34
+
35
+ @property
36
+ def lo(self) -> int:
37
+ return 0
38
+
39
+ @property
40
+ def hi(self) -> int:
41
+ return (1 << self.bits) - 1
42
+
43
+
44
+ class Signed(NamedTuple):
45
+ """An ``iN`` width, two's complement.
46
+
47
+ >>> Signed(8).name, Signed(8).lo, Signed(8).hi
48
+ ('i8', -128, 127)
49
+ >>> Signed(1).lo, Signed(1).hi
50
+ (-1, 0)
51
+ """
52
+
53
+ bits: int
54
+ signed: Literal[True] = True
55
+
56
+ @property
57
+ def name(self) -> str:
58
+ return f"i{self.bits}"
59
+
60
+ @property
61
+ def lo(self) -> int:
62
+ return -(1 << (self.bits - 1))
63
+
64
+ @property
65
+ def hi(self) -> int:
66
+ return (1 << (self.bits - 1)) - 1
67
+
68
+
69
+ type Width = Unsigned | Signed
70
+
71
+ type Variant = Literal["flat", "nested", "union", "annotated", "opaque"]
72
+ type Kind = Literal["both", "u", "i"]
73
+
74
+ VARIANTS: Final[tuple[Variant, ...]] = ("flat", "nested", "union", "annotated", "opaque")
75
+ KINDS: Final[tuple[Kind, ...]] = ("both", "u", "i")
76
+
77
+ BANNER: Final = "# Generated by types_bits._generate — do not edit."
78
+
79
+
80
+ def members(width: Width) -> range:
81
+ """Every value the width can hold.
82
+
83
+ >>> tuple(members(Signed(2)))
84
+ (-2, -1, 0, 1)
85
+ """
86
+ return range(width.lo, width.hi + 1)
87
+
88
+
89
+ def narrower(width: Width) -> Width | None:
90
+ """Step down one bit, keeping the signedness; ``None`` at the floor.
91
+
92
+ >>> narrower(Unsigned(3)), narrower(Unsigned(1))
93
+ (Unsigned(bits=2, signed=False), None)
94
+ """
95
+ if width.bits == 1:
96
+ return None
97
+ match width:
98
+ case Unsigned():
99
+ return Unsigned(width.bits - 1)
100
+ case Signed():
101
+ return Signed(width.bits - 1)
102
+ case _ as unreachable: # pyright: ignore[reportUnnecessaryComparison]
103
+ assert_never(unreachable)
104
+
105
+
106
+ def added(width: Width) -> tuple[int, ...]:
107
+ """Take the members a width contributes over the next-narrower one.
108
+
109
+ >>> added(Unsigned(3))
110
+ (4, 5, 6, 7)
111
+ >>> added(Signed(3))
112
+ (-4, -3, 2, 3)
113
+ """
114
+ prev = narrower(width)
115
+ if prev is None:
116
+ return tuple(members(width))
117
+ return tuple(value for value in members(width) if value not in members(prev))
118
+
119
+
120
+ def widths(bits: int, kind: Kind = "both") -> tuple[Width, ...]:
121
+ """Widen from one bit up to ``bits``, unsigned before signed.
122
+
123
+ >>> tuple(w.name for w in widths(2))
124
+ ('u1', 'u2', 'i1', 'i2')
125
+ """
126
+ unsigned = tuple(Unsigned(n) for n in range(1, bits + 1))
127
+ signed = tuple(Signed(n) for n in range(1, bits + 1))
128
+ match kind:
129
+ case "both":
130
+ return unsigned + signed
131
+ case "u":
132
+ return unsigned
133
+ case "i":
134
+ return signed
135
+
136
+
137
+ def _literal(values: Iterable[int]) -> str:
138
+ return f"Literal[{', '.join(map(str, values))}]"
139
+
140
+
141
+ def _rhs(width: Width, variant: Variant) -> str:
142
+ prev = narrower(width)
143
+ match variant:
144
+ case "flat":
145
+ return _literal(members(width))
146
+ case "nested":
147
+ if prev is None:
148
+ return _literal(members(width))
149
+ return f"Literal[{prev.name}, {', '.join(map(str, added(width)))}]"
150
+ case "union":
151
+ if prev is None:
152
+ return _literal(members(width))
153
+ return f"{prev.name} | {_literal(added(width))}"
154
+ case "annotated":
155
+ return f"Annotated[{_literal(members(width))}, Ge({width.lo}), Le({width.hi})]"
156
+ case "opaque":
157
+ return "int"
158
+
159
+
160
+ def alias(width: Width, variant: Variant) -> str:
161
+ """Render one PEP 695 alias statement.
162
+
163
+ >>> alias(Unsigned(2), "flat")
164
+ 'type u2 = Literal[0, 1, 2, 3]'
165
+ >>> alias(Signed(2), "union")
166
+ 'type i2 = i1 | Literal[-2, 1]'
167
+ >>> alias(Unsigned(1), "annotated")
168
+ 'type u1 = Annotated[Literal[0, 1], Ge(0), Le(1)]'
169
+ """
170
+ return f"type {width.name} = {_rhs(width, variant)}"
171
+
172
+
173
+ def _imports(variant: Variant) -> tuple[str, ...]:
174
+ match variant:
175
+ case "flat" | "nested" | "union":
176
+ return ("from typing import Literal",)
177
+ case "annotated":
178
+ return ("from typing import Annotated, Literal", "from annotated_types import Ge, Le")
179
+ case "opaque":
180
+ return ()
181
+
182
+
183
+ def _dunder_all(names: Iterable[str]) -> str:
184
+ return f"__all__ = [{', '.join(f'{name!r}' for name in names)}]"
185
+
186
+
187
+ def module(bits: int, variant: Variant = "flat", kind: Kind = "both") -> str:
188
+ """Render a whole stub module.
189
+
190
+ >>> print(module(1, kind="u"))
191
+ # Generated by types_bits._generate — do not edit.
192
+ # variant=flat bits=1 kind=u
193
+ <BLANKLINE>
194
+ from typing import Literal
195
+ <BLANKLINE>
196
+ __all__ = ['u1']
197
+ <BLANKLINE>
198
+ type u1 = Literal[0, 1]
199
+ <BLANKLINE>
200
+ """
201
+ selected = widths(bits, kind)
202
+ sections = (
203
+ (BANNER, f"# variant={variant} bits={bits} kind={kind}"),
204
+ _imports(variant),
205
+ (_dunder_all([width.name for width in selected]),),
206
+ tuple(alias(width, variant) for width in selected),
207
+ )
208
+ return "\n\n".join("\n".join(section) for section in sections if section) + "\n"
209
+
210
+
211
+ def write(path: Path, bits: int = MAX_BITS, variant: Variant = "flat", kind: Kind = "both") -> Path:
212
+ path.parent.mkdir(parents=True, exist_ok=True)
213
+ scratch = path.with_name(f"{path.name}.{os.getpid()}.tmp")
214
+ scratch.write_text(module(bits, variant, kind), encoding="utf-8")
215
+ scratch.replace(path)
216
+ return path
types_bits/_spec.py ADDED
@@ -0,0 +1,6 @@
1
+ """Shared by both tiers.
2
+
3
+ Annotation-free on purpose; ``tests/test_runtime.py`` pins why.
4
+ """
5
+
6
+ MAX_BITS = 10
types_bits/py.typed ADDED
File without changes
@@ -0,0 +1,222 @@
1
+ Metadata-Version: 2.4
2
+ Name: types-bits
3
+ Version: 0.1.0
4
+ Summary: Sized integer types: exhaustive Literal unions statically, Annotated bounds at runtime
5
+ Author-email: JP Hutchins <jphutchins@gmail.com>
6
+ License-Expression: MIT
7
+ License-File: LICENSE
8
+ Requires-Python: >=3.12
9
+ Provides-Extra: rt
10
+ Requires-Dist: annotated-types>=0.7; extra == 'rt'
11
+ Description-Content-Type: text/markdown
12
+
13
+ # types-bits
14
+
15
+ `u1`..`u10` and `i1`..`i10` as fully materialized `Literal` unions. Generated `.pyi`, zero
16
+ runtime cost, exhaustively checked.
17
+
18
+ ```python
19
+ from typing import TYPE_CHECKING
20
+
21
+ if TYPE_CHECKING:
22
+ from types_bits import u4
23
+
24
+ x: u4 = 15 # ok
25
+ y: u4 = 16 # error, on every checker
26
+ ```
27
+
28
+ `camas` runs the gate; `camas --list` enumerates it. CI fans the same tree out over a
29
+ runner axis, with both matrix axes emitted from `tasks.py`. `camas bench` and
30
+ `camas bench_shapes` regenerate everything below into `bench/results/`.
31
+
32
+ ## Runtime cost
33
+
34
+ Zero. The stub is a [PEP 484][pep484] `.pyi` behind `TYPE_CHECKING`. `import types_bits`
35
+ loads two modules and no stdlib (`tests/test_runtime.py`). Every number below is
36
+ type-checker wall clock, per check run.
37
+
38
+ ## Check cost by width
39
+
40
+ Seconds, cold, best of one, Python 3.14.1 / WSL2. Encoding `flat`
41
+ (`type uN = Literal[0, ..., 2**N-1]`), declaring `u1..uN` (so a probe at N bits holds 2^(N+1)-2 literals) and widening each
42
+ into the next.
43
+
44
+ | bits | mypy | pyright | basedpyright | ty | pyrefly | zuban |
45
+ |---:|---:|---:|---:|---:|---:|---:|
46
+ | 8 | 2.30 | 0.68 | 0.71 | 0.08 | 0.32 | 0.10 |
47
+ | 10 | 1.98 | 0.75 | 0.83 | 0.09 | 0.38 | 0.12 |
48
+ | 12 | 2.22 | 0.79 | 0.85 | 0.11 | 0.31 | 0.33 |
49
+ | 14 | 3.10 | 0.59 | 0.64 | 0.17 | 0.27 | 3.23 |
50
+ | 16 | 3.85 | 0.70 | 0.79 | 0.41 | 0.46 | 51.26 |
51
+
52
+ Shipped library (`u1..u10` + `i1..i10`): mypy 2.05, basedpyright 1.43,
53
+ pyright 1.13, pyrefly 0.24, zuban 0.08, ty 0.06 — matching the `type uN = int` control.
54
+
55
+ ```mermaid
56
+ xychart-beta
57
+ title "16 bits"
58
+ x-axis [zuban, mypy, basedpyright, pyright, pyrefly, ty]
59
+ y-axis "seconds" 0 --> 55
60
+ bar [51.26, 3.85, 0.79, 0.70, 0.46, 0.41]
61
+ ```
62
+
63
+ zuban, same sweep — roughly 16x per extra 2 bits past 12:
64
+
65
+ ```mermaid
66
+ xychart-beta
67
+ title "zuban vs width"
68
+ x-axis "bits" [8, 10, 12, 14, 16]
69
+ y-axis "seconds" 0 --> 55
70
+ line [0.10, 0.12, 0.33, 3.23, 51.26]
71
+ ```
72
+
73
+ The other five, 0–4s axis. Rising line is mypy; flat cluster is pyright, basedpyright,
74
+ pyrefly, ty:
75
+
76
+ ```mermaid
77
+ xychart-beta
78
+ title "mypy, pyright, basedpyright, pyrefly, ty"
79
+ x-axis "bits" [8, 10, 12, 14, 16]
80
+ y-axis "seconds" 0 --> 4
81
+ line [2.30, 1.98, 2.22, 3.10, 3.85]
82
+ line [0.68, 0.75, 0.79, 0.59, 0.70]
83
+ line [0.71, 0.83, 0.85, 0.64, 0.79]
84
+ line [0.32, 0.38, 0.31, 0.27, 0.46]
85
+ line [0.08, 0.09, 0.11, 0.17, 0.41]
86
+ ```
87
+
88
+ ## Fixed vs marginal cost
89
+
90
+ `u(N-1)` and `u(N)` declared in every row; only the use count varies. Italic rows are the
91
+ `type uN = int` control.
92
+
93
+ 10 bits — indistinguishable from `int`:
94
+
95
+ | uses | mypy | pyright | basedpyright | ty | pyrefly | zuban |
96
+ |---|---:|---:|---:|---:|---:|---:|
97
+ | declared, unused | 1.64 | 0.55 | 0.60 | 0.05 | 0.23 | 0.10 |
98
+ | *control* | *1.64* | *0.60* | *0.59* | *0.06* | *0.23* | *0.08* |
99
+ | 1 widening | 1.50 | 0.56 | 0.64 | 0.06 | 0.26 | 0.09 |
100
+ | 10 widenings | 1.75 | 0.65 | 0.90 | 0.08 | 0.29 | 0.20 |
101
+
102
+ 16 bits — 98,304 literals:
103
+
104
+ | uses | mypy | pyright | basedpyright | ty | pyrefly | zuban |
105
+ |---|---:|---:|---:|---:|---:|---:|
106
+ | declared, unused | 2.79 | 0.66 | 0.64 | 0.18 | 0.29 | 0.20 |
107
+ | *control* | *1.57* | *0.62* | *0.59* | *0.05* | *0.28* | *0.08* |
108
+ | 1 assignment | 2.77 | 0.62 | 0.65 | 0.19 | 0.33 | 0.21 |
109
+ | 1 widening | 2.81 | 0.64 | 0.65 | 0.22 | 0.37 | **35.66** |
110
+ | 10 widenings | 3.31 | 0.56 | 0.58 | 0.20 | 0.31 | **timeout (>180s)** |
111
+
112
+ - Declaration: fixed per check run, ~linear in literals (~12 µs/literal on mypy). Not per
113
+ importing file, not per use.
114
+ - Assignment: free. Enumerated membership is a hash lookup.
115
+ - Widening: free except zuban at width.
116
+
117
+ ## Widening
118
+
119
+ Cost tracks the *narrow* operand, not the wide one. Wide side fixed at `u16`, one widening:
120
+
121
+ | narrow | zuban | mypy | ty |
122
+ |---|---:|---:|---:|
123
+ | u1 | 0.18 | 2.54 | 0.20 |
124
+ | u4 | 0.18 | 2.46 | 0.15 |
125
+ | u8 | 0.16 | 2.67 | 0.21 |
126
+ | u12 | 0.76 | 2.50 | 0.17 |
127
+ | u15 | 35.21 | 2.80 | 0.18 |
128
+
129
+ Both operands must be large. At the 10-bit ceiling the worst case (`u9` → `u10`) is 0.09s.
130
+ Annotating a boundary at one width, so callers assign literals rather than widen between
131
+ adjacent wide aliases, avoids the shape entirely.
132
+
133
+ ## Encodings
134
+
135
+ | encoding | form | result |
136
+ |---|---|---|
137
+ | `flat` | `Literal[0, ..., 2**N-1]` | shipped; fastest, portable |
138
+ | `nested` | `Literal[u9, 512, ...]` | legal per [PEP 586][pep586]; pyrefly rejects past ~10 levels (`Invalid type inside literal, int`, 1 error at 10 bits → 7 at 16), ty at 16 |
139
+ | `union` | `u9 \| Literal[512, ...]` | ty 44.24s at 14 bits vs 0.17s flat |
140
+ | `annotated` | `Annotated[Literal[...], Ge, Le]` | tracks `flat` within noise to 14 bits |
141
+ | `opaque` | `int` | control |
142
+
143
+ ```mermaid
144
+ xychart-beta
145
+ title "ty at 14 bits by encoding"
146
+ x-axis [union, nested, annotated, flat]
147
+ y-axis "seconds" 0 --> 46
148
+ bar [44.24, 0.23, 0.22, 0.17]
149
+ ```
150
+
151
+ ## Runtime tier
152
+
153
+ [PEP 562][pep562] module `__getattr__` resolves the same names to
154
+ `Annotated[int, Ge(lo), Le(hi)]` ([PEP 593][pep593]), the shape
155
+ [`annotated-types`][at] consumers read. `tests/test_runtime.py` pins it against the static
156
+ bounds for all 20 widths. Needs the `rt` extra; `annotated_types` imports on first
157
+ attribute access.
158
+
159
+ ```python
160
+ from pydantic import TypeAdapter
161
+ from types_bits import u8 # Annotated[int, Ge(0), Le(255)] at runtime
162
+
163
+ TypeAdapter(u8).validate_python(256) # ValidationError
164
+ ```
165
+
166
+ ## Prior art
167
+
168
+ [`range-typed-integers`][rti] defines `u8 = NewType('u8', Annotated[int, ValueRange(0, 255)])`
169
+ for the byte widths `u8`..`u64` / `i8`..`i64`.
170
+
171
+ | | range-typed-integers | types-bits |
172
+ |---|---|---|
173
+ | carrier | `NewType` over `Annotated[int, ValueRange]` | `Literal` enumeration |
174
+ | bound enforced by | runtime `u8_checked()` / `check_int()`, raising `IntegerBoundError` | the type checker |
175
+ | `a: u8 = 12` | mypy error — `int` is not `u8`; requires `u8(12)` | ok |
176
+ | `a: u8 = 900` | mypy error, *identical* to the line above | error, and distinguished |
177
+ | `u8(900)` | accepted statically | n/a |
178
+ | widths | u8..u64 | u1..u10 |
179
+
180
+ Verified against every checker in the gate: mypy reports the same `Incompatible types in assignment
181
+ (expression has type "int", variable has type "u8")` on the in-range and out-of-range
182
+ lines alike. The range is metadata no checker reads ([PEP 746][pep746] would not change
183
+ this). `ValueRange` is O(1) per type, so it reaches u64; enumeration is O(2^N), so it
184
+ stops at u10.
185
+
186
+ ## PEPs
187
+
188
+ No PEP provides bounded integers.
189
+
190
+ | PEP | Status | Relevance |
191
+ |---|---|---|
192
+ | [586 – Literal Types][pep586] | Final | The mechanism. Calls `Literal` insufficient for numpy-style numeric code and defers integer generics. Permits the `nested` form pyrefly rejects. |
193
+ | [593 – `Annotated`][pep593] | Final | Metadata channel for the runtime tier. |
194
+ | [695 – Type Parameter Syntax][pep695] | Final | `type uN = ...` in the stub. |
195
+ | [561 – Packaging Type Information][pep561] | Final | `py.typed`; why the stub ships in the wheel. |
196
+ | [562 – Module `__getattr__`][pep562] | Final | One name, two tiers. |
197
+ | [649][pep649] / [749][pep749] – Deferred Annotations | Final (3.14) | Guarded import gets cheaper. |
198
+ | [746 – Type checking `Annotated` metadata][pep746] | Draft, targets 3.15 | Lets a checker verify metadata suits its type. Does not make any checker enforce `Ge`/`Le`. |
199
+
200
+ - [python/typing#554, "Support for Range Types?"][i554] — closed. Requested an Ada-style
201
+ `RangeType`.
202
+ - [discuss.python.org, "Use type hinting with bound constraints, e.g. `int[0:15]`"][thread]
203
+ — no resolution. Objections: most constraints are not statically validatable; ranges need
204
+ new type-system machinery; arithmetic is not closed. Landed on `Annotated` +
205
+ `annotated-types` with runtime validation.
206
+
207
+ `fixtures/reject.py` covers the arithmetic case: every checker rejects `u4 + u4` where a
208
+ `u4` is required. mypy widens the sum to `int`; ty and zuban widen it to `Literal[0, ..., 30]`.
209
+
210
+ [pep484]: https://peps.python.org/pep-0484/
211
+ [pep561]: https://peps.python.org/pep-0561/
212
+ [pep562]: https://peps.python.org/pep-0562/
213
+ [pep586]: https://peps.python.org/pep-0586/
214
+ [pep593]: https://peps.python.org/pep-0593/
215
+ [pep649]: https://peps.python.org/pep-0649/
216
+ [pep695]: https://peps.python.org/pep-0695/
217
+ [pep746]: https://peps.python.org/pep-0746/
218
+ [pep749]: https://peps.python.org/pep-0749/
219
+ [at]: https://github.com/annotated-types/annotated-types
220
+ [i554]: https://github.com/python/typing/issues/554
221
+ [thread]: https://discuss.python.org/t/use-type-hinting-with-bound-constraints-e-g-int-0-15/38820
222
+ [rti]: https://github.com/theCapypara/range-typed-integers
@@ -0,0 +1,10 @@
1
+ types_bits/__init__.py,sha256=KWjhWzFBU_AlRFYmGX4Ivpj2Vetkjcp3lHC5vB1hiGM,735
2
+ types_bits/__init__.pyi,sha256=fhsSIyAQ5WfQagJGnygKxLGMCeH8UrU58pJ3a6F4rk0,20513
3
+ types_bits/__main__.py,sha256=capR_YPj4T2SphzQxaEOOu_zGMMD8jjwHOPuJzs8A8s,1178
4
+ types_bits/_generate.py,sha256=toXd2w9rZjcXBoNkANdkdhzilCm9GJr36Iv9uP3jK9o,6006
5
+ types_bits/_spec.py,sha256=IxO5nKnXEjBCJM_EAmxR0FjyKKJDS-h8whR6oGFisAY,109
6
+ types_bits/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ types_bits-0.1.0.dist-info/METADATA,sha256=7GttperlGHPHYlWPmFntzAFfNDPleNdn_GkmEkWv1DA,8874
8
+ types_bits-0.1.0.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
9
+ types_bits-0.1.0.dist-info/licenses/LICENSE,sha256=WqlOTEeKt2qflqeLgs0Gl4FCfY0_mSc0BbwEbD8b8jM,1068
10
+ types_bits-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.31.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 JP Hutchins
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.