eagleflo / mpyq

Python library for reading MPQ archives.
BSD 2-Clause "Simplified" License
99 stars 23 forks source link

Issue with mpyq, StormReply, and Python 3 #32

Closed regner closed 8 years ago

regner commented 8 years ago

Hey,

So Blizzard recently released their heroprotocol and I have been doing some work on getting the whole thing into a tidy python package with some tests. One of the things that has come from this is the realization that everything works OK on Python 2.7 but falls over on Python 3.

You can see the results in Travis CI here.

TestHeroProtocolAllVersions.test_version[tests/replays/protocol32524.StormReplay] 
self = <tests.test_heroprotocol_all_versions.TestHeroProtocolAllVersions object at 0x2f65a10>
version = 'tests/replays/protocol32524.StormReplay'
    def test_version(self, version):
        search = '^(tests\/replays\/protocol)(\d*)(\.StormReplay)$'
        results = re.search(search, version)
        hp = HeroProtocol(version)
>       assert hp.version() == int(results.group(2))
tests/test_heroprotocol_all_versions.py:41: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
heroprotocol/heroprotocol.py:96: in version
    return self.decode_header()['m_version']['m_baseBuild']
heroprotocol/heroprotocol.py:91: in decode_header
    decoder = VersionedDecoder(contents, self.protocol.typeinfos)
heroprotocol/heroprotocol.py:72: in protocol
    header = decoder.instance(protocol29406.replay_header_typeid)
heroprotocol/decoders.py:173: in instance
    return getattr(self, typeinfo[0])(*typeinfo[1])
heroprotocol/decoders.py:252: in _struct
    self._expect_skip(5)
heroprotocol/decoders.py:185: in _expect_skip
    if self._buffer.read_bits(8) != expected:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
self = <heroprotocol.decoders.BitPackedBuffer object at 0x2f65690>, bits = 8
    def read_bits(self, bits):
        result = 0
        resultbits = 0
        while resultbits != bits:
            if self._nextbits == 0:
                if self.done():
                    raise TruncatedError(self)
>               self._next = ord(self._data[self._used])
E               TypeError: ord() expected string of length 1, but int found
heroprotocol/decoders.py:62: TypeError

Was wondering if anyone here had a suggestion for tracking this down and possibly a suggestion for how to fix. Thanks in advance for your help! :)

eagleflo commented 8 years ago

Both https://github.com/Blizzard/s2protocol and https://github.com/Blizzard/heroprotocol explicitly require Python 2 and won't currently work with Python 3.

Blizzard has bundled mpyq version 0.2.0 (from 2011) in both projects. Sadly that version of mpyq didn't have support for Python 3 yet; we added support for Python 3 in version 0.2.2 (from 2013). Updating the bundled mpyq would be the first step towards Python 3 compatibility in both projects, but there are other 2to3 fixes they'd need to do in addition to that.

eagleflo commented 8 years ago

As far as I'm aware the most recent version of mpyq works well with Python 3. If this is not the case please elaborate.

eagleflo commented 8 years ago

(Just a further follow up: the traceback you pasted is from https://github.com/Blizzard/heroprotocol/blob/master/decoders.py#L69, not mpyq.)

regner commented 8 years ago

@eagleflo I forked the Blizzard repo, stripped out mpyq, made the whole thing an actual package, and then listed the newer version of mpyq as a requirement. So for the most part that is already done.

I amreally sorry about this though. I completely misread the damn stacktrace and thought it was failing in mpyq. Not sure how the hell I possibly got into that mindset. Sorry!