diff options
-rw-r--r-- | Include/pydebug.h | 1 | ||||
-rw-r--r-- | Include/pythonrun.h | 1 | ||||
-rw-r--r-- | Modules/main.c | 68 | ||||
-rw-r--r-- | Objects/complexobject.c | 23 | ||||
-rw-r--r-- | Objects/floatobject.c | 21 | ||||
-rw-r--r-- | Objects/intobject.c | 25 | ||||
-rw-r--r-- | Objects/longobject.c | 22 | ||||
-rw-r--r-- | Objects/object.c | 2 | ||||
-rw-r--r-- | Python/pythonrun.c | 8 |
9 files changed, 146 insertions, 25 deletions
diff --git a/Include/pydebug.h b/Include/pydebug.h index 32e1552..9ecd8a0 100644 --- a/Include/pydebug.h +++ b/Include/pydebug.h @@ -15,6 +15,7 @@ extern DL_IMPORT(int) Py_FrozenFlag; extern DL_IMPORT(int) Py_TabcheckFlag; extern DL_IMPORT(int) Py_UnicodeFlag; extern DL_IMPORT(int) Py_IgnoreEnvironmentFlag; +extern DL_IMPORT(int) Py_DivisionWarningFlag; /* this is a wrapper around getenv() that pays attention to Py_IgnoreEnvironmentFlag. It should be used for getting variables like diff --git a/Include/pythonrun.h b/Include/pythonrun.h index 6d3a6d8..3e00cde 100644 --- a/Include/pythonrun.h +++ b/Include/pythonrun.h @@ -33,6 +33,7 @@ DL_IMPORT(int) PyRun_AnyFileFlags(FILE *, char *, PyCompilerFlags *); DL_IMPORT(int) PyRun_AnyFileExFlags(FILE *, char *, int, PyCompilerFlags *); DL_IMPORT(int) PyRun_SimpleString(char *); +DL_IMPORT(int) PyRun_SimpleStringFlags(char *, PyCompilerFlags *); DL_IMPORT(int) PyRun_SimpleFile(FILE *, char *); DL_IMPORT(int) PyRun_SimpleFileEx(FILE *, char *, int); DL_IMPORT(int) PyRun_SimpleFileExFlags(FILE *, char *, int, PyCompilerFlags *); diff --git a/Modules/main.c b/Modules/main.c index ad2616d..7c368c7 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -2,6 +2,7 @@ #include "Python.h" #include "osdefs.h" +#include "compile.h" /* For CO_FUTURE_DIVISION */ #ifdef HAVE_UNISTD_H #include <unistd.h> @@ -28,7 +29,7 @@ static char **orig_argv; static int orig_argc; /* command line options */ -#define BASE_OPTS "c:diOSEtuUvxXhVW:" +#define BASE_OPTS "c:dD:EhiOStuUvVWxX:" #ifndef RISCOS #define PROGRAM_OPTS BASE_OPTS @@ -45,30 +46,33 @@ static char *usage_line = "usage: %s [option] ... [-c cmd | file | -] [arg] ...\n"; /* Long usage message, split into parts < 512 bytes */ -static char *usage_top = "\ +static char *usage_1 = "\ Options and arguments (and corresponding environment variables):\n\ +-c cmd : program passed in as string (terminates option list)\n\ -d : debug output from parser (also PYTHONDEBUG=x)\n\ +-D arg : division options: -Dold (default), -Dwarn, -Dnew\n\ +-E : ignore environment variables (such as PYTHONPATH)\n\ +-h : print this help message and exit\n\ +"; +static char *usage_2 = "\ -i : inspect interactively after running script, (also PYTHONINSPECT=x)\n\ and force prompts, even if stdin does not appear to be a terminal\n\ -O : optimize generated bytecode (a tad; also PYTHONOPTIMIZE=x)\n\ -OO : remove doc-strings in addition to the -O optimizations\n\ -S : don't imply 'import site' on initialization\n\ --E : ignore environment variables (such as PYTHONPATH)\n\ -t : issue warnings about inconsistent tab usage (-tt: issue errors)\n\ -"; -static char *usage_mid = "\ -u : unbuffered binary stdout and stderr (also PYTHONUNBUFFERED=x)\n\ +"; +static char *usage_3 = "\ -U : Unicode literals: treats '...' literals like u'...'\n\ -v : verbose (trace import statements) (also PYTHONVERBOSE=x)\n\ --x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\ --h : print this help message and exit\n\ -V : print the Python version number and exit\n\ -W arg : warning control (arg is action:message:category:module:lineno)\n\ --c cmd : program passed in as string (terminates option list)\n\ +-x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\ file : program read from script file\n\ - : program read from stdin (default; interactive mode if a tty)\n\ "; -static char *usage_bot = "\ +static char *usage_4 = "\ arg ...: arguments passed to program in sys.argv[1:]\n\ Other environment variables:\n\ PYTHONSTARTUP: file executed on interactive startup (no default)\n\ @@ -83,10 +87,17 @@ PYTHONCASEOK : ignore case in 'import' statements (Windows).\n\ static void usage(int exitcode, char* program) { - fprintf(stderr, usage_line, program); - fprintf(stderr, usage_top); - fprintf(stderr, usage_mid); - fprintf(stderr, usage_bot, DELIM, DELIM, PYTHONHOMEHELP); + FILE *f = exitcode ? stderr : stdout; + + fprintf(f, usage_line, program); + if (exitcode) + fprintf(f, "Try `python -h' for more information.\n"); + else { + fprintf(f, usage_1); + fprintf(f, usage_2); + fprintf(f, usage_3); + fprintf(f, usage_4, DELIM, DELIM, PYTHONHOMEHELP); + } exit(exitcode); /*NOTREACHED*/ } @@ -113,6 +124,8 @@ Py_Main(int argc, char **argv) int saw_unbuffered_flag = 0; PyCompilerFlags cf; + cf.cf_flags = 0; + orig_argc = argc; /* For Py_GetArgcArgv() */ orig_argv = argv; @@ -135,13 +148,33 @@ Py_Main(int argc, char **argv) strcat(command, "\n"); break; } - + switch (c) { case 'd': Py_DebugFlag++; break; + case 'D': + if (strcmp(_PyOS_optarg, "old") == 0) { + Py_DivisionWarningFlag = 0; + break; + } + if (strcmp(_PyOS_optarg, "warn") == 0) { + Py_DivisionWarningFlag++; + break; + } + if (strcmp(_PyOS_optarg, "new") == 0) { + /* XXX This only affects __main__ */ + cf.cf_flags |= CO_FUTURE_DIVISION; + break; + } + fprintf(stderr, + "-D option should be " + "`-Dold', `-Dwarn' or `-Dnew' only\n"); + usage(2, argv[0]); + /* NOTREACHED */ + case 'i': inspect++; saw_inspect_flag = 1; @@ -290,8 +323,7 @@ Py_Main(int argc, char **argv) (command == NULL && filename == NULL && stdin_is_interactive)) fprintf(stderr, "Python %s on %s\n%s\n", Py_GetVersion(), Py_GetPlatform(), COPYRIGHT); - - + if (command != NULL) { /* Backup _PyOS_optind and force sys.argv[0] = '-c' */ _PyOS_optind--; @@ -310,10 +342,8 @@ Py_Main(int argc, char **argv) Py_DECREF(v); } - cf.cf_flags = 0; - if (command) { - sts = PyRun_SimpleString(command) != 0; + sts = PyRun_SimpleStringFlags(command, &cf) != 0; free(command); } else { diff --git a/Objects/complexobject.c b/Objects/complexobject.c index cb081aa..281de13 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -373,6 +373,27 @@ complex_div(PyComplexObject *v, PyComplexObject *w) } static PyObject * +complex_classic_div(PyComplexObject *v, PyComplexObject *w) +{ + Py_complex quot; + + if (Py_DivisionWarningFlag && + PyErr_Warn(PyExc_DeprecationWarning, + "classic complex division") < 0) + return NULL; + + PyFPE_START_PROTECT("complex_classic_div", return 0) + errno = 0; + quot = c_quot(v->cval,w->cval); + PyFPE_END_PROTECT(quot) + if (errno == EDOM) { + PyErr_SetString(PyExc_ZeroDivisionError, "complex division"); + return NULL; + } + return PyComplex_FromCComplex(quot); +} + +static PyObject * complex_remainder(PyComplexObject *v, PyComplexObject *w) { Py_complex div, mod; @@ -854,7 +875,7 @@ static PyNumberMethods complex_as_number = { (binaryfunc)complex_add, /* nb_add */ (binaryfunc)complex_sub, /* nb_subtract */ (binaryfunc)complex_mul, /* nb_multiply */ - (binaryfunc)complex_div, /* nb_divide */ + (binaryfunc)complex_classic_div, /* nb_divide */ (binaryfunc)complex_remainder, /* nb_remainder */ (binaryfunc)complex_divmod, /* nb_divmod */ (ternaryfunc)complex_pow, /* nb_power */ diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 7eb2777..39eba8e 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -414,6 +414,25 @@ float_div(PyObject *v, PyObject *w) } static PyObject * +float_classic_div(PyObject *v, PyObject *w) +{ + double a,b; + CONVERT_TO_DOUBLE(v, a); + CONVERT_TO_DOUBLE(w, b); + if (Py_DivisionWarningFlag && + PyErr_Warn(PyExc_DeprecationWarning, "classic float division") < 0) + return NULL; + if (b == 0.0) { + PyErr_SetString(PyExc_ZeroDivisionError, "float division"); + return NULL; + } + PyFPE_START_PROTECT("divide", return 0) + a = a / b; + PyFPE_END_PROTECT(a) + return PyFloat_FromDouble(a); +} + +static PyObject * float_rem(PyObject *v, PyObject *w) { double vx, wx; @@ -677,7 +696,7 @@ static PyNumberMethods float_as_number = { (binaryfunc)float_add, /*nb_add*/ (binaryfunc)float_sub, /*nb_subtract*/ (binaryfunc)float_mul, /*nb_multiply*/ - (binaryfunc)float_div, /*nb_divide*/ + (binaryfunc)float_classic_div, /*nb_divide*/ (binaryfunc)float_rem, /*nb_remainder*/ (binaryfunc)float_divmod, /*nb_divmod*/ (ternaryfunc)float_pow, /*nb_power*/ diff --git a/Objects/intobject.c b/Objects/intobject.c index d1f241d..108e658 100644 --- a/Objects/intobject.c +++ b/Objects/intobject.c @@ -512,6 +512,27 @@ int_div(PyIntObject *x, PyIntObject *y) } static PyObject * +int_classic_div(PyIntObject *x, PyIntObject *y) +{ + long xi, yi; + long d, m; + CONVERT_TO_LONG(x, xi); + CONVERT_TO_LONG(y, yi); + if (Py_DivisionWarningFlag && + PyErr_Warn(PyExc_DeprecationWarning, "classic int division") < 0) + return NULL; + switch (i_divmod(xi, yi, &d, &m)) { + case DIVMOD_OK: + return PyInt_FromLong(d); + case DIVMOD_OVERFLOW: + return PyLong_Type.tp_as_number->nb_divide((PyObject *)x, + (PyObject *)y); + default: + return NULL; + } +} + +static PyObject * int_mod(PyIntObject *x, PyIntObject *y) { long xi, yi; @@ -744,7 +765,7 @@ int_or(PyIntObject *v, PyIntObject *w) static PyObject * int_true_divide(PyObject *v, PyObject *w) { - return PyFloat_Type.tp_as_number->nb_divide(v, w); + return PyFloat_Type.tp_as_number->nb_true_divide(v, w); } static PyObject * @@ -855,7 +876,7 @@ static PyNumberMethods int_as_number = { (binaryfunc)int_add, /*nb_add*/ (binaryfunc)int_sub, /*nb_subtract*/ (binaryfunc)int_mul, /*nb_multiply*/ - (binaryfunc)int_div, /*nb_divide*/ + (binaryfunc)int_classic_div, /*nb_divide*/ (binaryfunc)int_mod, /*nb_remainder*/ (binaryfunc)int_divmod, /*nb_divmod*/ (ternaryfunc)int_pow, /*nb_power*/ diff --git a/Objects/longobject.c b/Objects/longobject.c index 25d0377..4209419 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -1509,6 +1509,26 @@ long_div(PyObject *v, PyObject *w) } static PyObject * +long_classic_div(PyObject *v, PyObject *w) +{ + PyLongObject *a, *b, *div, *mod; + + CONVERT_BINOP(v, w, &a, &b); + + if (Py_DivisionWarningFlag && + PyErr_Warn(PyExc_DeprecationWarning, "classic long division") < 0) + div = NULL; + else if (l_divmod(a, b, &div, &mod) < 0) + div = NULL; + else + Py_DECREF(mod); + + Py_DECREF(a); + Py_DECREF(b); + return (PyObject *)div; +} + +static PyObject * long_mod(PyObject *v, PyObject *w) { PyLongObject *a, *b, *div, *mod; @@ -2115,7 +2135,7 @@ static PyNumberMethods long_as_number = { (binaryfunc) long_add, /*nb_add*/ (binaryfunc) long_sub, /*nb_subtract*/ (binaryfunc) long_mul, /*nb_multiply*/ - (binaryfunc) long_div, /*nb_divide*/ + (binaryfunc) long_classic_div, /*nb_divide*/ (binaryfunc) long_mod, /*nb_remainder*/ (binaryfunc) long_divmod, /*nb_divmod*/ (ternaryfunc) long_pow, /*nb_power*/ diff --git a/Objects/object.c b/Objects/object.c index 7b9e280..66b4eae 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -16,6 +16,8 @@ DL_IMPORT(long) _Py_RefTotal; #endif +DL_IMPORT(int) Py_DivisionWarningFlag; + /* Object allocation routines used by NEWOBJ and NEWVAROBJ macros. These are used by the individual routines for object creation. Do not call them otherwise, they do not initialize the object! */ diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 621ce9d..8dd9c14 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -687,12 +687,18 @@ PyRun_SimpleFileExFlags(FILE *fp, char *filename, int closeit, int PyRun_SimpleString(char *command) { + return PyRun_SimpleStringFlags(command, NULL); +} + +int +PyRun_SimpleStringFlags(char *command, PyCompilerFlags *flags) +{ PyObject *m, *d, *v; m = PyImport_AddModule("__main__"); if (m == NULL) return -1; d = PyModule_GetDict(m); - v = PyRun_String(command, Py_file_input, d, d); + v = PyRun_StringFlags(command, Py_file_input, d, d, flags); if (v == NULL) { PyErr_Print(); return -1; |