Qual é o erro do número mágico ruim?

320

O que é o ImportError "Número mágico incorreto" em python e como corrigi-lo?

A única coisa que posso encontrar online sugere que isso é causado pela compilação de um arquivo .py -> .pyc e, em seguida, tentando usá-lo com a versão errada do python. No meu caso, no entanto, o arquivo parece importar bem algumas vezes, mas não outras, e não sei por que.

As informações que o python fornece no traceback não são particularmente úteis (e é por isso que eu estava perguntando aqui ...), mas aqui está, caso ajude:

Traceback (most recent call last):
  File "run.py", line 7, in <module>
    from Normalization import Normalizer
Noé
fonte
Você poderia fornecer o código no qual o problema está ocorrendo?
Evan Fosmark 5/02/09
E qual versão do python você está usando?
5289
E a Normalização é um dos seus arquivos ou um arquivo de terceiros?
5609
3
Bem, acho que devo estar importando um arquivo .pyc antigo que foi deixado para trás há muito tempo quando mudei o arquivo .py, para que eu pudesse importar a nova versão, mas não a antiga.
Noé
1
Eu axei o arquivo .pyc antigo, então não o tenho à mão, mas meu problema estava nos caminhos de importação - acho que o python teria usado o arquivo .py para recriar o arquivo .pyc se não o tivesse movido (é mesmo?)
Noah

Respostas:

401

O número mágico vem de sistemas do tipo UNIX, nos quais os primeiros bytes de um arquivo mantinham um marcador indicando o tipo de arquivo.

Python coloca um marcador semelhante em seus pycarquivos quando os cria.

Em seguida, o intérprete python garante que esse número esteja correto ao carregá-lo.

Qualquer coisa que danifique esse número mágico causará seu problema. Isso inclui editar o pycarquivo ou tentar executar um pycde uma versão diferente do python (geralmente mais tarde) que o seu intérprete.

Se forem seus pyc arquivos, exclua-os e deixe o intérprete recompilar os pyarquivos. Em sistemas do tipo UNIX, isso pode ser algo tão simples quanto:

rm *.pyc

ou:

find . -name '*.pyc' -delete

Se eles não forem seus, você precisará obter os pyarquivos para recompilação ou um intérprete que possa executar os pycarquivos com esse valor mágico específico.

Uma coisa que pode estar causando a natureza intermitente. O problema pycque está causando o problema pode ser importado apenas sob certas condições. É altamente improvável que às vezes seja importado. Você deve verificar o rastreamento de pilha completa real quando a importação falhar?

Como um aparte, a primeira palavra de todos os meus 2.5.1(r251:54863) pycarquivos é 62131, 2.6.1(r261:67517)é 62161. A lista de todos os números mágicos pode ser encontrada Python/import.caqui, reproduzida aqui para ser completa (atual, no momento em que a resposta foi postada, ela pode ter sido alterada desde então):

1.5:   20121
1.5.1: 20121
1.5.2: 20121
1.6:   50428
2.0:   50823
2.0.1: 50823
2.1:   60202
2.1.1: 60202
2.1.2: 60202
2.2:   60717
2.3a0: 62011
2.3a0: 62021
2.3a0: 62011
2.4a0: 62041
2.4a3: 62051
2.4b1: 62061
2.5a0: 62071
2.5a0: 62081
2.5a0: 62091
2.5a0: 62092
2.5b3: 62101
2.5b3: 62111
2.5c1: 62121
2.5c2: 62131
2.6a0: 62151
2.6a1: 62161
2.7a0: 62171
paxdiablo
fonte
2
Obrigado - isso não me ajudou diretamente a descobrir o meu problema, mas é bom saber a resposta de qualquer maneira!
Noé
Como posso verificar qual arquivo pyc causa o problema, excluí todos os arquivos pyc, mas ainda estou recebendo esse erro.
sunprophit
Talvez você precise de 'rm __pycache __ / * pyc' agora, porque os arquivos pyc agora estão nessa pasta.
Arpad Horvath
1
Obrigado! Isso estava acontecendo comigo: ERRO: tornado.general: Não é possível carregar a tradução para 'es': [Erro 0] Número mágico inválido: '/app/locale/es/LC_MESSAGES/django.mo'. De fato, o * .mo não foi compilado corretamente.
Ericson.cepeda
60

A exclusão de todos os arquivos .pyc corrigirá o erro "Número mágico inválido".

