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]
Answers:
This might work current_string += str(c)
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.
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?
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]
This might work current_string += str(c)
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.
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?