Type conversion in Python 2.7 vs 3.5, how to make my 2.7 code work under 3.5?

Question:

I’m porting 2.7 code into 3.5 and the 2.7 code works just fine. After running 2to3 and changing the obvious in the old code, I still get the following error message:

Exception in thread Thread-7:
Traceback (most recent call last):
  File "C:UsersAnaconda3libthreading.py", line 914, in _bootstrap_inner
    self.run()
  File "C:UsersAnaconda3libthreading.py", line 862, in run
    self._target(*self._args, **self._kwargs)
  File "<ipython-input-2-eadc3d59ae9f>", line 70, in receiveData
    nftp = self.parseNFTPData(stringBuffer(data[:-1]))
  File "<ipython-input-2-eadc3d59ae9f>", line 101, in parseNFTPData
    current_string += c
TypeError: Can't convert 'int' object to str implicitly

I do understand the error, but why is this error raised in under Python 3 and not 2?

Code as follows:

def parseNFTPData(self, strbuf):
      quote = False
      result = []
      current_string = ""
   
      while not strbuf.eof(): 
         c = strbuf.read()
         if c == """:
            if quote: 
               quote = False
            else:
               quote = True
         elif c == "(" and not quote:
            list = self.parseNFTPData(strbuf)
            result.append(list)
         elif c == ")" and not quote: 
            result.append(self.typeConvert(current_string))
            strbuf.read()
            return result
         elif len(current_string) > 0 and c == " " and not quote:
            result.append(self.typeConvert(current_string))
            current_string = ""
         else: 
            current_string += c
   
      if len(current_string) > 0: 
         result.append(self.typeConvert(current_string))
      return result

strbuf is of class stringBuffer:

class stringBuffer:
   def __init__(self, string):
      self.buffer  = string
      self.readptr = 0
   
   def read(self): 
      if self.readptr < len(self.buffer): 
         readc = self.buffer[self.readptr]
         self.readptr += 1
      else:
         readc = False
      return readc

   def eof(self): 
      if self.readptr >= len(self.buffer): 
         return True
      else:
         return False 

   def peek(self): 
      return self.buffer[self.readptr]
Asked By: cJc

||

Answers:

This might work current_string += str(c)

Answered By: amarnath

current_string += c wouldn’t work in both Python 2.7 & 3.5, if type(current_string) == str and type(c) == int. Python has never allowed the concatenation between strings and integers directly. You might need to check your original code in Python 2.7 to find the exact issues, or you can post your original code here if you like.

FYI, current_string += str(c) would solve the bugs you are currently facing.

Answered By: Jason

The most likely cause is that strbuf is behaving differently. In 2.7, strbuf.read() probably returned a character, while in 3.5 it’s returning an int.

I suspect that this is related to the Unicode changes that were made. Is strbuf something like a byte string in 3.5?

Answered By: Simon Callan
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.