Rätselhafter Fehler im Python 3 Interpreter

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Ich bearbeite gerade einen Tool und bin dabei dass das auch unter Python 3 läuft.
Python 2 läuft ohne Probleme durch. Im Python 3.4 wirft er mir einen merkwürdigen Fehler, weder passt die Fehlermeldung noch die Position(innerhalb eines Kommentars!). Ich führe die richtige Datei auch aus und hab auch sonst keine Probleme mit Einrückungen oder Kodierung, ich versteh's nicht wieso er trotzdem dort was findet.

Testdatei gibts hier.

Code: Alles auswählen

#!/usr/bin/env python
#encoding:utf8
#
#          FILE:  simg2img.py
# 
#         USAGE:  ./simg2img.py system.img 
# 
#   DESCRIPTION:  
# 
#        AUTHOR: Karl Zheng 
#       COMPANY: Meizu
#       CREATED: 2011年10月18日 15时25分15秒 CST
#      REVISION:  ---
#===============================================================================

from __future__ import print_function
import os
import sys
import struct

EXT4_FILE_HEADER_MAGIC = 0xED26FF3A
EXT4_CHUNK_HEADER_SIZE = 12

class ext4_file_header(object):
    def __init__(self, buf):
        (self.magic, 
            self.major, 
            self.minor, 
            self.file_header_size, 
            self.chunk_header_size, 
            self.block_size, 
            self.total_blocks, 
            self.total_chunks, 
            self.crc32) = struct.unpack('<I4H4I', buf)

class ext4_chunk_header(object):
    def __init__(self, buf):
        (self.type,
            self.reserved,
            self.chunk_size,
            self.total_size) = struct.unpack('<2H2I', buf)

def main():
    if len(sys.argv) == 2 and os.path.exists(sys.argv[1]):
        file_name = sys.argv[1] 
    else:
        print("required existing input file")
        sys.exit(1)
        
    with open(file_name, "rb") as ifd:

        print("file size: %d" % os.stat(file_name).st_size)

        file_header = ext4_file_header(ifd.read(28))

        if file_header.magic != EXT4_FILE_HEADER_MAGIC:
            print("Not a compressed ext4 file!!")
            sys.exit(3)

        print("file_header chunks:%X" % file_header.total_chunks)

        total_chunks = file_header.total_chunks
        print("total chunk = %d " % total_chunks)

        with open(file_name.replace(".img", ".raw.img"), "wb") as ofd:
            sector_base = 82528
            output_len = 0

            while total_chunks > 0:
                chunk_header = ext4_chunk_header(ifd.read(EXT4_CHUNK_HEADER_SIZE))
                sector_size = (chunk_header.chunk_size * file_header.block_size) >> 9
                #print("ct:%X, cs:%X, ts:%X, ss:%X"%(chunk_header.type, chunk_header.chunk_size, chunk_header.total_size, sector_size))

                if chunk_header.type == 0xCAC1:  # raw type 
                    data = ifd.read(chunk_header.total_size - EXT4_CHUNK_HEADER_SIZE)
                    if len(data) != (sector_size << 9):
                        print("len data:%d, sector_size:%d" % (len(data), sector_size << 9))
                        sys.exit(4)
                    else:
                        print("len data:%d, sector_size:%d" % (len(data), sector_size << 9))
                        ofd.write(data)
                        output_len += len(data)
                        print("raw_chunk ")
                        print("write raw data in %d size %d \n" % (sector_base, sector_size))
                        print("output len:%x" % output_len)

                        sector_base += sector_size
                else:
                    if chunk_header.type == 0xCAC2:  # TYPE_FILL
                        data = '\0' * (sector_size << 9)
                        ofd.write(data) 
                        output_len += len(data)
                        print("fill_chunk \n")
                        print("chunk_size:%x" % chunk_header.chunk_size)
                        print("output len:%x" % output_len)
                        sector_base += sector_size
                    else:
                        if chunk_header.type == 0xCAC3:  # TYPE_DONT_CARE
                            print("none chunk at chunk:%d" % (file_header.total_chunks - total_chunks))
                            print("data_size:0x%x, chunk_size:%d, block_size:%d" % (sector_size << 9, 
                                chunk_header.chunk_size, file_header.block_size))
                            #print(sector_size, type(sector_size), type("\0"))
                            #data = '\0' * (sector_size << 9)
                            ##ofd.write(data) 
                            for _ in range(sector_size << 9): ofd.write("\0")
                            output_len += len(data)
                            sector_base += sector_size
                        else:
                            data = '\0' * (sector_size << 9)
                            ofd.write(data)
                            print("unknown type!!")
                            output_len += len(data)
                            print("output len:%x" % output_len)
                            sector_base += sector_size

                total_chunks -= 1 
                print("remain chunks = %d "% total_chunks)

            print("write done")
        return 0
    
if __name__ == "__main__":
    main()
output len:60d1000
remain chunks = 22
none chunk at chunk:454
data_size:0x1f2f000, chunk_size:7983, block_size:4096
Traceback (most recent call last):
File "simg2img.py", line 122, in <module>
if __name__ == "__main__":
File "simg2img.py", line 104, in main
##ofd.write(data)
TypeError: 'str' does not support the buffer interface
Zuletzt geändert von darktrym am Dienstag 15. April 2014, 10:12, insgesamt 1-mal geändert.
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
BlackJack

@darktrym: Die Fehlermeldung würde aber schon zu der Zeile passen, wenn sie nicht auskommentiert wäre. Bist Du wirklich sicher, dass der richtige Code ausgeführt wird und nicht zum Beispiel eine alte *.pyc-Datei wo noch der auskommentierte Code als Bytecode drin steht?
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Deshalb auch die doppelte Raute, um das abzusichern, er gibt alle Änderungen so wie beschrieben aus. Es befindet sich auch keine pyc im Verzeichnis, gestartet wird's in der Eingabeaufforderung. Glaube nicht das es an meiner Installation liegt. Trotzdem, wenn einer zuviel Zeit hat, kann er es mal testen ob diese Meldung auch bei ihm ausgegeben wird.
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
BlackJack

@darktrym: Was soll denn die doppelte Raute absichern? Auskommentiert ist auskommentiert. Ist ja nicht so als wenn es mit einer Raute nur manchmal als Kommentar gesehen wird oder so.

Python 3 kann *.pyc-Dateien auch woanders ablegen, ein Verzeichnis war das glaube ich. `__pyc_cache__` oder so etwas. Musst Du mal in der Dokumentation schauen. Und wenn man Module direkt ausführt, werden sie nicht neu zu einer *.pyc-Datei kompiliert, nur wenn man sie importiert.
Benutzeravatar
darktrym
User
Beiträge: 784
Registriert: Freitag 24. April 2009, 09:26

Das ist ein Marker für mich den ich vor jeden Start setze.
„gcc finds bugs in Linux, NetBSD finds bugs in gcc.“[Michael Dexter, Systems 2008]
Bitbucket, Github
Antworten