When is it better to use value comparison instead of identify comparison when checking if a string is unicode?

StackOverflow https://stackoverflow.com/questions/19289110

Pregunta

The origin of this question is the flask tutorial at http://blog.miguelgrinberg.com/post/designing-a-restful-api-with-python-and-flask. While reading this tutorial, I came across this function:

@app.route('/todo/api/v1.0/tasks/<int:task_id>', methods = ['PUT'])
def update_task(task_id):
    task = filter(lambda t: t['id'] == task_id, tasks)
    if len(task) == 0:
        abort(404)
    if not request.json:
        abort(400)
    if 'title' in request.json and type(request.json['title']) != unicode:
        abort(400)
    if 'description' in request.json and type(request.json['description']) is not unicode:
        abort(400)
    if 'done' in request.json and type(request.json['done']) is not bool:
        abort(400)
    task[0]['title'] = request.json.get('title', task[0]['title'])
    task[0]['description'] = request.json.get('description', task[0]['description'])
    task[0]['done'] = request.json.get('done', task[0]['done'])
    return jsonify( { 'task': task[0] } )

This line uses value comparison:

if 'title' in request.json and type(request.json['title']) != unicode:

But this line uses identity comparison:

if 'description' in request.json and type(request.json['description']) is not unicode:

Is there a reason that the author was not consistent? Will both versions provide the same level of security? If so, what is the more pythonic approach?

¿Fue útil?

Solución 2

I think better use json schema instead:

from jsonschema import validate, ValidationError

schema = {
    'type': 'object',
    'properties': {
        'title': {
            'type': 'string',
        },
        'description': {
            'type': 'string',
        },
        'done': {
            'type': 'boolean',
        },
    },
}

try:
    validate(request.get_json(), schema)
except ValidationError:
    abort(400)

Also request.json is deprecated if you use flask>=0.10, and better use request.get_json(): http://flask.pocoo.org/docs/api/#flask.Request.json.

Otros consejos

I would prefer this way:

if isinstance(request.json['title'], unicode):
    pass

Will both versions provide the same level of security? ->no

it is not a question of which one is more pythonic,it is a question of which level you want to compare at. consider this and you will know the answer yourself:

>>> a = 1
>>> b = 1.0
>>> a is b
False
>>> a == b
True
>>> id(a)
12777000
>>> id(b)
14986000
>>> a = 1
>>> b = 1
>>> a is b
True
>>> a == b
True
>>> id(a)
12777000
>>> id(b)
12777000

but note this :

>>> a=1000
>>> b=1000
>>> a is b
False

>>> a='good'
>>> b='good'
>>> a is b
True
>>> a='啊'
>>> b='啊'
>>> a is b
False
>>> a==b
True

the reason is the notion of buffer pool. So,when you want to compare value,'=' and '!=' is safer

when id,'is' and 'is not' is safer(but do note the buffer pool)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top