2009-02-12 8 views
23
File "/usr/local/lib/python3.0/cgi.py", line 477, in __init__ 
    self.read_urlencoded() 
    File "/usr/local/lib/python3.0/cgi.py", line 577, in read_urlencoded 
    self.strict_parsing): 
    File "/usr/local/lib/python3.0/urllib/parse.py", line 377, in parse_qsl 
    pairs = [s2 for s1 in qs.split('&') for s2 in s1.split(';')] 
TypeError: Type str doesn't support the buffer API 

¿Alguien me puede indicar cómo evitar esto? Lo estoy recibiendo alimentando datos en el cgi.Fieldstorage y no puedo hacerlo de otra manera.Error de urllib.parse de Python 3.0 "Escriba str no admite la API de búfer"

Respuesta

28

urllib está tratando de hacer:

b'a,b'.split(',') 

que no funciona. Las cadenas de bytes y cadenas unicode se mezclan aún menos en Py3k de lo que solían hacerlo, deliberadamente, para hacer que los problemas de codificación salgan mal más temprano que tarde.

Así que el error es bastante opaco que le dice 'no puede pasar una cadena de bytes a urllib.parse'. Es de suponer que está haciendo una solicitud POST, donde la cadena codificada entra en cgi como cuerpo de contenido; el cuerpo de contenido sigue siendo una cadena/secuencia de bytes por lo que ahora entra en conflicto con el nuevo urllib.

Así que sí, es un error en cgi.py, otra víctima de la conversión 2to3 que no se ha corregido correctamente para el nuevo modelo de cadena. Debería convertir la secuencia de bytes entrantes a caracteres antes de pasarlos a urllib.

¿Mencioné que las bibliotecas de Python 3.0 (especialmente las relacionadas con la web) siguen siendo bastante shonky? :-)

+0

Sí. Hasta ahora he notado grandes problemas con cgi, urllib y wsgiref. Espero que se arreglen pronto. :( –

+0

De hecho, el impulso en WEB-SIG parece haberse detenido, nadie parece querer la propiedad del tema. Muy decepcionante. – bobince

+0

Creo que esto finalmente debería funcionar correctamente en 3.2 (ver http: // bugs .python.org/issue4953). – ncoghlan

13

En el tutorial de Python (http://www.python.org/doc/3.0/tutorial/stdlib.html) hay un ejemplo del uso del método urlopen. Se plantea el mismo error.

for line in urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl'): 
    if 'EST' in line or 'EDT' in line: # look for Eastern Time 
     print(line) 

Tendrá que usar la función str para convertir el byte thingo en una cadena con la codificación correcta. De la siguiente manera:

for line in urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl'): 
    lineStr = str(line, encoding='utf8') 
    if 'EST' in lineStr or 'EDT' in lineStr: # look for Eastern Time 
     print(lineStr) 
+3

Sería realmente interesante proporcionar una solución que funcione con ambas versiones de python. – sorin

Cuestiones relacionadas