Ошибка атрибута: объект ‘float’ не имеет атрибута ‘co_names’

#python-3.x #unmarshalling #inspect

Вопрос:

простой скрипт проверки файла pyc есть проблема с функцией co_name, скрипт работает хорошо, пока модуль маршала не загрузится, а затем не упадет.

 magic: 160d0d0a
mod_time: 1493965574
source_size: 231

code:
Traceback (most recent call last):
  File "/home/ubuntu/Downloads/book-resources-master/chapter4/code-exec-eg/python/inspect.py", line 24, in <module>
    inspect_code(code)
  File "/home/ubuntu/Downloads/book-resources-master/chapter4/code-exec-eg/python/inspect.py", line 8, in inspect_code
    print('{}{}(line:{})'.format(indent, code.co_names, code.co_firstlineno))
AttributeError: 'float' object has no attribute 'co_names'
 

если кто-нибудь может помочь !
Спасибо

 import marshal
import types

def to_long(s):
    return s[0]   (s[1] << 8)   (s[2] << 16)   (s[3] << 24)

def inspect_code(code, indent='    '):
    print('{}{}(line:{})'.format(indent, code.co_names, code.co_firstlineno))
    for c in code.co_consts:
        if isinstance(c, types.CodeType):
            inspect_code(c, indent   '    ')

f = open('__pycache__/add.cpython-39.pyc', 'rb')

magic = f.read(4)
print('magic: {}'.format(magic.hex()))
mod_time = to_long(f.read(4))
print('mod_time: {}'.format(mod_time))
source_size = to_long(f.read(4))
print('source_size: {}'.format(source_size))

print('ncode:')
code = marshal.load(f)
inspect_code(code)

f.close()

import dis
dis.disassemble(code)
 

Ответ №1:

Я не знаком ни с marshal модулем, ни pyc с содержимым, но когда я попробовал ваш код с Python 3.9, я получил ошибку при чтении значения кода. И формат файла кажется другим для моего примера pyc, построенного на Python 3.9.

 magic: 610d0d0a
mod_time: 0 # <---- Unknown
source_size: 1621462747 # <---- Must be mode time
 

Когда я прочитал еще 4 байта, прежде чем прочитать значение для кода, я получил это:

 magic: 610d0d0a
mod_time: 0
source_size: 1621462747
4 more bytes: 14 # <----- Must be source size
 

Тогда я мог бы прочитать значение кода:

 code:
    ('print',)(line:1)
  1           0 LOAD_NAME                0 (print)
              2 LOAD_CONST               0 ('Hello')
              4 CALL_FUNCTION            1
              6 POP_TOP
              8 LOAD_CONST               1 (None)
             10 RETURN_VALUE
 

Я не уверен, почему вы можете работать marshal.load() без ошибок, но можете ли вы попытаться прочитать 4 байта больше или меньше перед вызовом marshal.load(f) ?

Комментарии:

1. Я думаю, что проблема не в чтении перед вызовом, а в определении модуля в моей версии, однако я уже обновил свою версию python, но ничего не происходит.!!