Domanda

I've converted a older Python script with the Python 2to3 tool to make it compatible with Blender. The script makes communication possible between Blender3D and a OMRON PLC. However after conversion the script gives the following error in the Blender 3D console:

TypeError: 'str' does not support the buffer interface

This occurs in the following lines:

def _send(self,  raw):
    self.sock.send( raw)
    #print ' Send:' + repr(raw)
def _recieve(self):
    pr = self.sock.recv(8)
    length = binstr2int( pr[4:8])
    r = pr + self.sock.recv( length)
    #print ' Recv:' + repr(r)
    return r

I've searched the problem using google and it seems its a problem that occurs when you convert or use an older script for Python 3+. Adding .encode() and .decode() to the objects where the problems occur has not helped either.

def _send(self,  raw):
    self.sock.send( raw.encode())
    #print ' Send:' + repr(raw)
def _recieve(self):
    pr = self.sock.recv(8).decode()
    length = binstr2int( pr[4:8])
    r = pr + self.sock.recv( length)
    #print ' Recv:' + repr(r)
    return r

This gives a different kind of error:

TypeError: can't convert 'bytes' to str implicitly

The script was not made by me, I'm simply using it for a school project to make communication possible between software (Blender3D) and hardware (PLC).

Help would be much appreciated, thanks.

I've put the converted version of the script here.

È stato utile?

Soluzione

  1. Bytes-only operations like self._send(c1.raw) needs to be encoded correctly. Use either self._send(bytes(c1.raw, "utf-8")) or self._send(c1.raw.encode("utf-8"))

    However, since your classes like FinsTCPframe is actually operating bytes stream instead of unicode literals, I'd suggest to just stick to bytes (append b in front of any affected string constants, like b'' instead of ''

  2. ord() around an item of a bytes instance (for example, if s is a bytes instance, s[i] is the item) should be removed, since retrieving one element from bytes in Python 3.x is already a int instance. If you are not 100% sure what's inside your ord() call, try this (dirty) workaround:

    safe_ord = lambda c: ord(c) if isinstance(c, str) else c

    And replace corresponding ord() with safe_ord()

  3. chr() in python 3 returns a str, but if you need bytes instead, try this:

    bytes_chr = lambda x: bytes([x]) (from this stackoverflow question)

    And replace corresponding chr() with bytes_chr()

  4. Division / is resulting in a float by default, so if you want to retain the old behavior, double the symbol: //

A full list of porting guide can be found on the official python docs site, consult this if you need to do the porting work in the future :)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top