Issue 1877: unhelpful error when calling "python " (original) (raw)

Created on 2008-01-20 14:48 by georg.brandl, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Messages (13)
msg61303 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2008-01-20 14:48
gbr@lap ~/devel/python> ./python Lib Traceback (most recent call last): File "Lib/runpy.py", line 99, in _run_module_as_main loader, code, fname = _get_module_details(mod_name) File "Lib/runpy.py", line 86, in _get_module_details raise ImportError("No code object available for %s" % mod_name) ImportError: No code object available for __main__
msg61359 - (view) Author: Alyssa Coghlan (ncoghlan) * (Python committer) Date: 2008-01-20 20:38
In what sense is this being flagged as easy? All the runpy code knows at this point is that it asked the import system for the __main__ module's code object and didn't get one. __main__ always exists, so the module is definitely able to be found - working out after the fact why the code object can't be provided isn't the simplest thing in the world. For example, "./python -m sys" triggers a similar error message. Or are you merely suggesting the addition of something like "(e.g. directory or zipfile does not contain __main__.py)" to the current error message when the requested module is "__main__"?
msg61360 - (view) Author: Georg Brandl (georg.brandl) * (Python committer) Date: 2008-01-20 20:40
No idea about the "easy" -- I haven't really looked at the code, but amending the error message would be a good thing.
msg61361 - (view) Author: Alyssa Coghlan (ncoghlan) * (Python committer) Date: 2008-01-20 21:03
I removed the easy tag. I'll try to come up with some ideas for making the error message more helpful without making it misleading.
msg62676 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2008-02-22 04:08
Actually, a very simple change restores python2.5 behavior: =================================================================== --- Modules/main.c (revision 60941) +++ Modules/main.c (working copy) @@ -187,6 +187,7 @@ if ((argv0 = PyString_FromString(filename)) && (importer = PyImport_GetImporter(argv0)) && + (importer != Py_None) && (importer->ob_type != &PyNullImporter_Type)) { /* argv0 is usable as an import source, so $ ./python.exe . ./python.exe: '.' is a directory, cannot continue $ ./python.exe abc ./python.exe: can't open file 'abc': [Errno 2] No such file or directory I'm not sure, however that PyImport_GetImporter is behaving correctly in this case. (For one, it should INCREF Py_None before returning it.) I could not find any documentation for PyImport_GetImporter. Can someone enlighten me what Py_None (instead of NULL) return from yImport_GetImporter signifies?
msg62677 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2008-02-22 05:11
I have found relevant documentation in a comment preceding get_path_importer definition: ... traverse path_hooks until a hook is found that can handle the path item. Return None if no hook could; this tells our caller it should fall back to the builtin import mechanism. Therefore, Py_None return is legitimate and should be handled the way I suggested in my previous message. The same comment explains that get_path_importer "Returns a borrowed reference," so my criticism of return Py_None was misplaced. I will submit a documentation patch adding PyImport_GetImporter documentation.
msg62680 - (view) Author: Alyssa Coghlan (ncoghlan) * (Python committer) Date: 2008-02-22 08:39
We don't want to restore Python 2.5 behaviour - directories containing a __main__.py file are meant to be executable in 2.6. With your proposed change test_cmd_line_script will fail its directory execution tests (since those rely on the default importer to find the code for __main__). Georg is rightly complaining about the way that the implementation details leak through in the error message when __main__ isn't found. It makes perfect sense to me, but anyone that isn't intimately familiar with the import system is going to be left scratching their heads and wondering what is going on. I'm currently pondering an approach that involves trapping the ImportError in _run_module_as_main and displaying different error messages based on whether or not the module being looked for is called __main__, and whether or not sys.argv[0] is a directory.
msg62683 - (view) Author: Alyssa Coghlan (ncoghlan) * (Python committer) Date: 2008-02-22 11:01
I've checked in friendlier error messages as r60955 Examples (paths somewhat redacted): $ ./python bob ./python: can't open file 'bob': [Errno 2] No such file or directory $ ./python . /devel/python/python: can't find '__main__.py' in '.' $ ./python Lib /devel/python/python: can't find '__main__.py' in 'Lib' $ ./python -m bob /devel/python/python: No module named bob $ ./python -m sys /devel/python/python: No code object available for sys $ ./python -m __main__ /devel/python/python: No code object available for __main__
msg62690 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2008-02-22 15:39
Nick, I understand the __main__.py issue now, but I still don't like your approach. Allowing RunMainFromImporter to call exit and never return does not feel right. (A minor problem is that objects on the C stack do not get deleted.) Without a check for Py_None return, the comment "argv0 is usable as an import source" is misleading.
msg62694 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2008-02-22 17:38
I think a more elegant solution will be possible if patch is accepted. I suggest to reopen this issue for Py3k pending resolution of .
msg62713 - (view) Author: Alyssa Coghlan (ncoghlan) * (Python committer) Date: 2008-02-23 02:12
If main.c doesn't handle sys.exit() correctly for code run via RunMainFromImporter, then that's a problem with the main function - it will happen regardless of whether it is runpy.py or application code that calls sys.exit. But as far as I can tell, it handles it just fine - the SystemExit exception is converted to an error return from PyObject_Call, which then flows back up the C stack as an error return from each relevant function call in main.c (until it gets back to the shell with a non-zero return code from the main function). And I don't understand your complaint about the Py_None return conflicting with the comment on that if statement: PyImport_GetImporter will return Py_None for a directory name, as directories are handled by the builtin machinery. If PyImport_GetImporter fails completely it will return NULL - if the function returns anything else, then PyImport thinks the passed in string is a legitimate sys.path entry (i.e. usable as an import source). The *only* difference (or Brett's import_in_py branch) would make to any of this is that PyImport_GetImporter won't return Py_None anymore. In either case, the additional try/except in runpy would still be necessary in order to intercept the ImportError when looking for the module to be executed and convert it to something a bit more explicit.
msg62717 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2008-02-23 03:07
Nick, you are right about sys.exit(). I did to much C programming lately and forgot that sys.exit() does not exit. :-) I understood your comment as saying that 'importer' points to a valid importer. Now I understand that with the present state of the code, that would only be the case when running a zip file. Now it all makes sense. I still wonder if the case of a bona fide importer could be handled without a sys.path mutating trick by simply calling importer- >find_module.
msg62718 - (view) Author: Alyssa Coghlan (ncoghlan) * (Python committer) Date: 2008-02-23 05:49
The mutation of sys.path is deliberate - the use case is to allow the interpreter to execute a zipfile directly and have access to all of the Python modules and packages bundled along with __main__.py. Supporting execution of directories as well makes it much easier to test your application before bundling it that way (since you can test with the directory till it works, zip the directory, test with the zipfile, then distribute it). You can find more details on this feature in issue 1739468
History
Date User Action Args
2022-04-11 14:56:29 admin set github: 46185
2011-11-29 06:26:02 eric.snow set nosy: + eric.snow
2008-02-23 05:49:07 ncoghlan set messages: +
2008-02-23 03:07:27 belopolsky set messages: +
2008-02-23 02:12:34 ncoghlan set messages: +
2008-02-22 17:38:03 belopolsky set messages: +
2008-02-22 15:39:08 belopolsky set messages: +
2008-02-22 11:01:14 ncoghlan set status: open -> closedresolution: fixedmessages: +
2008-02-22 08:39:50 ncoghlan set messages: +
2008-02-22 05:11:17 belopolsky set messages: +
2008-02-22 04:08:05 belopolsky set nosy: + belopolskymessages: +
2008-01-20 21:03:10 ncoghlan set messages: +
2008-01-20 20:40:48 georg.brandl set messages: +
2008-01-20 20:38:31 ncoghlan set messages: +
2008-01-20 14:49:37 christian.heimes set priority: normalkeywords: + easytype: behaviorcomponents: + Library (Lib)versions: + Python 2.6, Python 3.0
2008-01-20 14:48:07 georg.brandl create