2016-07-05 1 views
0

J'ai rencontré des problèmes en utilisant le SimpleCookie de Python lorsque vous utilisiez une chaîne JSON comme valeur.Python SimpleCookie et la valeur JSON

In [1]: from http.cookies import SimpleCookie 

In [2]: cookie = SimpleCookie('x=1; json={"myVal":1}; y=2') 

In [3]: cookie.keys() 
Out[3]: dict_keys(['x']) 

In [4]: cookie = SimpleCookie('x=1; y=2') 

In [5]: cookie.keys() 
Out[5]: dict_keys(['y', 'x']) 

Non seulement la chaîne JSON est manquante, mais toutes les autres valeurs viennent également. Je me demande maintenant s'il s'agit d'un bug lié à Python, car les caractères devraient être bien utilisés dans un cookie?

Répondre

2

Actuellement, vous essayez d'utiliser un objet comme valeur, pas une représentation de chaîne JSON de cet objet. Vous devez échapper à la chaîne JSON au sein de votre chaîne d'arguments, comme suit:

>>> from http.cookies import SimpleCookie 
>>> cookie = SimpleCookie(r'x=1; json="{\"myVal\":1}"; y=2') 
         #^note raw string ^and single backslashes 
>>> cookie.keys() 
dict_keys(['json', 'x', 'y']) 

Il semble étrange qu'une chaîne malformée est tranquillement consommée dans la mesure où il peut aller et le reste est abandonné, bien que; Je m'attends à un ValueError ou quelque chose pour votre contribution. The parser s'arrête juste et renvoie le résultat si loin quand il est à court de choses qui correspondent à l'expression rationnelle.


Compte tenu Marius's answer, qui semblait fonctionner sur 3.3.2, mais ne fonctionne pas dans 3.5.2 (et, pour moi, ne ressemble pas à cela devrait fonctionner partout, une importation de package JSON implicite ?!) Je suis allé chercher quand ça a changé. En utilisant ce script:

from http.cookies import SimpleCookie 
import json 
from sys import version 

print(version) 

cookie1 = SimpleCookie('x=1; json=json.dumps({"myVal":1}); y=2') 
print('Marius ', cookie1.keys(), repr(cookie1.get('json')), sep='\t') 

cookie2 = SimpleCookie(r'x=1; json="{\"myVal\":1}"; y=2') 
print('Jonathan', cookie2.keys(), repr(cookie2.get('json')), sep='\t') 

cookie3 = SimpleCookie('x=1; json={"myVal":1}; y=2') 
print('Bernhard', cookie3.keys(), repr(cookie3.get('json')), sep='\t') 

et pyenv sous Mac OS X donne les résultats suivants pour 3.3:

3.3.0 (default, Jul 7 2016, 10:47:41) 
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.72)] 
Marius  dict_keys(['x', 'y', 'json']) <Morsel: json='json.dumps({'> 
Jonathan dict_keys(['x', 'y', 'json']) <Morsel: json='{"myVal":1}'> 
Bernhard dict_keys(['x', 'y', 'json']) <Morsel: json='{'> 

3.3.1 (default, Jul 7 2016, 10:53:06) 
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.72)] 
Marius  dict_keys(['json', 'x', 'y']) <Morsel: json='json.dumps({'> 
Jonathan dict_keys(['json', 'x', 'y']) <Morsel: json='{"myVal":1}'> 
Bernhard dict_keys(['json', 'x', 'y']) <Morsel: json='{'> 

3.3.2 (default, Jul 6 2016, 22:02:23) 
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.72)] 
Marius  dict_keys(['json', 'y', 'x']) <Morsel: json='json.dumps({'> 
Jonathan dict_keys(['json', 'y', 'x']) <Morsel: json='{"myVal":1}'> 
Bernhard dict_keys(['json', 'y', 'x']) <Morsel: json='{'> 

# ...loses 'json' 

3.3.3 (default, Jul 7 2016, 10:57:02) 
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.72)] 
Marius  dict_keys(['x', 'y']) None 
Jonathan dict_keys(['x', 'y', 'json']) <Morsel: json='{"myVal":1}'> 
Bernhard dict_keys(['x', 'y']) None 

