¿Cuál es el error del número mágico malo?

320

¿Qué es el ImportError "Número mágico malo" en Python y cómo lo soluciono?

Lo único que puedo encontrar en línea sugiere que esto se debe a compilar un archivo .py -> .pyc y luego intentar usarlo con la versión incorrecta de python. En mi caso, sin embargo, el archivo parece importarse bien algunas veces pero no otras, y no estoy seguro de por qué.

La información que proporciona Python en el rastreo no es particularmente útil (es por eso que estaba preguntando aquí ...), pero aquí está en caso de que ayude:

Traceback (most recent call last):
  File "run.py", line 7, in <module>
    from Normalization import Normalizer
Noé
fuente
¿Podría proporcionar el código en el que se produce el problema?
Evan Fosmark
¿Y qué versión de Python estás usando?
paxdiablo
¿Y es Normalization uno de sus archivos o un tercero?
paxdiablo
3
Hrm, está bien, creo que debo haber estado importando un archivo .pyc antiguo que se quedó atrás hace mucho tiempo cuando moví el archivo .py, por lo que pude importar la nueva versión pero no la anterior.
Noah
1
Eliminé el viejo archivo .pyc, así que no lo tengo a la mano, pero mi problema fue con las rutas de importación: creo que Python habría usado el archivo .py para recrear el archivo .pyc si no lo hubiera movido (¿es así?)
Noah

Respuestas:

401

El número mágico proviene de sistemas de tipo UNIX donde los primeros bytes de un archivo contenían un marcador que indica el tipo de archivo.

Python coloca un marcador similar en sus pycarchivos cuando los crea.

Luego, el intérprete de Python se asegura de que este número sea correcto al cargarlo.

Cualquier cosa que dañe este número mágico causará su problema. Esto incluye editar el pycarchivo o intentar ejecutar un archivo pycdesde una versión diferente de python (generalmente más tarde) que su intérprete.

Si son sus pyc archivos, simplemente elimínelos y deje que el intérprete vuelva a compilar los pyarchivos. En los sistemas de tipo UNIX, eso podría ser algo tan simple como:

rm *.pyc

o:

find . -name '*.pyc' -delete

Si no son suyos, tendrá que obtener los pyarchivos para volver a compilarlos o un intérprete que pueda ejecutar los pycarchivos con ese valor mágico en particular.

Una cosa que podría estar causando la naturaleza intermitente. Lo pycque está causando el problema solo puede importarse bajo ciertas condiciones. Es muy poco probable que importe algunas veces. ¿Debe verificar el seguimiento real de la pila completa cuando falla la importación?

Como comentario aparte, la primera palabra de todos mis 2.5.1(r251:54863) pycarchivos es 62131, 2.6.1(r261:67517)es 62161. La lista de todos los números mágicos se puede encontrar en Python/import.c, reproducida aquí para completar (actual como en el momento en que se publicó la respuesta, puede haber cambiado desde entonces):

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
fuente
2
Gracias, esto no me ayudó directamente a resolver mi problema, ¡pero es bueno saber la respuesta de todos modos!
Noah
¿Cómo puedo verificar qué archivo pyc causa el problema? He eliminado todos los archivos pyc pero sigo recibiendo este error.
sunprophit
Quizás necesite 'rm __pycache __ / * pyc' ahora, porque los archivos pyc ahora están en esa carpeta.
Arpad Horvath
1
¡Gracias! Me estaba sucediendo con: ERROR: tornado.general: No se puede cargar la traducción para 'es': [Errno 0] Número mágico incorrecto: '/app/locale/es/LC_MESSAGES/django.mo'. De hecho, fue que * .mo no se compiló correctamente.
ericson.cepeda
60

Eliminar todos los archivos .pyc solucionará el error "Número mágico incorrecto".