find . -name "*.pyc" -delete
akarca
fonte
8
Provavelmente é melhor usar find . -name "*.pyc" -delete, pois você terá problemas com espaços (e possivelmente com uma linha de comando muito longa) se expandir todos os nomes de arquivos para os quais passar rm.
Andrew Aylett 25/05
25
OMI é um script bastante perigoso. E se um pacote fosse entregue apenas com arquivos .pyc para mantê-lo em código fechado? Ops, você acabou de excluir o aplicativo.
Dan Mantyla
3
Provavelmente é melhor executar primeiro find . -name "*.pyc" -printe só então excluir os arquivos problemáticos manualmente e / ou executar o comando acima, depois de verificar se você não está fazendo algo lamentável.
11136 Michael
9
@DanMantyla Pacotes de código fechado merecem exclusão de qualquer maneira.
cat
25

Carregar um *.pycarquivo gerado em python3 com python2 também causa esse erro.

jtm
fonte
3
Isso pode ser um comentário, não uma resposta.
Kroltan
2
@Kroltan ainda é uma resposta muito boa, melhor do que a aceita. Conciso e ao ponto.
Antony Hatchkins
@AntonyHatchkins Pelo menos na minha opinião, isso poderia ser um comentário sobre qualquer uma das respostas sugerindo a exclusão de .pyc. Embora essa seja uma causa possível , ela não tem uma solução diferente , portanto é redundante. Sinta-se livre para discordar, apenas a minha opinião.
Kroltan
@Kroltan A parte 'como consertar' é bastante óbvia aqui. A causa, é isso que realmente interessante - pelo menos para mim - é. Fiz várias alterações com versões diferentes do python 2.x e nunca encontrei nenhuma incompatibilidade entre as versões .pyc. E esta solução diz que é problema python3 vs python2 - informações ausentes na resposta aceita. Além disso, eu amo respostas curtas (sempre que possível) :)
Antony Hatchkins
@AntonyHatchkins, esta solução pode muito bem dizer que é um PY2 3 emissão / mas isso é apenas uma possibilidade e, para essa matéria, sugerido na resposta aceita (parágrafo 4) desde a sua primeira versão :-)
paxdiablo
6

Leve o arquivo pyc para uma máquina Windows. Use qualquer editor Hex para abrir este arquivo pyc. Eu usei o freeware 'HexEdit'. Agora leia o valor hexadecimal dos dois primeiros bytes. No meu caso, eram 03 f3.

Abra o calc e converta seu modo de exibição para Programmer (Scientific in XP) para ver a conversão Hex e Decimal. Selecione "Hex" no botão de opção. Insira os valores como segundo byte primeiro e depois o primeiro byte, ou seja, f303 Agora clique no botão de opção "Dec" (decimal). O valor exibido é aquele que corresponde ao número mágico, também conhecido como versão do python.

Portanto, considerando a tabela fornecida na resposta anterior

  • 1.5 => 20121 => 4E99 para que os arquivos tenham o primeiro byte como 99 e o segundo como 4e
  • 1.6 => 50428 => C4FC para que os arquivos tenham primeiro byte como fc e segundo como c4
Sanjay Chopra
fonte
2

O erro "número mágico inválido" também ocorre se você tiver nomeado seu arquivo manualmente com uma extensão .pyc

Deke
fonte
1

Eu tive um caso estranho de erro de Bad Magic Number usando uma implementação muito antiga (1.5.2). Eu gerei um arquivo .pyo e isso acionou o erro. Estranhamente, o problema foi resolvido alterando o nome do módulo. O nome ofensivo era sms.py. Se eu gerar um sms.pyo a partir desse módulo, o erro Bad Magic Number foi o resultado. Quando mudei o nome para smst.py, o erro desapareceu. Eu verifiquei para frente e para trás para ver se o sms.py de alguma forma interferia em qualquer outro módulo com o mesmo nome, mas não encontrei nenhuma colisão de nomes. Embora a origem desse problema permaneça um mistério para mim, recomendo tentar uma alteração no nome do módulo.

Gábor Paller
fonte
1

Isso também pode ocorrer devido à falta de __init__.pyarquivo no diretório. Digamos que se você criar um novo diretório no django para separar os testes de unidade em vários arquivos e colocá-los em um diretório, também será necessário criar o __init__.pyarquivo ao lado de todos os outros arquivos no novo diretório de teste criado. caso contrário, pode dar erro como Traceback (most recent call last): File "C:\Users\USERNAME\AppData\Local\Programs\Python\Python35\Lib\unittest\loader.py",line 153, in loadTestsFromName module = __import__(module_name) ImportError: bad magic number in 'APPNAME.tests': b'\x03\xf3\r\n'

