5

I am working on converting an existing program from Python2 to Python3. One of the methods in the program authenticates the user with a remote server. It will prompt the user to enter in a password.

def _handshake(self):
    timestamp = int(time.time())
    token = (md5hash(md5hash((self.password).encode('utf-8')).hexdigest()
                + str(bytes('timestamp').encode('utf-8'))))
    auth_url = "%s/?hs=true&p=1.2&u=%s&t=%d&a=%s&c=%s" % (self.name,
                                                          self.username,
                                                          timestamp,
                                                          token,
                                                          self.client_code)
    response = urlopen(auth_url).read()
    lines = response.split("\n")
    if lines[0] != "OK":
        raise ScrobbleException("Server returned: %s" % (response,))
    self.session_id = lines[1]
    self.submit_url = lines[3]

The problem with this method is that after the integer is converted to a string, it needs to be encoded. But as far as I can tell, it is already encoded? I found this question but I was having a hard time applying that to the context of this program.

This is the line giving me problems.

  • + str(bytes('timestamp').encode('utf-8'))))
    • TypeError: string argument without an encoding

I have tried playing around with alternate ways of doing this, all with varying types of errors.

  • + str(bytes('timestamp', 'utf-8'))))
    • TypeError: Unicode-objects must be encoded before hashing
  • + str('timestamp', 'utf-8')))
    • TypeError: decoding str is not supported

I'm still getting started learning Python (but I have beginner to intermediate knowledge of Java), so I am not completely familiar with the language yet. Does anyone have any thoughts on what this issue might be?

Thanks!

5
  • I notice the code in the link has changed that line to + str(timestamp)).hexdigest()) is that possibly what needs to be done? Commented Jun 2, 2016 at 20:56
  • str(bytes('timestamp').encode('utf-8')) - what the heck? What were you trying to do there? Commented Jun 2, 2016 at 20:56
  • @TadhgMcDonald-Jensen Originally, it was, but when I was trying to run the script (e.g. + str(b'timestamp').hexdigest()))), I received a AttributeError: 'str' object has no attribute 'hexdigest' in return. It might be, but I'm not quite sure on this one. Commented Jun 2, 2016 at 23:32
  • @user2357112 I've been trying all kinds of combinations to get this line right, it's gone through many forms today... ultimately, I'm trying to just get this integer to convert to a format that Py3 will take as valid. Commented Jun 2, 2016 at 23:33
  • do you understand that timestamp is a name, 'timestamp' is a string literal (no relation to the timestamp name)? You don't need bytes here. To convert an integer to a string in Python: str(timestamp). Use urllib.parse.urlencode() to create the query. Pass it str objects (Unicode in Python). You might need to call .decode('ascii', 'strict') on a .hexdigest() result, to get str instead of bytes. Commented Jun 3, 2016 at 0:19

1 Answer 1

12

This error is due to how you create bytes in python 3.

You will not do bytes("bla bla") but just b"blabla" or you need to specify an encoding type like bytes("bla bla","utf-8") because it needs to know what was the original encoding before turning it into an array of numbers.

Then the error

TypeError: string argument without an encoding

Should disappear.

You have either bytes or str. If you have a bytes value and you want to turn it in str you should do:

my_bytes_value.decode("utf-8")

And it will return you a str.

I hoped it help ! Have a nice day !

Sign up to request clarification or add additional context in comments.

3 Comments

Hi, thanks for the response! So, I first tried rewriting it just as b'timestamp', but this gave me TypeError: Can't convert 'bytes' object to str implicitly. Instead, I tried doing str(b'timestamp'), but this outputs TypeError: Unicode-objects must be encoded before hashing. Your explanation makes sense, but I'm just having a hard time figuring out to return the value as a string. I tried using a decode("utf-8") but to no avail. Any thoughts or ideas?
do bytes('timestamp','utf-8')
Now I'm getting TypeError: urlopen() got an unexpected keyword argument 'encoding'

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.