find . -name "*.pyc" -delete
akarca
fuente
8
Probablemente sea mejor usarlo find . -name "*.pyc" -delete, ya que tendrá problemas con los espacios (y posiblemente con una línea de comando demasiado larga) si expande todos los nombres de archivo para pasar rm.
Andrew Aylett
25
OMI es un guión bastante peligroso. ¿Qué sucede si un paquete se entregó solo con archivos .pyc para mantener el código cerrado? Vaya, acabas de eliminar la aplicación.
Dan Mantyla
3
Probablemente sea mejor ejecutar primero find . -name "*.pyc" -printy solo luego eliminar manualmente los archivos problemáticos y / o ejecutar el comando anterior, después de verificar que no está haciendo algo lamentable.
michael
99
@DanMantyla Los paquetes de código cerrado merecen borrarse de todos modos.
gato
25

Cargar un *.pycarchivo generado por python3 con python2 también causa este error.

jtm
fuente
3
Esto podría ser un comentario, no una respuesta.
Kroltan
2
@Kroltan, sin embargo, es una respuesta muy buena, mejor que la aceptada. Concisa y al grano.
Antony Hatchkins
@AntonyHatchkins Al menos en mi opinión, este podría ser un comentario sobre cualquiera de las respuestas que sugieran la eliminación de .pyc. Aunque esta es una posible causa , no tiene una solución diferente , por lo que es redundante. Siéntase libre de estar en desacuerdo, solo mi opinión.
Kroltan
@Kroltan La parte de "cómo arreglar" es bastante obvia aquí. La causa, eso es lo realmente interesante, al menos para mí, es. Hice mucho trabajo con diferentes versiones de python 2.x y nunca encontré ninguna incompatibilidad entre las versiones .pyc. Y esta solución dice que es un problema python3 vs python2: falta información en la respuesta aceptada. Además, me encantan las respuestas cortas (cuando sea posible) :)
Antony Hatchkins
@AntonyHatchkins, esta solución puede decir que es un problema de py2 / 3, pero esa es solo una posibilidad y, de hecho, una sugerida en la respuesta aceptada (párrafo 4) desde su primera versión :-)
paxdiablo
6

Lleva el archivo pyc a una máquina con Windows. Use cualquier editor hexadecimal para abrir este archivo pyc. Utilicé el freeware 'HexEdit'. Ahora lea el valor hexadecimal de los primeros dos bytes. En mi caso, estos fueron 03 f3.

Abra calc y convierta su modo de visualización a Programmer (Scientific en XP) para ver la conversión Hex y Decimal. Seleccione "Hex" del botón de radio. Ingrese los valores como el segundo byte primero y luego el primer byte, es decir, f303 Ahora haga clic en el botón de opción "Dec" (Decimal). El valor que se muestra es uno que corresponde al número mágico, también conocido como versión de python.

Entonces, considerando la tabla proporcionada en la respuesta anterior

  • 1.5 => 20121 => 4E99 para que los archivos tengan el primer byte como 99 y el segundo como 4e
  • 1.6 => 50428 => C4FC para que los archivos tengan el primer byte como fc y el segundo como c4
Sanjay Chopra
fuente
2

El error "Número mágico incorrecto" también ocurre si ha nombrado manualmente su archivo con una extensión .pyc

Deke
fuente
1

Tuve un extraño caso de error Bad Magic Number usando una implementación muy antigua (1.5.2). Generé un archivo .pyo y eso provocó el error. Curiosamente, el problema se resolvió cambiando el nombre del módulo. El nombre ofensivo era sms.py. Si generé un sms.pyo a partir de ese módulo, el resultado fue un error de Bad Magic Number. Cuando cambié el nombre a smst.py, el error desapareció. Revisé de un lado a otro para ver si sms.py de alguna manera interfería con algún otro módulo con el mismo nombre, pero no pude encontrar ninguna colisión de nombres. Aunque la fuente de este problema seguía siendo un misterio para mí, recomiendo probar un cambio de nombre del módulo.

Gábor Paller
fuente
1

