This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: unhelpful error when calling "python "
Type: behavior Stage:
Components: Library (Lib) Versions: Python 3.0, Python 2.6
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: ncoghlan Nosy List: belopolsky, eric.snow, georg.brandl, ncoghlan
Priority: normal Keywords: easy

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: Nick 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: Nick 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: Nick 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: Nick 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 issue2135 patch is 
accepted.  I suggest to reopen this issue for Py3k pending resolution of issue2135.
msg62713 - (view) Author: Nick 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 issue3125 (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: Nick 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:29adminsetgithub: 46185
2011-11-29 06:26:02eric.snowsetnosy: + eric.snow
2008-02-23 05:49:07ncoghlansetmessages: + msg62718
2008-02-23 03:07:27belopolskysetmessages: + msg62717
2008-02-23 02:12:34ncoghlansetmessages: + msg62713
2008-02-22 17:38:03belopolskysetmessages: + msg62694
2008-02-22 15:39:08belopolskysetmessages: + msg62690
2008-02-22 11:01:14ncoghlansetstatus: open -> closed
resolution: fixed
messages: + msg62683
2008-02-22 08:39:50ncoghlansetmessages: + msg62680
2008-02-22 05:11:17belopolskysetmessages: + msg62677
2008-02-22 04:08:05belopolskysetnosy: + belopolsky
messages: + msg62676
2008-01-20 21:03:10ncoghlansetmessages: + msg61361
2008-01-20 20:40:48georg.brandlsetmessages: + msg61360
2008-01-20 20:38:31ncoghlansetmessages: + msg61359
2008-01-20 14:49:37christian.heimessetpriority: normal
keywords: + easy
type: behavior
components: + Library (Lib)
versions: + Python 2.6, Python 3.0
2008-01-20 14:48:07georg.brandlcreate