-
-
Notifications
You must be signed in to change notification settings - Fork 34.5k
gh-143050: correct PyLong_FromString() to use _PyLong_Negate() #145901
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 7 commits
fbcec5a
b8333ba
20e79c6
413e56d
b892216
78c5b4b
69d35bd
2f927e0
53523de
1f363f4
41961ed
0b29e28
45b3b04
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -231,6 +231,16 @@ _PyLong_IsPositive(const PyLongObject *op) | |
| return (op->long_value.lv_tag & SIGN_MASK) == 0; | ||
| } | ||
|
|
||
| static inline bool | ||
| _PyLong_HasImmortalTag(const PyLongObject *op) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IMO the intent here is to check if an integer is a small integer, rather than checking for a tag. So I would prefer to rename the function to I wanted to suggest referring to
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are two notions for "small int"'s. One - by value and other is - this. If @colesbury is ok - I'm fine with renaming..
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
For example, you can add the following check for (You need to update your branch to retrieve my For me, testing
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've added an assert. BTW, what do you think on #145901 (comment)? I don't think we should mention _PY_IS_SMALL_INT in the description of the function, assert is readable enough.
For now, we use _PY_IS_SMALL_INT() to check this. But eventually this could be just testing a flag.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would prefer to rename the function to
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've added suggestions.
vstinner marked this conversation as resolved.
Outdated
|
||
| { | ||
| assert(PyLong_Check(op)); | ||
| bool is_small_int = (op->long_value.lv_tag & IMMORTALITY_BIT_MASK) != 0; | ||
| assert(PyLong_CheckExact(op) || (!is_small_int)); | ||
| assert((is_small_int && _Py_IsImmortal(op)) || (!is_small_int)); | ||
|
colesbury marked this conversation as resolved.
Outdated
|
||
| return is_small_int; | ||
| } | ||
|
|
||
| static inline Py_ssize_t | ||
| _PyLong_DigitCount(const PyLongObject *op) | ||
| { | ||
|
|
@@ -292,7 +302,9 @@ _PyLong_SetDigitCount(PyLongObject *op, Py_ssize_t size) | |
| #define NON_SIZE_MASK ~(uintptr_t)((1 << NON_SIZE_BITS) - 1) | ||
|
|
||
| static inline void | ||
| _PyLong_FlipSign(PyLongObject *op) { | ||
| _PyLong_FlipSign(PyLongObject *op) | ||
| { | ||
| assert(!_PyLong_HasImmortalTag(op)); | ||
|
vstinner marked this conversation as resolved.
Outdated
|
||
| unsigned int flipped_sign = 2 - (op->long_value.lv_tag & SIGN_MASK); | ||
| op->long_value.lv_tag &= NON_SIZE_MASK; | ||
| op->long_value.lv_tag |= flipped_sign; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -803,6 +803,13 @@ def to_digits(num): | |
| self.assertEqual(pylongwriter_create(negative, digits), num, | ||
| (negative, digits)) | ||
|
|
||
| def test_bug_143050(self): | ||
| with support.adjust_int_max_str_digits(0): | ||
| int('-' + '0' * 7000, 10) | ||
|
skirpichev marked this conversation as resolved.
|
||
| _testcapi.test_immortal_small_ints() | ||
| int('-' + '0' * 7000 + '123', 10) | ||
|
skirpichev marked this conversation as resolved.
|
||
| _testcapi.test_immortal_small_ints() | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's okay as long as it catches the regression in a debug build.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. _testcapi is always built with assertions, even in release mode.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I built Python in release mode without |
||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| unittest.main() | ||
Uh oh!
There was an error while loading. Please reload this page.