Created on 2008-05-04 00:36 by benjamin.peterson, last changed 2009-07-10 09:08 by ncoghlan. This issue is now closed.
|msg66184 - (view)||Author: Benjamin Peterson (benjamin.peterson) *||Date: 2008-05-04 00:36|
If I have a package like this: pack/ __init__.py and __init__.py looks like this if __name__ == "__main__": print "Spam" python -m pack gives one is a package and cannot be directly executed This is regression from 2.5 where "Spam" would be printed.
|msg66189 - (view)||Author: Nick Coghlan (ncoghlan) *||Date: 2008-05-04 04:34|
The ability to execute packages was never intended, since doing so breaks imports in a variety of subtle ways. It was actually a bug in 2.5 that it was permitted at all, so 2.6 not only disabled it again, but also added a test to make sure it stays disabled (2.4 correctly rejected it with an ImportError, just as 2.6 does). Here's the relevant svn log entry: r56509 | nick.coghlan | 2007-07-23 23:41:45 +1000 (Mon, 23 Jul 2007) | 5 lines Correctly cleanup sys.modules after executing runpy relative import tests Restore Python 2.4 ImportError when attempting to execute a package (as imports cannot be guaranteed to work properly if you try it)
|msg74678 - (view)||Author: Nick Coghlan (ncoghlan) *||Date: 2008-10-13 09:20|
(Adding some additional details regarding the reasons why this became an error again in 2.6) The ImportError when attempting to execute a package was lost during the conversion from the C-based implementation in 2.4 to the runpy module based implementation as part of 2.5. Packages really aren't meant to be executable with -m - it gets messy since__init__ is able to modify the way module lookups work within the package, and there are various other package specific details related to relative imports that don't apply when dealing with normal modules. That said, executing "-m pkg.__init__" with Python 2.6 will generally have the same effect as doing "-m pkg" with Python 2.5 (it keeps the import machinery happy since the package gets imported normally first, and so long as pkg.__init__ can cope with being first imported normally for the package initialisation and then run as '__main__' it should also work as a script). Anyone that would like to see the ability to execute packages restored should feel free to create a RFE issue for it, but it would take a fairly detailed analysis of the import system to convince me that doing so doesn't break any of the interpreter internals.
|msg90370 - (view)||Author: Rene Dudfield (illume)||Date: 2009-07-10 02:52|
Hi, note -m on packages still works with python3.0 and python3.1. It works by allowing a __main__.py file that gets called by -m. This is a really annoying regression for python2.6. It's a fairly wide spread feature too. I can't see any PEP for why this regression exists. For pygame we will probably work around it by using "python -m tests.main" or "python -m pygame.tests.run" which is ugly, but at least it'll work! cheers,
|msg90372 - (view)||Author: Nick Coghlan (ncoghlan) *||Date: 2009-07-10 03:30|
It doesn't work in 2.6 or 3.0 because, as stated above, it was only due to a bug that it even appeared to work at all in 2.5 (it was always meant to be disallowed because it puts dodgy data in the import machinery's internal records if you do it). It took a new feature (looking for a __main__ module as described in issue 4195 and as you already noted) to make it actually work properly for 3.1 (and 2.7 when that is released).
|msg90375 - (view)||Author: Rene Dudfield (illume)||Date: 2009-07-10 05:21|
hello, thanks for the explanation of why it's that way. Any ideas of a work around? python2.5 has been out for ages now. Even if it was an accident, it's the behavior people expect, and it's still a regression. Also, why should it matter if a module is a package or a module? Note how pygame.tests has a type of module, and not of package: >>> import pygame.tests >>> type(pygame.tests) <type 'module'> Even though it is a package, python calls its type a module. This has been true for a long time (at least as far back as python2.3). Because it's a regression, I think this bug should be reopened. To illustrate why it causes problems, here is part of the documentation mentioning the __main__. """ You can do a self test with: python -m pygame.tests Or with python2.6 do: python -m pygame.tests.__main__ See a list of examples... python -m pygame.examples Or with python2.6, python -m pygame.examples.__main__ """ It's twice as long, and I doubt anyone will remember the __main__ part. People used to running their programs with -m now have broken programs with python2.6. Having said all that, maybe there is a work around... One work around might be to make it into a module-module, not a package-module. Then have the module-module load the package-module into its namespace. I haven't tested that yet, but it might work. Will have to go through a round of testing to see how that works out. Will write back when I've found out the issues with that approach. cheers,
|msg90380 - (view)||Author: Nick Coghlan (ncoghlan) *||Date: 2009-07-10 09:07|
If you need to support Python 2.6 as well as 3.1, the simplest thing to do is just tell people to run "pygame.tests.main" always (i.e. completely skip the idea of executing the package directly and always run a submodule instead). The reason the distinction between packages and modules matters is that the import system has to do more bookkeeping for packages (since they can contain modules and subpackages). Direct execution of packages was meant to be disallowed because the Python 2.5 accident means the __init__ module runs without that extra bookkeeping having been set up properly, which can lead to a broken import system. Unfortunately, the relevant error message was lost for 2.5 in a refactoring that merged duplicated code from a couple of different parts of the standard library. I added Barry to the nosy list as the 2.6 release manager. I'm reluctant to re-enable a known-broken behaviour at all, but if Barry thinks it would be worthwhile downgrading this to a DeprecationWarning rather than an outright error in the next 2.6 maintenance then I would be willing to do that. That would still leave you with people getting a warning though, so I don't think it would be that much of a gain in practice.
messages: + msg90380
|2009-07-10 05:21:41||illume||set||messages: + msg90375|
|2009-07-10 03:30:52||ncoghlan||set||messages: + msg90372|
messages: + msg90370
|2008-10-13 09:20:14||ncoghlan||set||messages: + msg74678|
|2008-05-04 04:34:26||ncoghlan||set||status: open -> closed|
messages: + msg66189
|2008-05-04 00:40:15||benjamin.peterson||set||assignee: ncoghlan|
nosy: + ncoghlan