2015-02-27 6 views
11

Non riesco a trovare la causa principale di questo. Non so se si tratta di pyinstaller, un problema di pip, il modulo delle richieste o qualcos'altro visto che nulla può essere eliminato in modo definitivo.Errore Pyinstaller ImportError: nessun modulo denominato 'requests.packages.chardet.sys

Ho scritto uno script in python che configura correttamente un nuovo hardware sonicwall per la nostra rete aziendale quando dobbiamo implementare una nuova unità. Configura un file .exp corretto in memoria, accede al dispositivo sonicwall con credenziali predefinite, importa il file tramite un modulo dati multiparte, riavvia il sonicwall, quindi esegue nuovamente il login e modifica correttamente il segreto condiviso. Per motivi di sicurezza, non posso pubblicare il codice qui, ma posso spiegare il problema con un esempio molto più semplice. In precedenza, il codice utilizzava urllib e urllib2 per elaborare le richieste http, ma poi ho scoperto il modulo delle richieste quando ho dovuto riscrivere lo script per includere csrfTokens.

Per farla breve, lo script funziona in modo sorprendente quando viene chiamato dall'interprete python. Tuttavia, quando provo a compilarlo con pyinstaller, ricevo una serie di errori ora che sono passato alle richieste invece delle urllibs.

Alcuni più di fondo:

Windows 7 - Python2.7.9 
pip 6.0.8 from C:\Python27\lib\site-packages\pip-6.0.8-py2.7.egg (python 2.7) 
pip freeze output: 
pyinstaller==2.1.1.dev0 
pywin32==219 
requests==2.5.3 

Per fare un esempio, ti darò un codice che le bombe, una semplice richiesta a Google.

#!/usr/bin/python 
import requests 
r = requests.get('https://google.com') 
print(r.text) 

Il codice precedente funziona per una semplice richiesta quando chiamo il file in pitone, ma quando compilo esso, ottengo questo:

(EDIT avendo problemi per incollare in uscita, qui è la pastebin) pastebin

esso crea un eseguibile di Windows, ma questo è il seguente errore quando provo a farlo funzionare:

NOTA ho installato il ms C++ 2008 redistributa per aiutare a chiarire msvcr90.dll, ma ottengo ancora l'errore request.packages.chardet.sys sopra.

Ho provato tutto quello che posso pensare, installando chardet, installando chardet2, installando cchardet, forzando le versioni precedenti di pyinstaller e le richieste in modo incrementale. Rottamazione dei pip e installazione manuale di pyinstaler e richieste. Sono alla fine del mio spirito con cose da provare, non ho proprio qui l'errore. requests.packages.chardet esiste sul sistema. Ho anche C: \ Python27 nel mio PATH di Windows in quanto posso chiamare python da qualsiasi directory.

Se avete bisogno di ulteriori informazioni, fatemelo sapere. Ho cercato di essere il più accurato possibile con gli errori e ciò che ho installato, ma posso fornire di più se necessario.

ANCHE SOLO questo problema sembra accadere quando provo a compilare quando impongo richieste. creando script di test, beautifulsoup, urllib/2, ecc. tutti compilano un exe di windows valido che funziona correttamente.

+0

Sembra correlato a https://www.mail-archive.com/[email protected]/msg00374.html e http://comments.gmane.org/gmane.comp.python.pyinstaller/3281 –

risposta

9

Non ho ancora una soluzione per questo, ma questo è causato dalle ultime modifiche nel modulo requests (versioni 2.5.2 & 2.5.3).

Per ora è possibile utilizzare la versione 2.5.1 finché PyInstaller non avrà un gancio adatto per risolvere questo problema.

Non posso davvero spiegare il problema, ma sembra che ci sia una specie di collisione tra PyInstaller ganci d'importazione e alcune ultime aggiunte al requests (VendorAlias).

+0

.. . Grazie! Hai appena risposto ieri, e oggi ho ricevuto l'errore. Eccezionale! – swdev

+0

m1keil, hai appena salvato ciò che rimane dei capelli in testa! Mi sono tirato i capelli su questo problema e forzare le richieste 2.5.1 l'ho risolto! Prima di pubblicare qui, ho anche pubblicato il bug tracker di richieste github, quindi ne è a conoscenza. Ho collegato questo thread anche al suo tracker dei problemi. Ma solo così capisco, non pensiamo che sia necessariamente tutte le richieste di errore, o pyinstaller, sembra solo che entrambi stiano facendo le cose in modo diverso e finiscano in una collisione con ganci di importazione e una nuova aggiunta alle richieste? –

+0

Sì, è esattamente quello che penso. Il problema con cose come PyInstaller, py2exe e simili è che il modulo Python sottostante deve essere "consapevole" che a volte è in esecuzione in stato "congelato". Sembra che questo sia esattamente il caso. – m1keil

-1

Penso che il problema sia stato apportato alla versione Setuptools, quindi provare a utilizzare una versione precedente e testarla di nuovo. Nel mio caso funziona!

>> pip uninstall setuptools 
>> pip install setuptools==12.0.5 

Credo che il problema è in relazione con l'interpretazione di un argomento posizionale

+1

Ho provato questo e non ha funzionato per me. –

1

Come m1keil dice, il problema è tra PyInstaller ganci d'importazione e le nuove funzionalità load_module di richieste, implementato nel file requests.packages.__init__.py sorgente.

Il debug di questo file è possibile vedere che qualsiasi importazione del pacchetto di richieste sta passando attraverso la funzione load_module. Questo include i pacchetti standard Python. Questa è la ragione dell'errore.

mia soluzione consiste nella modifica della (cartella all'interno della virtualenv) requests.packages.__init__.py della versione 2.5.3 e l'aggiunta di questo pezzo di codice, proprio all'inizio della funzione load_module:

print "Requested name = ", name #Comment this line when it works 
    direct_loaded_packages = ('sys', 'errno','logging','warnings' 
      ,'socket','os','re','time','hashlib','base64' 
      ,'time','collections','datetime','io', 'argparse' 
      ,'codecs', 'Queue', 'zlib', 'ssl', 'operator' 
      ,'types','platform','struct', 'StringIO','httplib' 
      ,'simplejson','cookielib','urllib','urlparse' 
      ,'urllib2','Cookie','http','binascii','certifi' 
      ,'uuid','json','threading','dummy_thread','email' 
      ,'email.utils','operator','mimetypes')  


    new_name = '' 
    #Package with three directory deep 
    if '.'.join(name.split('.')[3:]) in direct_loaded_packages: 
     new_name = '.'.join(name.split('.')[3:]) 
    #Package with four directory deep 
    elif '.'.join(name.split('.')[4:]) in direct_loaded_packages: 
     new_name = '.'.join(name.split('.')[4:]) 
    #Package with five directory deep 
    elif '.'.join(name.split('.')[5:]) in direct_loaded_packages: 
     new_name = '.'.join(name.split('.')[5:]) 

    if new_name != '': 
     module = __import__(new_name) 
     return module 

Dalla prova di errore e & grepping Ho compilato la lista dei pacchetti che devono essere caricati direttamente senza passare dalla funzione load_module.

Non è elegante ma funziona. Ho provato una soluzione più elegante ma non ci sono riuscito.

3

Buone notizie, questo è stato risolto nella versione più recente di requests

pip install requests --upgrade 

facile.