Luxe
Luxe

Reputation: 69

python 3: can only concatenate str (not "bytes") to str

I'm updating my code from python 2 and I'm getting an error that worked in that version before. I'm so lost, please help.

I'm getting an error here at except function:

for c in text:
  try:
      if isEncrypt:
          i = tp_alphabet.index(c)
          ret += tc_alphabet[i]
       else:
          i = tc_alphabet.index(c)
          ret += tp_alphabet[i]
   except ValueError as e:
          wrchar = c.encode('utf-8')
          raise Exception("Can't find char '" + wrchar + "' of text in alphabet!")

when I run this:

dec = machine.decrypt(plaintext)
print(dec)

This is the error:

File "python3.py", line 133, in __encDec
    raise Exception("Can't find char '" + wrchar + "' of text in alphabet!")
TypeError: can only concatenate str (not "bytes") to str

Upvotes: 1

Views: 5201

Answers (1)

Karl Knechtel
Karl Knechtel

Reputation: 61644

I'm updating my code from python 2

In 2.x, and without using any __future__ declarations, the type str is the same as bytes, and Unicode text (also known as text) is stored in unicode objects.

Presumably, text (and therefore also c) was of type unicode in the 2.x version of the code, while ordinary string literals (such as "Can't find char '") are str (i.e., bytes) objects. So a conversion was needed: encoding the Unicode data into bytes, to be concatenated together - i.e., the line of code wrchar = c.encode('utf-8').

In 3.x, strings work properly. str is the text type, storing Unicode code points (not the same as characters, BTW), and is not an alias for bytes. There is no unicode any more, but if there were, it would be the same as str.

Therefore, it is now not only unnecessary, but a bug to do this encoding step. So what you need to do is remove that, and insert c into the output string directly.

While we're modernizing, let's assemble the string in a modern way.

except ValueError as e:
    raise Exception(f"Can't find char '{c}' of text in alphabet!")

Upvotes: 3

Related Questions