0

I moved my python scripts from 2.7 to 3 using 2to3 module, and now I am trying them out...Can some explain what I need to change here?

found_qr = None
while not found_qr:
    keep_alive(1,5)
    time.sleep(4)
    process = None
    stdout_list = None
    process = subprocess.Popen('grep -E -o ".Source QR CODE :.{0,65}" ' + latest_file + ' | tail -1', shell=True, stdout=subprocess.PIPE,)
    stdout_list = process.communicate()
    stdout_list = stdout_list[0]
    if stdout_list.find("Source QR CODE") == -1:
        found_qr = None
    else:
        found_qr = 'found!'

I am getting this error:

if stdout_list.find("Source QR CODE") == -1:
TypeError: argument should be integer or bytes-like object, not 'str'

any idea? thanks!

Update: Here is a similar issue I am seeing:

keep_alive(1,1)
process = subprocess.Popen('grep -E -o ".Source QR CODE :.{0,65}" ' + latest_file + ' | tail -1', shell=True, stdout=subprocess.PIPE,)
stdout_list = process.communicate()
qr_code = stdout_list[0].replace('Source QR CODE : ','')
qr_code = qr_code.replace(' ','')
qr_code = qr_code.replace('\n', '')
qr_code = str(qr_code)

TypeError: a bytes-like object is required, not 'str'

1 Answer 1

1

In stdout_list = process.communicate() you get a list of bytes, so stdout_list[0] is a bytes object.

In stdout_list.find("Source QR CODE") you're trying to find a string in this bytes object, which won't work because bytes is different from str in Python 3.

Since this string is constant, you can convert it to a bytes object easily:

stdout_list.find(b"Source QR CODE")  # note the `b` before the string literal

Or encode this string appropriately:

stdout_list.find("Source QR CODE".encode('ascii'))  # here you can use whatever encoding you need

As the error message tells you, you can search for "bytes-like objects" and integers, because a bytes object is actually a list of integers from 0 to 255:

>>> b'thing'  # this is a bytes object
b'thing'
>>> list(_)
[116, 104, 105, 110, 103]  # actually a bunch of integers (bytes)
>>> b'thing'.find(116)  # find a single byte
0
Sign up to request clarification or add additional context in comments.

7 Comments

That seems to have worked...but can you help with this (similar issue): process = subprocess.Popen('grep -E -o ".Source QR CODE :.{0,65}" ' + latest_file + ' | tail -1', shell=True, stdout=subprocess.PIPE,) stdout_list = process.communicate() qr_code = stdout_list[0].replace('Source QR CODE : ','') qr_code = qr_code.replace(' ','') qr_code = qr_code.replace('\n', '') qr_code = str(qr_code)
@cjg123, you can run your code through 2to3 first. It should convert most of the code to Python 3 automatically
I did, but a lot of it was not changed...why would that be?
@cjg123, well, it's not perfect. For example, it doesn't seem to be able to infer that stdout_list is a bytes object. Anyway, for each error message of this kind, you should add a prefix b to each string literal in that line. For example: qr_code = stdout_list[0].replace('Source QR CODE : ','') -> qr_code = stdout_list[0].replace(b'Source QR CODE : ', b'')
@cjg123, actually, qr_code = str(qr_code) will result in "b'thing'", not just b'thing'. Why? Well, Python did what you asked it to do - it returned the string representation of that bytes object - the "b'thing'", while you expected just "thing", but that would be a different operation - decoding.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.