#python #compilation
#python #Сборник
Вопрос:
Есть ли какой-либо способ узнать, с помощью какой версии Python .pyc
был скомпилирован файл?
Ответ №1:
Первые два байта .pyc
файла — это магическое число, которое указывает версию байт-кодов. Слово хранится в формате с малым порядком, а известные значения:
Версия Python | Десятичный | Шестнадцатеричный | Комментарий |
---|---|---|---|
Python 1.5 | 20121 | 0x994e | |
Python 1.5.1 | 20121 | 0x994e | |
Python 1.5.2 | 20121 | 0x994e | |
Python 1.6 | 50428 | 0x4cc4 | |
Python 2.0 | 50823 | 0x87c6 | |
Python 2.0.1 | 50823 | 0x87c6 | |
Python 2.1 | 60202 | 0x2aeb | |
Python 2.1.1 | 60202 | 0x2aeb | |
Python 2.1.2 | 60202 | 0x2aeb | |
Python 2.2 | 60717 | 0x2ded | |
Python 2.3a0 | 62011 | 0x3bf2 | |
Python 2.3a0 | 62021 | 0x45f2 | |
Python 2.3a0 | 62011 | 0x3bf2 | ! |
Python 2.4a0 | 62041 | 0x59f2 | |
Python 2.4a3 | 62051 | 0x63f2 | |
Python 2.4b1 | 62061 | 0x6df2 | |
Python 2.5a0 | 62071 | 0x77f2 | |
Python 2.5a0 | 62081 | 0x81f2 | ast-ветвь |
Python 2.5a0 | 62091 | 0x8bf2 | with |
Python 2.5a0 | 62092 | 0x8cf2 | изменен WITH_CLEANUP код операции |
Python 2.5b3 | 62101 | 0x95f2 | исправить неправильный код: for x, in ... |
Python 2.5b3 | 62111 | 0x9ff2 | исправить неправильный код: x = yield |
Python 2.5c1 | 62121 | 0xa9f2 | исправьте неправильный lnotab с помощью циклов for и сохранения констант, которые должны были быть удалены |
Python 2.5c2 | 62131 | 0xb3f2 | исправить неправильный код: for x, in ... в listcomp / genexp |
Python 2.6a0 | 62151 | 0xc7f2 | оптимизация глазка и STORE_MAP код операции |
Python 2.6a1 | 62161 | 0xd1f2 | WITH_CLEANUP оптимизация |
Python 2.7a0 | 62171 | 0xdbf2 | оптимизация понимания / изменения списка LIST_APPEND |
Python 2.7a0 | 62181 | 0xe5f2 | оптимизация условных ветвей: введение POP_JUMP_IF_FALSE и POP_JUMP_IF_TRUE |
Python 2.7a0 | 62191 | 0xeff2 | представляем SETUP_WITH |
Python 2.7a0 | 62201 | 0xf9f2 | представляем BUILD_SET |
Python 2.7a0 | 62211 | 0x03f3 | представьте MAP_ADD и SET_ADD |
Python 3000 | 3000 | 0xb80b | |
3010 | 0xc20b | Удалено UNARY_CONVERT |
|
3020 | 0xcc0b | добавлено BUILD_SET |
|
3030 | 0xd60b | добавлены параметры только для ключевых слов | |
3040 | 0xe00b | добавлены аннотации подписи | |
3050 | 0xea0b | print становится функцией |
|
3060 | 0xf40b | Синтаксис метакласса PEP 3115 | |
3061 | 0xf50b | строковые литералы становятся юникодом | |
3071 | 0xff0b | PEP 3109 вызывает изменения | |
3081 | 0x090c | PEP 3137 make __file__ и __name__ unicode |
|
3091 | 0x130c | убейте интернирование str8 | |
3101 | 0x1d0c | слияние с 2.6a0, см. 62151 | |
3103 | 0x1f0c | __file__ указывает на исходный файл |
|
Python 3.0a4 | 3111 | 0x270c | WITH_CLEANUP оптимизация |
Python 3.0a5 | 3131 | 0x3b0c | лексическое накопление исключений, включая POP_EXCEPT |
Python 3.1a0 | 3141 | 0x450c | оптимизация понимания списков, наборов и диктовок: изменение LIST_APPEND и SET_ADD добавление MAP_ADD |
Python 3.1a0 | 3151 | 0x4f0c | оптимизация условных ветвей: введение POP_JUMP_IF_FALSE и POP_JUMP_IF_TRUE |
Python 3.2a0 | 3160 | 0x580c | добавить SETUP_WITH , тег: cpython-32 |
Python 3.2a1 | 3170 | 0x620c | добавить DUP_TOP_TWO , удалить DUP_TOPX и ROT_FOUR , тег: cpython-32 |
Python 3.2a2 | 3180 | 0x6c0c | Добавить DELETE_DEREF |
Источники:
- Python / import.c — объединенный aix с Python 2.7.2 и Python 3.2.2
- Небольшие шестнадцатеричные значения для сравнения первых двух байтов метода Игоря Попова, добавленные jimbob
Комментарии:
1.
@aix
также хороший ответ, но обычно программное решение легко понять, как@Popov
указано. Действительно спасибо.2. @AamirAdnan: Но что, если у вас случайно нет версии python, которая создала файл .pyc?
3. Нет проблем. Ваш ответ был отличным, и теперь его использует простой поиск по таблице
with open('test51.pyc') as f: magic=f.read(2); magic.encode('hex')
.4.
@Jefromi
О, да, какой смысл, в таком случае@Popov
, решениеFails
. Поскольку он никогда не будет сопоставлен сpython version hex code
hex code of first two bytes
.pyc
файлом of . И я никогда не узнаю, какой была версия. И в конце концов я должен перейти к@aix
решению для поиска версии Python. Я прав?:)5. обновленный список магических чисел @ raw.githubusercontent.com/google/pytype/master/pytype/pyc /…
Ответ №2:
Вы можете получить магическое число вашего Python следующим образом:
$ python -V
Python 2.6.2
# python
>>> import imp
>>> imp.get_magic().encode('hex')
'd1f20d0a'
Чтобы получить магическое число для файла pyc, вы можете сделать следующее:
>>> f = open('test25.pyc')
>>> magic = f.read(4)
>>> magic.encode('hex')
'b3f20d0a'
>>> f = open('test26.pyc')
>>> magic = f.read(4)
>>> magic.encode('hex')
'd1f20d0a'
Сравнивая магические числа, вы узнаете версию python, которая сгенерировала файл pyc.
Комментарии:
1. чтобы сравнить волшебное слово, записанное как целое число в исходном коде Python , с
imp.get_magic()
байтами (Python 3):int.from_bytes(imp.get_magic()[:2], 'little')
(игнорироватьb'rn'
), например,imp.get_magic() == b'3rrn'
соответствует3379
(Python 3.6).
Ответ №3:
Или, если у вас система GNU / Linux, вы можете использовать команду «file» в терминале:
$ file code.pyc
> code.pyc: python 3.5.2 byte-compiled
Комментарии:
1. Это намного проще
2. Спасибо. Но я попал
test2.cpython-38.pyc: data
под Windows WSL Ubuntu с python 3.8.5, я не знаю почему.3. @Rick это зависит от выпуска самой программы «file», моя команда file взята из общих команд BSD, а моя версия — 5.39. Исходный код можно найти здесь: github.com/freebsd/freebsd/tree/master/contrib/file и файл, в котором записаны правила для файлов .pyc, находится здесь: github.com/freebsd/freebsd/blob/master/contrib/file/magic /…
Ответ №4:
Взгляните на мой скрипт на Python, который обнаруживает и возвращает версию Python, с помощью которой был скомпилирован файл (* .pyc или * .pyo).
Он обнаруживает версии Python от Python 1.5 до последней сборки Python 3.
Комментарии:
1. Я не смог найти свое магическое число в использовании других ответов, спасибо за сценарий!
Ответ №5:
Официальный репозиторий Python github больше не сохраняет список в import.c.
При поиске более актуального списка, чем я мог найти в другом месте, я столкнулся с тем, что выглядит как актуальный список от Google по состоянию на май 2017 года.
https://github.com/google/pytype/blob/master/pytype/pyc/magic.py
Комментарии:
1. исходные данные взяты из репозитория CPython
Ответ №6:
Добавление к ответу @Igor Popov.
Чтобы проверить версию скомпилированного скрипта из более новой версии Python:
# written in python3
filename = "outfit.cpython-39.pyc"
with open(filename,'rb') as f:
magic = f.read(4)
print(int.from_bytes(magic[:2], 'little'))
Вы можете найти номер вывода здесь:
https://github.com/google/pytype/blob/master/pytype/pyc/magic.py