Shahraiz Ali
fonte
0

Isso é muito mais eficaz do que acima.

find {directory-of-.pyc-files} -name "*.pyc" -print0 | xargs -0 rm -rf

onde {directory-of-.pyc-files}é o diretório que contém os arquivos python compilados.

ozgurv
fonte
1
Ou seja, se você tiver os arquivos py em mãos, caso contrário, será necessário fazer o downgrade da instalação do python.
Leon Fedotov
1
Isso ainda não é seguro para alguns casos extremos. Além disso, por que estamos fazendo uma exclusão recursiva quando falamos de arquivos?
21612 Jerome Baum
1
Por que você está usando dois processos? Mesmo se achado não tem exclusão, você ainda poderia correrfind /dir -name "*.pyc" -exec rm '{}' ';'
mikemaccana
1
O comando 'find' não funcionará com segurança para nomes de arquivos com espaços se o operador final default -print for usado diretamente pelo xargs rm. O Python não importa arquivos nomeados não identificadores como este, mas os scripts ainda podem causar a quebra e não serão excluídos. Geralmente sempre é mais seguro usar -print0 extra (zero no final) no comando find (como o último parâmetro antes do símbolo de barra vertical | |) e, em seguida, a opção -0 em xargs (que é um hífen + zero) para entender o - print0 output antes do comando rm, quando a tubulação encontra no xargs.
Breezer #
0

No meu caso, não eram mais do que arquivos de tradução .pycbinária antigos .modepois que renomeei meu próprio módulo, portanto, dentro desta pasta do módulo, tive que executar

find . -name \*.po -execdir sh -c 'msgfmt "$0" -o `basename $0 .po`.mo' '{}' \;

(faça backup e tente corrigir os .pycarquivos primeiro)

d9k
fonte
0

Isso também pode acontecer se você tiver o arquivo python27.dll errado (no caso do Windows), para resolver isso basta reinstalar (ou extrair) o python com a versão exata da dll correspondente. Eu tive uma experiência parecida.

Ibrahim.H
fonte
0

Eu apenas enfrentei o mesmo problema com o Fedora26, onde muitas ferramentas como o dnf foram quebradas devido ao número mágico ruim para seis. Por um motivo desconhecido, eu tenho um arquivo /usr/bin/six.pyc, com o número mágico inesperado. A exclusão deste arquivo corrige o problema

zedge
fonte
0

No meu caso, eu tenho git cloneuma biblioteca que tinha um intérprete de

#!/usr/bin/env python

Embora pythonestivesse levando Python2.7embora meu código principal estivesse sendo executado com python3.6 ... ele ainda criou um *.pycarquivo para a 2.7versão ...

Posso dizer que esse erro provavelmente é resultado de uma mistura entre as versões 2.7 e 3+, é por isso que a limpeza (de qualquer forma que você possa pensar que está usando) - ajudará aqui ...

  • não se esqueça de ajustar o código Python2x -> python 3 ...
Ricky Levi
fonte
-1

Não os apague !!! Até..........

Encontre uma versão na sua pasta git, svn ou copy que funcione.

Exclua-os e depois recupere todos os .pyc.

Isso é trabalho para mim.

lauralacarra
fonte
eyyy por que eu tenho -1? ele realmente funciona para mim e eu estava em péssima situação ¬¬
lauralacarra
2
reverter para a versão anterior não é uma solução global
ZiTAL 16/01
4
Por que você iria confirmar seus *.pycarquivos?
Manos Kounelakis 2/11
Esse é o erro usual. Quando você não configura o arquivo git ignore corretamente. Então, eu dou a solução e então você deve pedir seu git.
Lauralacarra
-1

Você precisará executar este comando em todos os caminhos existentes em seu ambiente.

>>> import sys
>>> sys.path
['', '/usr/lib/python36.zip', '/usr/lib/python3.6', '/usr/lib/python3.6/lib-dynload', '/usr/local/lib/python3.6/dist-packages', '/source_code/src/python', '/usr/lib/python3/dist-packages']

Em seguida, execute o comando em todos os diretórios aqui

find /usr/lib/python3.6/ -name "*.pyc" -delete
find /usr/local/lib/python3.6/dist-packages -name "*.pyc" -delete
# etc...
Ahmed
fonte