[Python-ideas] breaking out of module execution
Stefan Behnel
stefan_ml at behnel.de
Fri Apr 27 09:05:26 CEST 2012
Eric Snow, 24.04.2012 21:23:
> In a function you can use a return statement to break out of execution
> in the middle of the function. With modules you have no recourse.
> This is akin to return statements being allowed only at the end of a
> function.
>
> There are a small number of ways you can work around this, but they
> aren't great. This includes using wrapper modules or import hooks or
> sometimes from-import-*. Otherwise, if your module's execution is
> conditional, you end up indenting everything inside an if/else
> statement.
>
> Proposal: introduce a non-error mechanism to break out of module
> execution. This could be satisfied by a statement like break or
> return, though those specific ones could be confusing. It could also
> involve raising a special subclass of ImportError that the import
> machinery simply handles as not-an-error.
>
> This came up last year on python-list with mixed results. [1]
> However, time has not dimmed the appeal for me so I'm rebooting here.
>
> While the proposal seems relatively minor, the use cases are not
> extensive. <wink> The three main ones I've encountered are these:
>
> 1. C extension module with fallback to pure Python:
>
> try:
> from _extension_module import *
> except ImportError:
> pass
> else:
> break # or whatever color the bikeshed is
>
> # pure python implementation goes here
>
> 2. module imported under different name:
>
> if __name__ != "expected_name":
> from expected_name import *
> break
>
> # business as usual
>
> 3. module already imported under a different name:
>
> if "other_module" in sys.modules:
> exec("from other_module import *", globals())
> break
>
> # module code here
>
> Thoughts?
Without having read through the thread, I think that code that needs this
is just badly structured. All of the above cases can be fixed by moving the
code into a separate (and appropriately named) module and importing
conditionally from that.
I'm generally -1 on anything that would allow non-error code at an
arbitrary place further up in a module to prevent the non-indented module
code I'm looking at from being executed. Whether the result of that
execution makes it into the module API or not is a different question that
is commonly answered either by "__all__" at the very top of a module or by
the code at the very end of the module, not in between.
Stefan
More information about the Python-ideas
mailing list