Jan-03-2023, 08:24 PM
Hi, I am very new to Python so I apologise if this is an obvious fix!
I have a script that was written a long time ago (not by me) so it is in Python 2. I have been working through the errors that are being caused by the update to Python 3, but there is one I am stuck on. The following line seems to be causing the issue:
My question is how should it be used with the line in question? I have tried a few different ways and none of them seem to work. Here is the whole script if it helps (line 82 is the one causing the error):
I have a script that was written a long time ago (not by me) so it is in Python 2. I have been working through the errors that are being caused by the update to Python 3, but there is one I am stuck on. The following line seems to be causing the issue:
t = struct.unpack(fmt, str)I have done some research and I understand this would be fine in Python 2, but it will not work in Python 3; thus it generates the error:
Error:TypeError: a bytes-like object is required, not 'str'
I did a bit more research and found that bytes() should be used in Python 3.My question is how should it be used with the line in question? I have tried a few different ways and none of them seem to work. Here is the whole script if it helps (line 82 is the one causing the error):
#!/usr/bin/python -t # # vim:set ts=4 sw=4: "Pickup file (.PIC) editor" from pprint import pprint import struct name_table = { 0: 'Trojax' ,1: 'Pyrolite' ,2: 'Transpulse' ,3: 'SussGun' ,4: 'Laser' ,5: 'Mug' ,6: 'Mugs' ,7: 'Heatseaker' ,8: 'HeatseakerPickup' ,9: 'Thief' ,10: 'Scatter' ,11: 'Gravgon' ,12: 'Launcher' ,13: 'TitanStar' ,14: 'PurgePickup' ,15: 'PinePickup' ,16: 'QuantumPickup' ,17: 'SpiderPod' ,18: 'Parasite' ,19: 'Flare' ,20: 'GeneralAmmo' ,21: 'PyroliteAmmo' ,22: 'SussGunAmmo' ,23: 'PowerPod' ,24: 'Shield' ,25: 'Inv' ,26: 'ExtraLife' ,27: 'Computer' ,28: 'Smoke' ,29: 'Nitro' ,30: 'Goggles' ,31: 'Gold' ,32: 'Mantle' ,33: 'Crystal' ,34: 'Orb' ,35: 'GoldenPowerPod' ,36: 'DNA' ,37: 'SkeletonKey' ,38: 'Bomb' ,39: 'GoldFigure' ,40: 'Flag' ,41: 'Bounty' ,42: 'Flag1' ,43: 'Flag2' ,44: 'Flag3' ,45: 'Flag4' } class BinFile: "File which allows for easier reading from binary files." def __init__(self, source, mode='r'): if type(source) == str: self.source = open(source, mode, encoding='ANSI') elif hasattr(source, 'read'): self.source = source else: raise ValueError('Source must be filename or something that can read()') self.close = self.source.close self.read = self.source.read self.seek = self.source.seek self.tell = self.source.tell self.write = self.source.write def binread(self, fmt): "Read little-endian binary data specified by fmt." fmt = '<' + fmt size = struct.calcsize(fmt) str = self.read(size) if len(str) < size: raise EOFError('Unexpected end of file (%d bytes read instead of %d)' % (len(str), size)) t = struct.unpack(fmt, str) if len(t) == 1: return t[0] else: return t def read(self, n): return self.source.read(n) def seek(self, offset, whence=None): if whence is None: return self.source.seek(offset) else: return self.source.seek(offset, whence) def tell(self): return self.source.tell() def write(self, str): return self.source.write(str) class PickupList: def __init__(self, source): self.read_from(source) def pprint(self): print ('Version: %d') % self.version print ('Number of pickups: %d') % self.num_pickups print ('Pickups:') pprint(self.pickups) def read_from(self, source): if type(source) == str: source = BinFile(source, 'r') elif not hasattr(source, 'binread'): raise ValueError('Source must be filename or something that can binread()') magic = source.binread('4s') if magic != 'PRJX': raise InvalidPICFileError('Invalid magic number ' + magic) self.version, self.num_pickups = source.binread('Ih') self.version = int(self.version) self.pickups = [] for i in xrange(self.num_pickups): pickup = {} pickup['gen_type'], pickup['regen_type'], pickup['gen_delay'], \ pickup['life_span'] = source.binread('HHff') pickup['pos'] = {} pickup['pos']['x'], pickup['pos']['y'], pickup['pos']['z'] \ = source.binread('fff') pickup['group'], pickup['type'], pickup['trigger_mod'] \ = source.binread('HHH') self.pickups.append(pickup) source.close() def write_to(self, target): if type(target) == str: target = BinFile(target, 'w') elif not hasattr(target, 'write'): raise ValueError('Target must be a filename or something we can write() to') target.write('PRJX') target.write(struct.pack('Ih', self.version, self.num_pickups)) assert self.num_pickups == len(self.pickups) for pickup in self.pickups: target.write(struct.pack('HHff', pickup['gen_type'], \ pickup['regen_type'], pickup['gen_delay'], \ pickup['life_span'])) target.write(struct.pack('fff', pickup['pos']['x'], \ pickup['pos']['y'], pickup['pos']['z'])) target.write(struct.pack('HHH', pickup['group'], pickup['type'], \ pickup['trigger_mod'])) target.close() class InvalidPICFileError(Exception): def __init__(self, msg): self.msg = msg def __str__(self): return self.msg if __name__ == '__main__': import sys import yaml if len(sys.argv) < 2: print ('Convert PIC files to and from YAML') print ('Usage: %s <-pictoyaml|-yamltopic> [source] [> destination]') % sys.argv[0] sys.exit(0) elif len(sys.argv) < 3: source = BinFile(sys.stdin) else: source = BinFile(sys.argv[2]) if sys.argv[1] == '-pictoyaml': pl = PickupList(source) sys.stdout.write(yaml.dump(pl)) elif sys.argv[1] == '-yamltopic': pl = yaml.load(source) pl.write_to(sys.stdout) else: print ('first argument must be -pictoyaml or -yamltopic') sys.exit(1)Thanks!