MongoEngine / flask-mongoengine

MongoEngine flask extension with WTF model forms support
Other
840 stars 255 forks source link

Storing dictionaries with MongoEngineSessionInterface #196

Open lafrech opened 8 years ago

lafrech commented 8 years ago

I posted this as a question on SO: http://stackoverflow.com/questions/35068300/ and was answered it may be a bug, so here it is:

In a request, I set a dictionary in session['test']:

session['test'] = {'test': {'test': {'test':0}}}

Next iteration, session is read back from MongoDB, but the dict has become a <class 'mongoengine.base.datastructures.BaseDict'> which is immutable. Trying to modify it raises

ReferenceError: weakly-referenced object no longer exists

I can cast to a dict but it is not recursive.

print(type(session['test']))
print(type(session['test']['test']))
print(type(session['test']['test']['test']))

test = dict(session['test'])
print(type(test))
print(type(test['test']))
print(type(test['test']['test']))

prints

<class 'mongoengine.base.datastructures.BaseDict'>
<class 'mongoengine.base.datastructures.BaseDict'>
<class 'mongoengine.base.datastructures.BaseDict'>
<class 'dict'>
<class 'mongoengine.base.datastructures.BaseDict'>
<class 'mongoengine.base.datastructures.BaseDict'>

This does not happen with cookie session storage.

The point is I can read or replace a key in session but I can't modify it anymore.

Steve Rossiter said:

Some garbage collection is going on between requests and the BaseDict instances that are created get destroyed but the references live on because BaseDict uses weakref.proxy. Then when you call BaseDict.setitem the exception is thrown. This might be something that can be fixed inside flask-mongoengine if you file an issue.

lafrech commented 8 years ago

Considering this a bug. I shall add a test and see if this can be solved.