joerussbowman / gaeutilities

gaeutilities - A collection of utilities to help with application development on Google Appengine
http://gaeutilities.appspot.com
BSD 3-Clause "New" or "Revised" License
78 stars 4 forks source link

Session breaks NoseGAE #6

Closed bdoms closed 14 years ago

bdoms commented 14 years ago

With version 1.2.7 of GAE, version 1.3 of GAEUtils, and version 0.1.4 of NoseGAE, trying to run "nosetests --with-gae" produces this error (pertinent stack trace below):

File "google_appengine/google/appengine/tools/dev_appserver.py", line 1665, in LoadModuleRestricted
description)
ImportError: Cannot re-init internal module __main__

This is caused by line 37 of sessions.py:

import __main__

This conflict was previously reported to NoseGAE (http://code.google.com/p/nose-gae/issues/detail?id=15) with different versions of the libraries and including another more complete stack trace, but they marked it as won't fix. I'm hoping that you guys might have a better idea as to how to potentially fix this issue. It'd be really cool if both of these projects could be used simultaneously.

Here's the interesting part of the stack trace I got:

[in a controller file]
from gaeutils import sessions
File "build/bdist.linux-x86_64/egg/nosegae.py", line 173, in load_module
return super(HookMixin, self).load_module(fullname)
File "google_appengine/google/appengine/tools/dev_appserver.py", line 1163, in Decorate
return func(self, *args, **kwargs)
File "google_appengine/google/appengine/tools/dev_appserver.py", line 1812, in load_module
return self.FindAndLoadModule(submodule, fullname, search_path)
File "google_appengine/google/appengine/tools/dev_appserver.py", line 1163, in Decorate
return func(self, *args, **kwargs)
File "google_appengine/google/appengine/tools/dev_appserver.py", line 1714, in FindAndLoadModule
description)
File "google_appengine/google/appengine/tools/dev_appserver.py", line 1163, in Decorate
return func(self, *args, **kwargs)
File "google_appengine/google/appengine/tools/dev_appserver.py", line 1665, in LoadModuleRestricted
description)
File "app/gaeutils/sessions.py", line 37, in <module>
import __main__
File "build/bdist.linux-x86_64/egg/nosegae.py", line 173, in load_module
return super(HookMixin, self).load_module(fullname)
File "google_appengine/google/appengine/tools/dev_appserver.py", line 1163, in Decorate
return func(self, *args, **kwargs)
File "google_appengine/google/appengine/tools/dev_appserver.py", line 1812, in load_module
return self.FindAndLoadModule(submodule, fullname, search_path)
File "google_appengine/google/appengine/tools/dev_appserver.py", line 1163, in Decorate
return func(self, *args, **kwargs)
File "google_appengine/google/appengine/tools/dev_appserver.py", line 1714, in FindAndLoadModule
description)
File "google_appengine/google/appengine/tools/dev_appserver.py", line 1163, in Decorate
return func(self, *args, **kwargs)
File "google_appengine/google/appengine/tools/dev_appserver.py", line 1665, in LoadModuleRestricted
description)
ImportError: Cannot re-init internal module __main__
joerussbowman commented 14 years ago

Probably NoseGAE is doing something similar to Event, where main is loaded in order to insert itself. GAEUtilities currently isn't under any active development by myself, though if someone wishes to make a patch to make these projects work together, I'd be happy to apply it.

bdoms commented 14 years ago

There are two options for patching this. I have tried both, and they both appear to work with NoseGAE and not mess with anything GAEUtils is trying to do, but just a warning that I have probably not tested them all that rigorously.

Both of these are applied to the 1.3 release version of sessions.py. I couldn't figure out how to attach files, so I'm just pasting them in here.

The first option is to simply move the import to inside the method:

37d36
< import __main__
723a723
>         import __main__

The second is to access the main module through sys, rather than importing it:

37c37
< import __main__
---
> import sys
723a724
>         main_module = sys.modules['__main__']
725,726c726,727
<         if u"AEU_Events" in __main__.__dict__:
<             __main__.AEU_Events.fire_event(u"preSessionDelete")
---
>         if u"AEU_Events" in main_module.__dict__:
>             main_module.AEU_Events.fire_event(u"preSessionDelete")
735,736c736,737
<         if u"AEU_Events" in __main__.__dict__:
<             __main__.AEU_Events.fire_event(u"sessionDelete")
---
>         if u"AEU_Events" in main_module.__dict__:
>             main_module.AEU_Events.fire_event(u"sessionDelete")

So I'll leave it up to you to decide, but my gut is just to do the first, simpler one, unless it would cause some issue I'm not taking into account (is there some negative performance associated with importing it there every time?)

joerussbowman commented 14 years ago

Thanks for the patch, I went with option 2 as it helps keep the code more readable. I also did this not just in session, but in event and cache. It's been checked in to the master copy, if you can test it out and let me know how well it works, I'll see about a maintenance release in the next few days to get this and issue #5 out as a release.

bdoms commented 14 years ago

I've been developing with the master copy for a day or two now and everything seems to be behaving as expected with this change. Before you push out a release I would suggest taking a quick look at issue #7, which I just reported.

joerussbowman commented 14 years ago

OK, thanks for your effort on this as well. Closing this issue as it's resolved.