Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
9e3d54a
[mypyc] feat: new primitive for `int.bit_length`
BobTheBuidler Aug 16, 2025
24a7ae7
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 16, 2025
7dbbb77
Update int_ops.py
BobTheBuidler Aug 16, 2025
b133de3
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 16, 2025
9d4116e
add headers
BobTheBuidler Aug 16, 2025
499bfb4
Merge branch 'bit-length' of https://github.com/BobTheBuidler/mypy in…
BobTheBuidler Aug 16, 2025
f718507
fixture
BobTheBuidler Aug 16, 2025
bb0a5eb
fix ir
BobTheBuidler Aug 16, 2025
ae266ad
implement c
BobTheBuidler Aug 16, 2025
e83203b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 16, 2025
1545a8d
more run tests
BobTheBuidler Aug 16, 2025
0854952
fix c
BobTheBuidler Aug 16, 2025
1e10c40
Merge branch 'bit-length' of https://github.com/BobTheBuidler/mypy in…
BobTheBuidler Aug 16, 2025
be93fe7
optimize fast path for short
BobTheBuidler Aug 16, 2025
d7b0a0c
fix macro
BobTheBuidler Aug 16, 2025
1eb2c7e
Update run-integers.test
BobTheBuidler Aug 19, 2025
71c30a0
msc
BobTheBuidler Aug 19, 2025
37c6109
Merge branch 'bit-length' of https://github.com/BobTheBuidler/mypy in…
BobTheBuidler Aug 19, 2025
243cc9a
Update int_ops.c
BobTheBuidler Aug 20, 2025
3f55d82
Merge branch 'master' into bit-length
BobTheBuidler Aug 23, 2025
06fd2b2
lets see if the test works if I use `Any` instead of `int`
BobTheBuidler Sep 8, 2025
f2db97a
Revert "lets see if the test works if I use `Any` instead of `int`"
BobTheBuidler Sep 8, 2025
ef46238
CPyTagged_AsObject
BobTheBuidler Sep 9, 2025
ef11a21
Update run-integers.test
BobTheBuidler Sep 9, 2025
76c2d0d
Update run-integers.test
BobTheBuidler Sep 9, 2025
8256fbb
Update run-integers.test
BobTheBuidler Sep 9, 2025
9e22723
Merge branch 'master' into bit-length
BobTheBuidler Sep 9, 2025
5b58d41
Merge branch 'master' into bit-length
BobTheBuidler Sep 13, 2025
fd26207
Merge branch 'master' into bit-length
BobTheBuidler Sep 18, 2025
24f1ca2
Merge branch 'master' into bit-length
BobTheBuidler Sep 30, 2025
b47e3e9
Merge branch 'master' into bit-length
BobTheBuidler Oct 2, 2025
a53d1e0
Merge branch 'master' into bit-length
BobTheBuidler Oct 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions mypyc/lib-rt/CPy.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ CPyTagged CPyTagged_Remainder_(CPyTagged left, CPyTagged right);
CPyTagged CPyTagged_BitwiseLongOp_(CPyTagged a, CPyTagged b, char op);
CPyTagged CPyTagged_Rshift_(CPyTagged left, CPyTagged right);
CPyTagged CPyTagged_Lshift_(CPyTagged left, CPyTagged right);
CPyTagged CPyTagged_BitLength(CPyTagged self);

PyObject *CPyTagged_Str(CPyTagged n);
CPyTagged CPyTagged_FromFloat(double f);
Expand Down
21 changes: 21 additions & 0 deletions mypyc/lib-rt/int_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -581,3 +581,24 @@ double CPyTagged_TrueDivide(CPyTagged x, CPyTagged y) {
}
return 1.0;
}

// int.bit_length()
CPyTagged CPyTagged_BitLength(CPyTagged self) {
PyObject *pyint = CPyTagged_StealAsObject(self);
if (!PyLong_Check(pyint)) {
Py_DECREF(pyint);
PyErr_SetString(PyExc_TypeError, "self must be int");
return CPY_INT_TAG;
}
PyObject *res = PyObject_CallMethod(pyint, "bit_length", NULL);
Py_DECREF(pyint);
if (!res) {
return CPY_INT_TAG;
}
long value = PyLong_AsLong(res);
Py_DECREF(res);
if (value == -1 && PyErr_Occurred()) {
return CPY_INT_TAG;
}
return value << 1;
}
18 changes: 17 additions & 1 deletion mypyc/primitives/int_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,14 @@
str_rprimitive,
void_rtype,
)
from mypyc.primitives.registry import binary_op, custom_op, function_op, load_address_op, unary_op
from mypyc.primitives.registry import (
binary_op,
custom_op,
function_op,
load_address_op,
method_op,
unary_op,
)

# Constructors for builtins.int and native int types have the same behavior. In
# interpreted mode, native int types are just aliases to 'int'.
Expand Down Expand Up @@ -305,3 +312,12 @@ def int_unary_op(name: str, c_function_name: str) -> PrimitiveDescription:
c_function_name="PyLong_Check",
error_kind=ERR_NEVER,
)

# int.bit_length()
method_op(
name="bit_length",
arg_types=[int_rprimitive],
return_type=int_rprimitive,
c_function_name="CPyTagged_BitLength",
error_kind=ERR_MAGIC,
)
1 change: 1 addition & 0 deletions mypyc/test-data/fixtures/ir.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ def __lt__(self, n: int) -> bool: pass
def __gt__(self, n: int) -> bool: pass
def __le__(self, n: int) -> bool: pass
def __ge__(self, n: int) -> bool: pass
def bit_length(self) -> int: pass

class str:
@overload
Expand Down
10 changes: 10 additions & 0 deletions mypyc/test-data/irbuild-int.test
Original file line number Diff line number Diff line change
Expand Up @@ -210,3 +210,13 @@ L0:
r0 = CPyTagged_Invert(n)
x = r0
return x

[case testIntBitLength]
def f(x: int) -> int:
return x.bit_length()
[out]
def f(x):
x, r0 :: int
L0:
r0 = CPyTagged_BitLength(x)
return r0
10 changes: 10 additions & 0 deletions mypyc/test-data/run-integers.test
Original file line number Diff line number Diff line change
Expand Up @@ -572,3 +572,13 @@ class subc(int):
[file userdefinedint.py]
class int:
pass

[case testBitLength]
def bit_length(n: int) -> int:
return n.bit_length()
def test_bit_length() -> None:
assert bit_length(0) == 0
assert bit_length(1) == 1
assert bit_length(255) == 8
assert bit_length(256) == 9
assert bit_length(-256) == 9
Loading