1

I'm reading through some of Werkzeug's source and stumbled upon this nugget in the werkzeug.wrappers module.

def _run_wsgi_app(*args):
    """This function replaces itself to ensure that the test module is not
    imported unless required.  DO NOT USE!
    """
    global _run_wsgi_app
    from werkzeug.test import run_wsgi_app as _run_wsgi_app
    return _run_wsgi_app(*args)

What are the fine prints of doing something like this? What's the difference between this definition and another without the global _run_wsgi_app statement?

Michael Ekoka
  • 19,050
  • 12
  • 78
  • 79
  • The `import` statement binds to a name too; in this function the `from werkzeug.test import run_wsgi_app as _run_wsgi_app` would bind to a local name, except for the `global` making the import bind a global name instead. – Martijn Pieters Feb 24 '14 at 17:41

1 Answers1

3

If you go without the global statement, you will be creating a local variable with the name _run_wsgi_app, and then will use it, but nothing will change in the global namespace. Using global _run_wsgi_app you ensure that you are re-binding the global name to the new function.

Remember the basic usage of global:

def foo():
    x = 2
def bar():
    global x
    x = 3

x = 1
print(x) # --> 1
foo()
print(x) # --> 1
bar()
print(x) # --> 3

Your example is the same, but instead of binding the name directly with name = ..., it does with from ... import ... as name.

An alternative way to redefine itself without global is to use the module object where it is contained.

def _run_wsgi_app(*args):
    from werkzeug.test import run_wsgi_app as new_run_wsgi_app
    import sys
    sys.modules[__name__]._run_wsgi_app = new_run_wsgi_app
    return new_run_wsgi_app(*args)
rodrigo
  • 94,151
  • 12
  • 143
  • 190