summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Include/pydebug.h1
-rw-r--r--Include/pythonrun.h1
-rw-r--r--Modules/main.c68
-rw-r--r--Objects/complexobject.c23
-rw-r--r--Objects/floatobject.c21
-rw-r--r--Objects/intobject.c25
-rw-r--r--Objects/longobject.c22
-rw-r--r--Objects/object.c2
-rw-r--r--Python/pythonrun.c8
9 files changed, 146 insertions, 25 deletions
diff --git a/Include/pydebug.h b/Include/pydebug.h
index 32e15520da..9ecd8a00d2 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 6d3a6d8ee5..3e00cde62a 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 ad2616da04..7c368c7e36 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 cb081aac7b..281de13254 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 7eb27776f9..39eba8ebd6 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 d1f241d7ed..108e658755 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 25d0377528..42094190e4 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 7b9e280d75..66b4eae2b2 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 621ce9d3a2..8dd9c14c3b 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;