Py new by youknowone · Pull Request #6402 · RustPython/RustPython
🏁 Script executed:
# Find the PyBytesInner::try_from_borrowed_object implementation rg -A 20 "fn try_from_borrowed_object" crates/vm/src/builtins/bytes.rs
Repository: RustPython/RustPython
Length of output: 238
🏁 Script executed:
# Search for __bytes__ related tests or comments rg -B 3 -A 3 "__bytes__" crates/vm/src/builtins/bytes.rs
Repository: RustPython/RustPython
Length of output: 856
🏁 Script executed:
# Check if there are any tests for bytes constructor with __bytes__ fd -e rs -x rg -l "__bytes__" {} \; | head -20
Repository: RustPython/RustPython
Length of output: 222
🏁 Script executed:
# Look at the downcast usage pattern in this file rg "downcast" crates/vm/src/builtins/bytes.rs
Repository: RustPython/RustPython
Length of output: 794
🏁 Script executed:
# Find PyBytesInner definition and try_from_borrowed_object impl rg -B 5 -A 20 "impl.*PyBytesInner" crates/vm/src/builtins/bytes.rs | head -80
Repository: RustPython/RustPython
Length of output: 527
🏁 Script executed:
# Search for PyBytesInner enum/struct definition rg "^(pub )?struct PyBytesInner|^(pub )?enum PyBytesInner" crates/vm/src/builtins/bytes.rs
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Find where PyBytesInner::try_from_borrowed_object is actually implemented ast-grep --pattern 'impl PyBytesInner { $$$ fn try_from_borrowed_object($$$) { $$$ } $$$ }'
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Look for the actual implementation - search more broadly rg "fn try_from_borrowed_object" crates/vm/src/builtins/bytes.rs -B 2 -A 30 | head -100
Repository: RustPython/RustPython
Length of output: 288
🏁 Script executed:
# Look at the beginning/middle of bytes.rs for PyBytesInner impl head -300 crates/vm/src/builtins/bytes.rs | tail -200
Repository: RustPython/RustPython
Length of output: 5642
🏁 Script executed:
# Search for PyBytesInner impl with try_from_borrowed_object more carefully rg -B 3 "PyBytesInner::try_from_borrowed_object" crates/vm/src/builtins/bytes.rs
Repository: RustPython/RustPython
Length of output: 812
🏁 Script executed:
# Look at the entire impl block for PyBytesInner sed -n '/^impl PyBytesInner/,/^impl /p' crates/vm/src/builtins/bytes.rs | head -100
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Search across entire vm/src for PyBytesInner::try_from_borrowed_object implementation rg -B 2 -A 20 "impl.*PyBytesInner.*\{" crates/vm/src/builtins/bytes.rs | grep -A 25 "try_from_borrowed_object"
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# PyBytesInner might be defined as a type alias - search for its definition rg "type PyBytesInner|struct PyBytesInner|enum PyBytesInner" crates/vm/src/
Repository: RustPython/RustPython
Length of output: 119
🏁 Script executed:
# Search in function/buffer.rs since learnings mention it rg -B 2 -A 25 "try_from_borrowed_object" crates/vm/src/function/buffer.rs | head -80
Repository: RustPython/RustPython
Length of output: 2557
🏁 Script executed:
# Look at PyBytesInner implementation in bytes_inner.rs rg -B 2 -A 25 "fn try_from_borrowed_object" crates/vm/src/bytes_inner.rs
Repository: RustPython/RustPython
Length of output: 881
🏁 Script executed:
# Get context around PyBytesInner impl rg -B 5 -A 30 "impl PyBytesInner" crates/vm/src/bytes_inner.rs | head -100
Repository: RustPython/RustPython
Length of output: 1354
🏁 Script executed:
# Find bytes_from_object function rg -B 3 -A 40 "fn bytes_from_object" crates/vm/src/bytes_inner.rs
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Search entire codebase for bytes_from_object rg -B 3 -A 40 "fn bytes_from_object"
Repository: RustPython/RustPython
Length of output: 1345
🏁 Script executed:
# Check if it's imported in bytes_inner.rs rg "bytes_from_object" crates/vm/src/bytes_inner.rs
Repository: RustPython/RustPython
Length of output: 201
🌐 Web query:
CPython bytes constructor __bytes__ return type error message TypeError
💡 Result:
When you call bytes(x), CPython will call x.bytes() (if present) and that method must return a bytes object. If it returns some other type, CPython raises a TypeError such as:
- "TypeError: bytes returned non-bytes (type X)" (e.g. X == int or str). [1][2]
Fix: make bytes return a bytes object (e.g. return b"..." or return some_str.encode('utf-8')). [3]
Sources:
- object.bytes doc / pydoc requirement that bytes should return bytes. [1]
- Python tracker / example error message showing "bytes returned non-bytes (type ...)". [2]
- Explanation and example usage showing the TypeError and correct return type. [3]
🏁 Script executed:
# Search for tests of __bytes__ returning non-bytes rg -B 5 -A 10 "__bytes__.*non" crates/
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Look for __bytes__ error tests fd -e py -x rg -l "__bytes__" {} \; | xargs rg -l "TypeError" | head -5
Repository: RustPython/RustPython
Length of output: 731
🏁 Script executed:
# Check the test file for __bytes__ tests
cat extra_tests/snippets/builtin_bytes.pyRepository: RustPython/RustPython
Length of output: 20952
🏁 Script executed:
# Look at lines 120-137 more carefully with context sed -n '115,145p' crates/vm/src/builtins/bytes.rs
Repository: RustPython/RustPython
Length of output: 1364
🏁 Script executed:
# Check if there's specific __bytes__ error validation rg -B 5 -A 5 "returned non-bytes" crates/
Repository: RustPython/RustPython
Length of output: 47
The downcast usage on line 129 is correct; consider adding a specific error for __bytes__ returning non-bytes.
Line 129 correctly uses downcast::<PyBytes>() (which accepts subclasses) rather than downcast_exact. This matches CPython semantics: bytes() returns the __bytes__ result directly if it's any bytes instance, including subclasses.
However, when __bytes__ returns a non-bytes type, the current code delegates to PyBytesInner::try_from_borrowed_object, which raises a generic error: "can assign only bytes, buffers, or iterables of ints in range(0, 256)". CPython raises a more specific error: "TypeError: bytes returned non-bytes (type X)". Consider adding explicit validation to match CPython's error message.