diff --git a/crates/ruff_python_ast/src/int.rs b/crates/ruff_python_ast/src/int.rs index 268981cdb5511..166ee5562f568 100644 --- a/crates/ruff_python_ast/src/int.rs +++ b/crates/ruff_python_ast/src/int.rs @@ -40,16 +40,23 @@ impl Int { Self(Number::Big(value.into())) } - /// Parse an [`Int`] from a string with a given radix. - pub fn from_str_radix(s: &str, radix: u32) -> Result { - match i64::from_str_radix(s, radix) { + /// Parse an [`Int`] from a string with a given radix, like `0x95D`. + /// + /// Takes, as input, the numerical portion (`95D`), the parsed base (`16`), and the entire + /// token (`0x95D`). + pub fn from_str_radix( + number: &str, + radix: u32, + token: &str, + ) -> Result { + match i64::from_str_radix(number, radix) { Ok(value) => Ok(Int::small(value)), Err(err) => { if matches!( err.kind(), std::num::IntErrorKind::PosOverflow | std::num::IntErrorKind::NegOverflow ) { - Ok(Int::big(s)) + Ok(Int::big(token)) } else { Err(err) } diff --git a/crates/ruff_python_parser/src/lexer.rs b/crates/ruff_python_parser/src/lexer.rs index 2b56e8f116334..a1267f716a98c 100644 --- a/crates/ruff_python_parser/src/lexer.rs +++ b/crates/ruff_python_parser/src/lexer.rs @@ -261,10 +261,14 @@ impl<'source> Lexer<'source> { 'x' | 'o' | 'b' )); + // Lex the portion of the token after the base prefix (e.g., `9D5` in `0x9D5`). let mut number = LexedText::new(self.offset(), self.source); self.radix_run(&mut number, radix); - let value = match Int::from_str_radix(number.as_str(), radix.as_u32()) { + // Extract the entire number, including the base prefix (e.g., `0x9D5`). + let token = &self.source[self.token_range()]; + + let value = match Int::from_str_radix(number.as_str(), radix.as_u32(), token) { Ok(int) => int, Err(err) => { return Err(LexicalError { @@ -1462,7 +1466,8 @@ def f(arg=%timeit a = b): #[test] fn test_numbers() { - let source = "0x2f 0o12 0b1101 0 123 123_45_67_890 0.2 1e+2 2.1e3 2j 2.2j 000"; + let source = + "0x2f 0o12 0b1101 0 123 123_45_67_890 0.2 1e+2 2.1e3 2j 2.2j 000 0x995DC9BBDF1939FA"; assert_debug_snapshot!(lex_source(source)); } diff --git a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__numbers.snap b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__numbers.snap index 55cc7dfdad80c..f9a7a988b1e7f 100644 --- a/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__numbers.snap +++ b/crates/ruff_python_parser/src/snapshots/ruff_python_parser__lexer__tests__numbers.snap @@ -77,8 +77,14 @@ expression: lex_source(source) }, 60..63, ), + ( + Int { + value: 0x995DC9BBDF1939FA, + }, + 64..82, + ), ( Newline, - 63..63, + 82..82, ), ]