Index: Doc/tut/tut.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tut/tut.tex,v retrieving revision 1.253 diff -c -r1.253 tut.tex *** Doc/tut/tut.tex 28 Sep 2004 16:12:50 -0000 1.253 --- Doc/tut/tut.tex 7 Oct 2004 03:28:53 -0000 *************** *** 205,210 **** --- 205,215 ---- or other characters that are special to the shell, it is best to quote \var{command} in its entirety with double quotes. + Some Python modules are also useful as scripts. These can be invoked using + \samp{\program{python} \programopt{-m} \var{module} [arg] ...}, which + executes the source file for \var{module} as if you had spelled out its + full name on the command line. + Note that there is a difference between \samp{python file} and \samp{python *************** *** 33,39 **** static int orig_argc; /* command line options */ ! #define BASE_OPTS "c:dEhiOQ:StuUvVW:xX" #ifndef RISCOS #define PROGRAM_OPTS BASE_OPTS --- 34,40 ---- static int orig_argc; /* command line options */ ! #define BASE_OPTS "c:dEhim:OQ:StuUvVW:xX" #ifndef RISCOS #define PROGRAM_OPTS BASE_OPTS *************** *** 47,53 **** /* Short usage message (with %s for argv0) */ static char *usage_line = ! "usage: %s [option] ... [-c cmd | file | -] [arg] ...\n"; /* Long usage message, split into parts < 512 bytes */ static char *usage_1 = "\ --- 48,54 ---- /* Short usage message (with %s for argv0) */ static char *usage_line = ! "usage: %s [option] ... [-c cmd | -m mod | file | -] [arg] ...\n"; /* Long usage message, split into parts < 512 bytes */ static char *usage_1 = "\ *************** *** 60,74 **** and force prompts, even if stdin does not appear to be a terminal\n\ "; static char *usage_2 = "\ -O : optimize generated bytecode (a tad; also PYTHONOPTIMIZE=x)\n\ -OO : remove doc-strings in addition to the -O optimizations\n\ -Q arg : division options: -Qold (default), -Qwarn, -Qwarnall, -Qnew\n\ -S : don't imply 'import site' on initialization\n\ -t : issue warnings about inconsistent tab usage (-tt: issue errors)\n\ -u : unbuffered binary stdout and stderr (also PYTHONUNBUFFERED=x)\n\ - see man page for details on internal buffering relating to '-u'\n\ "; static char *usage_3 = "\ -v : verbose (trace import statements) (also PYTHONVERBOSE=x)\n\ -V : print the Python version number and exit\n\ -W arg : warning control (arg is action:message:category:module:lineno)\n\ --- 61,76 ---- and force prompts, even if stdin does not appear to be a terminal\n\ "; static char *usage_2 = "\ + -m mod : run library module as a script (terminates option list)\n\ -O : optimize generated bytecode (a tad; also PYTHONOPTIMIZE=x)\n\ -OO : remove doc-strings in addition to the -O optimizations\n\ -Q arg : division options: -Qold (default), -Qwarn, -Qwarnall, -Qnew\n\ -S : don't imply 'import site' on initialization\n\ -t : issue warnings about inconsistent tab usage (-tt: issue errors)\n\ -u : unbuffered binary stdout and stderr (also PYTHONUNBUFFERED=x)\n\ "; static char *usage_3 = "\ + see man page for details on internal buffering relating to '-u'\n\ -v : verbose (trace import statements) (also PYTHONVERBOSE=x)\n\ -V : print the Python version number and exit\n\ -W arg : warning control (arg is action:message:category:module:lineno)\n\ *************** *** 130,135 **** --- 132,160 ---- } } + /* Get the path to a top-level module */ + static struct filedescr * FindModule(const char *module, + FILE **fp, char **filename) + { + struct filedescr *fdescr = NULL; + *fp = NULL; + *filename = malloc(MAXPATHLEN); + + if (!*filename) { + return NULL; + } + + /* Find the actual module source code */ + fdescr = _PyImport_FindModule(module, NULL, + *filename, MAXPATHLEN, fp, NULL); + + if (!fdescr) { + free(*filename); + *filename = NULL; + } + + return fdescr; + } /* Main program */ *************** *** 140,145 **** --- 165,171 ---- int sts; char *command = NULL; char *filename = NULL; + char *module = NULL; FILE *fp = stdin; char *p; int inspect = 0; *************** *** 177,182 **** --- 203,220 ---- break; } + if (c == 'm') { + /* -m is the last option; following arguments + that look like options are left for the + module to interpret. */ + module = malloc(strlen(_PyOS_optarg) + 1); + if (module == NULL) + Py_FatalError( + "not enough memory to copy -m argument"); + strcpy(module, _PyOS_optarg); + break; + } + switch (c) { case 'd': *************** *** 289,295 **** (p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0') unbuffered = 1; ! if (command == NULL && _PyOS_optind < argc && strcmp(argv[_PyOS_optind], "-") != 0) { #ifdef __VMS --- 327,333 ---- (p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0') unbuffered = 1; ! if (command == NULL && module == NULL && _PyOS_optind < argc && strcmp(argv[_PyOS_optind], "-") != 0) { #ifdef __VMS *************** *** 381,387 **** Py_Initialize(); if (Py_VerboseFlag || ! (command == NULL && filename == NULL && stdin_is_interactive)) { fprintf(stderr, "Python %s on %s\n", Py_GetVersion(), Py_GetPlatform()); if (!Py_NoSiteFlag) --- 419,425 ---- Py_Initialize(); if (Py_VerboseFlag || ! (command == NULL && filename == NULL && module == NULL && stdin_is_interactive)) { fprintf(stderr, "Python %s on %s\n", Py_GetVersion(), Py_GetPlatform()); if (!Py_NoSiteFlag) *************** *** 394,402 **** argv[_PyOS_optind] = "-c"; } PySys_SetArgv(argc-_PyOS_optind, argv+_PyOS_optind); ! if ((inspect || (command == NULL && filename == NULL)) && isatty(fileno(stdin))) { PyObject *v; v = PyImport_ImportModule("readline"); --- 432,465 ---- argv[_PyOS_optind] = "-c"; } + if (module != NULL) { + /* Backup _PyOS_optind and find the real file */ + _PyOS_optind--; + struct filedescr *fdescr = NULL; + if ((fdescr = FindModule(module, &fp, &filename))) { + argv[_PyOS_optind] = filename; + } else { + fprintf(stderr, "%s: module %s not found\n", + argv[0], module); + return 2; + } + if (!fp) { + fprintf(stderr, + "%s: module %s has no associated file\n", + argv[0], module); + return 2; + } + if (!_PyImport_IsScript(fdescr)) { + fprintf(stderr, + "%s: module %s not usable as script\n (%s)\n", + argv[0], module, filename); + return 2; + } + } + PySys_SetArgv(argc-_PyOS_optind, argv+_PyOS_optind); ! if ((inspect || (command == NULL && filename == NULL && module == NULL)) && isatty(fileno(stdin))) { PyObject *v; v = PyImport_ImportModule("readline"); *************** *** 409,414 **** --- 472,481 ---- if (command) { sts = PyRun_SimpleStringFlags(command, &cf) != 0; free(command); + } else if (module) { + sts = PyRun_AnyFileExFlags(fp, filename, 1, &cf) != 0; + free(module); + free(filename); } else { if (filename == NULL && stdin_is_interactive) { *************** *** 431,437 **** } if (inspect && stdin_is_interactive && ! (filename != NULL || command != NULL)) /* XXX */ sts = PyRun_AnyFileFlags(stdin, "", &cf) != 0; --- 498,504 ---- } if (inspect && stdin_is_interactive && ! (filename != NULL || command != NULL || module != NULL)) /* XXX */ sts = PyRun_AnyFileFlags(stdin, "", &cf) != 0; Index: Python/import.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/import.c,v retrieving revision 2.239 diff -c -r2.239 import.c *** Python/import.c 23 Sep 2004 04:37:36 -0000 2.239 --- Python/import.c 7 Oct 2004 03:28:55 -0000 *************** *** 1334,1339 **** --- 1334,1355 ---- return fdp; } + /* Helpers for main.c + * Find the source file corresponding to a named module + */ + struct filedescr * + _PyImport_FindModule(const char *name, PyObject *path, char *buf, + size_t buflen, FILE **p_fp, PyObject **p_loader) + { + return find_module((char *) name, (char *) name, path, + buf, buflen, p_fp, p_loader); + } + + PyAPI_FUNC(int) _PyImport_IsScript(struct filedescr * fd) + { + return fd->type == PY_SOURCE || fd->type == PY_COMPILED; + } + /* case_ok(char* buf, int len, int namelen, char* name) * The arguments here are tricky, best shown by example: * /a/b/c/d/e/f/g/h/i/j/k/some_long_module_name.py\0