Skip to content

Slicing a bytes object returning <int> with single index #132062

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

Closed
maxpat78 opened this issue Apr 4, 2025 · 6 comments
Closed

Slicing a bytes object returning <int> with single index #132062

maxpat78 opened this issue Apr 4, 2025 · 6 comments
Labels
invalid type-bug An unexpected behavior, bug, or error

Comments

@maxpat78
Copy link

maxpat78 commented Apr 4, 2025

Bug report

Bug description:

Consider the first 'if' in the following piece of code.
It used to run nice in Python 2.x (where it was developed):

	if n_offset == 1: # ...BYTE
		offset = struct.unpack_from("<b", offset[0])[0] # offset[0]
	elif n_offset == 2: # ...WORD
		offset = struct.unpack_from("<h", offset[:2])[0]
	elif n_offset in (3,4):  # ...DWORD
		offset = struct.unpack_from("<i", offset[:4])[0]
	else: # ...QWORD
		offset = struct.unpack_from("<q", offset)[0]

Actually, it raises the exception TypeError: a bytes-like object is required, not 'int' and needs an awkward reconversion:

offset = struct.unpack_from("<b", offset[0].to_bytes())[0] # offset[0] -> int ! Must convert back!

Isn't it a contradiction (and a bug) that slicing returns bytes except in the case of a single slicing index???

CPython versions tested on:

3.13

Operating systems tested on:

Windows

@maxpat78 maxpat78 added the type-bug An unexpected behavior, bug, or error label Apr 4, 2025
@TeamSpen210
Copy link

TeamSpen210 commented Apr 4, 2025

It’s not actually, strings are the weird ones. Consider a list - mylist[4] gives the 5th element, but mylist[4:5] gives a 1-element list. Bytes objects are conceptually a sequence of 0-255 integers. If you do want 1 element, do a slice like offset[0:1].

@skirpichev
Copy link
Member

Isn't it a contradiction (and a bug) that slicing returns bytes except in the case of a single slicing index???

Are you about this:

offset = struct.unpack_from("<b", offset[0])[0] # offset[0]

?

It's not slicing, but subscription.

@skirpichev skirpichev added the pending The issue will be closed if no feedback is provided label Apr 4, 2025
@maxpat78
Copy link
Author

maxpat78 commented Apr 4, 2025

Call it how you like, indexing, subscription or slicing-of-one-item: but one expects that what you extract is what there is inside an object - bytes -> byte

@skirpichev
Copy link
Member

but one expects that what you extract is what there is inside an object - bytes -> byte

Python works here as expected, similar you can see just with ordinary lists:

>>> xs = [1, 2, 3]
>>> type(xs[0])
<class 'int'>
>>> type(xs[0:1])
<class 'list'>

Problem is definitely with your expectations.

@skirpichev skirpichev closed this as not planned Won't fix, can't repro, duplicate, stale Apr 4, 2025
@skirpichev skirpichev added invalid and removed pending The issue will be closed if no feedback is provided labels Apr 4, 2025
@sergey-miryanov
Copy link
Contributor

It is documented behavior since 3.3:

Since bytes objects are sequences of integers, for a bytes object b, b[0] will be an integer, while b[0:1] will be a bytes object of length 1. (This contrasts with text strings, where both indexing and slicing will produce a string of length 1)

@skirpichev
Copy link
Member

In fact, that was documented since beginning in py3, see 98297ee.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
invalid type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

5 participants
@sergey-miryanov @skirpichev @maxpat78 @TeamSpen210 and others