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