Esto también puede deberse a que falta un __init__.pyarchivo del directorio. Digamos que si crea un nuevo directorio en django para separar las pruebas unitarias en varios archivos y los coloca en un directorio, entonces también debe crear el __init__.pyarchivo junto a todos los demás archivos en el nuevo directorio de prueba creado. de lo contrario, puede dar un error 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
fuente
0

Esto es mucho más eficiente que el anterior.

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

donde {directory-of-.pyc-files}está el directorio que contiene los archivos compilados de python.

ozgurv
fuente
1
Eso es en caso de que tenga los archivos py a la mano, si no, tendrá que degradar la instalación de python.
Leon Fedotov
1
Esto todavía no es seguro para algunos casos extremos. Además, ¿por qué estamos haciendo una eliminación recursiva cuando hablamos de archivos?
Jerome Baum
1
¿Por qué estás usando dos procesos? Incluso si find no tuviera eliminar, aún podría ejecutarfind /dir -name "*.pyc" -exec rm '{}' ';'
mikemaccana
1
El comando 'buscar' no funcionará de forma segura para los nombres de archivo con espacios si el operador final predeterminado de impresión se usa directamente por xargs rm. Python no importa archivos con nombre sin identificador como este, pero las secuencias de comandos aún podrían hacer que esto se rompa y no se eliminarían. En general, siempre es más seguro usar un extra -print0 (cero al final) en el comando de búsqueda (como el último parámetro antes del símbolo de tubería '|') y luego la opción -0 en xargs (eso es un guión + cero) para comprender el - print0 salida antes del comando rm, cuando la tubería se encuentra en xargs.
Breezer
0

En mi caso, no fueron .pycsino viejos .moarchivos de traducción binaria después de cambiar el nombre de mi propio módulo, por lo que dentro de esta carpeta del módulo tuve que ejecutar

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

(haga una copia de seguridad e intente arreglar los .pycarchivos primero)

d9k
fuente
0

Esto también puede suceder si tiene el archivo python27.dll incorrecto (en el caso de Windows), para resolver esto simplemente reinstale (o extraiga) python con la versión dll correspondiente. Yo tuve una experiencia similar.

Ibrahim.H
fuente
0

Acabo de enfrentar el mismo problema con Fedora26, donde muchas herramientas como dnf se rompieron debido a un número mágico malo para seis. Por una razón desconocida, tengo un archivo /usr/bin/six.pyc, con el número mágico inesperado. Eliminar este archivo soluciona el problema

zedge
fuente
0

En mi caso, tengo git cloneuna biblioteca que tenía un intérprete de

#!/usr/bin/env python

Mientras pythonconducía a Python2.7pesar de que mi código principal se estaba ejecutando con python3.6 ... todavía creó un *.pycarchivo para la 2.7versión ...

Puedo decir que este error probablemente sea el resultado de una mezcla entre las versiones 2.7 y 3+, es por eso que la limpieza (de cualquier forma que se te ocurra que estás usando), ayudará aquí ...

  • no olvides ajustar esos códigos Python2x -> python 3 ...
Ricky Levi
fuente
-1

¡No los elimines! Hasta..........

Encuentre una versión en su carpeta git, svn o copy que funcione.

Elimínelos y luego recupere todo .pyc.

Eso es trabajo para mi.

lauralacarra
fuente
eyyy ¿por qué tengo -1? realmente funciona para mí y estaba en una situación realmente mala ¬¬
lauralacarra
2
volver a la versión anterior no es una solución global
ZiTAL
44
¿Por qué comprometerías tus *.pycarchivos?
Manos Kounelakis
Ese es el error habitual. Cuando no configuras el archivo git ignore correctamente. Así que doy la solución y luego debes pedir tu git.
lauralacarra
-1

Deberá ejecutar este comando en cada ruta que tenga en su entorno.

>>> 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']

Luego ejecute el comando en cada directorio aquí

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