0

I want to make a docstring for my router module in gae. I also know it must be the first thing in the module (after the file encoding type).

The thing is, if you run this module alone you get nothing but an import error (No module named webapp2). What I wanted is to print the docstring when running just the file but this import error just don't let me. Is there any way to do this?

I tried:

if __name__ == "__main__":
    print help(self)

And other combinations, but no success.

[EDIT]

No specific code. Could be appengine's example:

# coding: utf-8
""" docstring """

import webapp2

class MainPage(webapp2.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'text/plain'
        self.response.out.write('Hello, webapp World!')

app = webapp2.WSGIApplication([('/', MainPage)],
                              debug=True)
Harshal Patil
  • 6,284
  • 8
  • 37
  • 55
marcelocra
  • 1,614
  • 2
  • 21
  • 32

1 Answers1

1

The ImportError happens when you run it as a standalone because it won't include any of the 'magic' that is included when run as an app. For instance, if you look at dev_appserver.py (just the basic one you use to run a dev server), you'll see this function:

def fix_sys_path(extra_extra_paths=()):
  """Fix the sys.path to include our extra paths."""
  extra_paths = EXTRA_PATHS[:]
  extra_paths.extend(extra_extra_paths)
  sys.path = extra_paths + sys.path

Here you can see that sys.path is being modified to include some 'extra' paths, and if we take a look at one of them, you'll see webapp2 (as well as additional libraries provided in the SDK):

EXTRA_PATHS = [
  # ...other similar setups...
  os.path.join(DIR_PATH, 'lib', 'webapp2'),
  # ...other similar setups...
]

You can see GAE is performing some additional steps behind the scenes to let you say import webapp2 without issue. Therefore when you try to run it on its own, you will get that error because your system is just checking the standard paths for webapp2 (which you likely don't have installed).

And that doesn't really answer your question at all :) As for that, I'm sure there are definitely more elegant/appropriate ways of handling this, but one thing you could try is wrapping your import(s) in a try/except block and on ImportError, checking if you're running the module directly. If so, call the module docstring and exit. Note this is just an example - you would want to make this more refined if you were to actually use it:

"""Module information."""
import sys

try:
    import webapp2
except ImportError:
    if __name__ == '__main__':
        print __doc__
    else:
        print 'Webapp2 not found'
    sys.exit(1)


class MainPage(webapp2.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'text/plain'
        self.response.out.write('Hello, webapp World!')

app = webapp2.WSGIApplication([('/', MainPage)],
                              debug=True)

This will print Module information if you run it directly.

RocketDonkey
  • 33,047
  • 7
  • 75
  • 83
  • Now I understand why it doesn't work. And the solution also worked well. Thinking about the problem, maybe it doesn't make sense to print this information, once the programmer is already looking at it. If, instead, he wanted to import the file and then use the help() function, he would get to the `else` part, not to the docstring. Maybe there is another way, but I guess I'll leave to the programmer to read it (leaving the code cleaner). Thanks a lot for the answer! =D – marcelocra Jan 06 '13 at 04:53
  • @infostacker No problemo :) And yeah, unless it is something that is meant to be run on its own, you're probably fine not trying to account for that kind of behavior. As 'justification' for this, try going into the `./google_appengine/google/appengine/api` folder and running one of those on its own (`users.py`, for example) - you'll get a very similar import error. I agree with your approach - if they are at the point where they are digging around the code, let them read it :) – RocketDonkey Jan 06 '13 at 05:05