3.3.4 (default, Jul 7 2016, 10:59:21) 
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.72)] 
Marius  dict_keys(['y', 'x']) None 
Jonathan dict_keys(['y', 'x', 'json']) <Morsel: json='{"myVal":1}'> 
Bernhard dict_keys(['y', 'x']) None 

3.3.5 (default, Jul 7 2016, 11:01:45) 
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.72)] 
Marius  dict_keys(['y', 'x']) None 
Jonathan dict_keys(['json', 'y', 'x']) <Morsel: json='{"myVal":1}'> 
Bernhard dict_keys(['y', 'x']) None 

# ...and now 'y'! 

3.3.6 (default, Jul 7 2016, 11:03:40) 
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.72)] 
Marius  dict_keys(['x']) None 
Jonathan dict_keys(['json', 'x', 'y']) <Morsel: json='{"myVal":1}'> 
Bernhard dict_keys(['x']) None 

De là, il semble être stable:

3.4.4 (default, Jul 7 2016, 11:13:43) 
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.72)] 
Marius  dict_keys(['x']) None 
Jonathan dict_keys(['json', 'y', 'x']) <Morsel: json='{"myVal":1}'> 
Bernhard dict_keys(['x']) None 

3.5.2 (v3.5.2:4def2a2901a5, Jun 26 2016, 10:47:25) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] 
Marius  dict_keys(['x']) None 
Jonathan dict_keys(['x', 'json', 'y']) <Morsel: json="{\"myVal\":1}"> 
Bernhard dict_keys(['x']) None 

La version de 3.3 .6 était apparemment une solution de sécurité; voir this bug report. Cela a également été appliquée à 3.2.6, donc:

3.2.4 (default, Jul 7 2016, 11:05:33) 
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.72)] 
Marius  dict_keys(['y', 'x', 'json']) <Morsel: json='json.dumps({'> 
Jonathan dict_keys(['y', 'x', 'json']) <Morsel: json='{"myVal":1}'> 
Bernhard dict_keys(['y', 'x', 'json']) <Morsel: json='{'> 

3.2.5 (default, Jul 7 2016, 11:07:15) 
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.72)] 
Marius  dict_keys(['y', 'x', 'json']) <Morsel: json='json.dumps({'> 
Jonathan dict_keys(['y', 'x', 'json']) <Morsel: json='{"myVal":1}'> 
Bernhard dict_keys(['y', 'x', 'json']) <Morsel: json='{'> 

# ...loses 'y'?! 

3.2.6 (default, Jul 7 2016, 11:09:00) 
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.72)] 
Marius  dict_keys(['x', 'json']) <Morsel: json='json.dumps({'> 
Jonathan dict_keys(['y', 'x', 'json']) <Morsel: json='{"myVal":1}'> 
Bernhard dict_keys(['x', 'json']) <Morsel: json='{'> 

Ce comportement est différent à 3.3.6 avec le même bugfix! En fait, il définit la valeur de json dans le cookie à '{', en supprimant le reste de cette valeur et y.

Je conclus que:

  1. ma version est plus largement applicable;
  2. La version de Marius n'aide pas réellement l'OP, car elle a les mêmes clés que leur version originale; et
  3. quelque chose d'étrange se produisait avec cette fonctionnalité en 3.2 et 3.3!
0

Cela inclut 'json' comme clé en Python 3.3.2 et versions antérieures:

>>> import json 
>>> from http.cookies import SimpleCookie 
>>> cookie = SimpleCookie('x=1; json=json.dumps({"myVal":1}); y=2') 
>>> cookie.keys() 
dict_keys(['y', 'x', 'json']) 

Cependant, la valeur ne peut pas être comme prévu:

>>> print(cookie) 
Set-Cookie: json=json.dumps({ 
Set-Cookie: x=1 
Set-Cookie: y=2 
+0

Vous avez raison: je devrais avoir ajouté la ligne json d'importation. J'ai testé cela et la sortie est correcte. –

+0

J'utilise Python 3.3.2 version –

+0

http: //labs.codecademy.com/DX3H #: workspace <- Preuve que ce code fonctionne pour certaines versions de Python –