diff -r 1267d64c14b3 -r 9430a5c65114 Doc/library/sys.rst --- a/Doc/library/sys.rst Thu Nov 01 14:52:03 2012 +0200 +++ b/Doc/library/sys.rst Thu Nov 01 14:02:56 2012 +0100 @@ -766,6 +766,15 @@ This is a dictionary that maps module names to modules which have already been loaded. This can be manipulated to force reloading of modules and other tricks. +.. data:: oom_fatal + + If this is true, Python will crash hard when an out of memory condition + occurs. This value is set to ``True`` or ``False`` depending on the ``-o`` + command line option and the ``PYTHONOOMFATAL`` environment variable. You can + not change this flag at runtime. + + .. versionadded:: 3.4 + .. data:: path diff -r 1267d64c14b3 -r 9430a5c65114 Include/pydebug.h --- a/Include/pydebug.h Thu Nov 01 14:52:03 2012 +0200 +++ b/Include/pydebug.h Thu Nov 01 14:02:56 2012 +0100 @@ -20,6 +20,7 @@ PyAPI_DATA(int) Py_NoUserSiteDirectory; PyAPI_DATA(int) Py_UnbufferedStdioFlag; PyAPI_DATA(int) Py_HashRandomizationFlag; +PyAPI_DATA(int) Py_OomFatalFlag; /* this is a wrapper around getenv() that pays attention to Py_IgnoreEnvironmentFlag. It should be used for getting variables like diff -r 1267d64c14b3 -r 9430a5c65114 Lib/collections/abc.py --- a/Lib/collections/abc.py Thu Nov 01 14:52:03 2012 +0200 +++ b/Lib/collections/abc.py Thu Nov 01 14:02:56 2012 +0100 @@ -200,12 +200,12 @@ def __gt__(self, other): if not isinstance(other, Set): return NotImplemented - return other.__lt__(self) + return other < self def __ge__(self, other): if not isinstance(other, Set): return NotImplemented - return other.__le__(self) + return other <= self def __eq__(self, other): if not isinstance(other, Set): diff -r 1267d64c14b3 -r 9430a5c65114 Lib/test/test_cmd_line_script.py --- a/Lib/test/test_cmd_line_script.py Thu Nov 01 14:52:03 2012 +0200 +++ b/Lib/test/test_cmd_line_script.py Thu Nov 01 14:02:56 2012 +0100 @@ -363,15 +363,6 @@ self.assertTrue(text[1].startswith(' File ')) self.assertTrue(text[3].startswith('NameError')) - def test_non_utf8(self): - # Issue #16218 - with temp_dir() as script_dir: - script_name = _make_test_script(script_dir, - '\udcf1\udcea\udcf0\udce8\udcef\udcf2') - self._check_script(script_name, script_name, script_name, - script_dir, None, - importlib.machinery.SourceFileLoader) - def test_main(): support.run_unittest(CmdLineTest) support.reap_children() diff -r 1267d64c14b3 -r 9430a5c65114 Lib/test/test_collections.py --- a/Lib/test/test_collections.py Thu Nov 01 14:52:03 2012 +0200 +++ b/Lib/test/test_collections.py Thu Nov 01 14:02:56 2012 +0100 @@ -663,39 +663,6 @@ s |= s self.assertEqual(s, full) - def test_issue16373(self): - # Recursion error comparing comparable and noncomparable - # Set instances - class MyComparableSet(Set): - def __contains__(self, x): - return False - def __len__(self): - return 0 - def __iter__(self): - return iter([]) - class MyNonComparableSet(Set): - def __contains__(self, x): - return False - def __len__(self): - return 0 - def __iter__(self): - return iter([]) - def __le__(self, x): - return NotImplemented - def __lt__(self, x): - return NotImplemented - - cs = MyComparableSet() - ncs = MyNonComparableSet() - with self.assertRaises(TypeError): - ncs < cs - with self.assertRaises(TypeError): - ncs <= cs - with self.assertRaises(TypeError): - cs > ncs - with self.assertRaises(TypeError): - cs >= ncs - def test_Mapping(self): for sample in [dict]: self.assertIsInstance(sample(), Mapping) diff -r 1267d64c14b3 -r 9430a5c65114 Lib/test/test_sys.py --- a/Lib/test/test_sys.py Thu Nov 01 14:52:03 2012 +0200 +++ b/Lib/test/test_sys.py Thu Nov 01 14:02:56 2012 +0100 @@ -515,7 +515,7 @@ attrs = ("debug", "inspect", "interactive", "optimize", "dont_write_bytecode", "no_user_site", "no_site", "ignore_environment", "verbose", - "bytes_warning", "quiet", "hash_randomization") + "bytes_warning", "quiet", "hash_randomization", "oom_fatal") for attr in attrs: self.assertTrue(hasattr(sys.flags, attr), attr) self.assertEqual(type(getattr(sys.flags, attr)), int, attr) diff -r 1267d64c14b3 -r 9430a5c65114 Lib/xdrlib.py --- a/Lib/xdrlib.py Thu Nov 01 14:52:03 2012 +0200 +++ b/Lib/xdrlib.py Thu Nov 01 14:02:56 2012 +0100 @@ -13,7 +13,7 @@ class Error(Exception): """Exception class for this module. Use: - except xdrlib.Error as var: + except xdrlib.Error, var: # var has the Error instance for the exception Public ivars: diff -r 1267d64c14b3 -r 9430a5c65114 Modules/main.c --- a/Modules/main.c Thu Nov 01 14:52:03 2012 +0200 +++ b/Modules/main.c Thu Nov 01 14:02:56 2012 +0100 @@ -43,7 +43,7 @@ static int orig_argc; /* command line options */ -#define BASE_OPTS L"bBc:dEhiJm:OqRsStuvVW:xX:?" +#define BASE_OPTS L"bBc:dEhiJm:oOqRsStuvVW:xX:?" #define PROGRAM_OPTS BASE_OPTS @@ -66,6 +66,7 @@ -i : inspect interactively after running script; forces a prompt even\n\ if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\ -m mod : run library module as a script (terminates option list)\n\ +-o : make MemoryError exceptions fatal\n\ -O : optimize generated bytecode slightly; also PYTHONOPTIMIZE=x\n\ -OO : remove doc-strings in addition to the -O optimizations\n\ -q : don't print version and copyright messages on interactive startup\n\ @@ -394,6 +395,10 @@ /* case 'J': reserved for Jython */ + case 'o': + Py_OomFatalFlag++; + break; + case 'O': Py_OptimizeFlag++; break; diff -r 1267d64c14b3 -r 9430a5c65114 Python/errors.c --- a/Python/errors.c Thu Nov 01 14:52:03 2012 +0200 +++ b/Python/errors.c Thu Nov 01 14:02:56 2012 +0100 @@ -27,6 +27,10 @@ PyThreadState *tstate = PyThreadState_GET(); PyObject *oldtype, *oldvalue, *oldtraceback; + if (Py_OomFatalFlag && PyErr_GivenExceptionMatches(type, PyExc_MemoryError)) { + Py_FatalError("Out of memory"); + } + if (traceback != NULL && !PyTraceBack_Check(traceback)) { /* XXX Should never happen -- fatal error instead? */ /* Well, it could be None. */ diff -r 1267d64c14b3 -r 9430a5c65114 Python/pythonrun.c --- a/Python/pythonrun.c Thu Nov 01 14:52:03 2012 +0200 +++ b/Python/pythonrun.c Thu Nov 01 14:02:56 2012 +0100 @@ -93,6 +93,7 @@ int Py_NoUserSiteDirectory = 0; /* for -s and site.py */ int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */ int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */ +int Py_OomFatalFlag = 0; /* for -o and PYTHONOOMFATAL: crash under OOM conditions (MemoryError) */ PyThreadState *_Py_Finalizing = NULL; @@ -274,6 +275,8 @@ check its value further. */ if ((p = Py_GETENV("PYTHONHASHSEED")) && *p != '\0') Py_HashRandomizationFlag = add_flag(Py_HashRandomizationFlag, p); + if ((p = Py_GETENV("PYTHONOOMFATAL")) && *p != '\0') + Py_OomFatalFlag = add_flag(Py_OomFatalFlag, p); _PyRandom_Init(); @@ -1358,21 +1361,16 @@ { PyInterpreterState *interp; PyThreadState *tstate; - PyObject *filename_obj, *loader_type, *loader; + PyObject *loader_type, *loader; int result = 0; - - filename_obj = PyUnicode_DecodeFSDefault(filename); - if (filename_obj == NULL) - return -1; /* Get current thread state and interpreter pointer */ tstate = PyThreadState_GET(); interp = tstate->interp; loader_type = PyObject_GetAttrString(interp->importlib, loader_name); if (loader_type == NULL) { - Py_DECREF(filename_obj); return -1; } - loader = PyObject_CallFunction(loader_type, "sN", "__main__", filename_obj); + loader = PyObject_CallFunction(loader_type, "ss", "__main__", filename); Py_DECREF(loader_type); if (loader == NULL) { return -1; diff -r 1267d64c14b3 -r 9430a5c65114 Python/sysmodule.c --- a/Python/sysmodule.c Thu Nov 01 14:52:03 2012 +0200 +++ b/Python/sysmodule.c Thu Nov 01 14:02:56 2012 +0100 @@ -1357,6 +1357,7 @@ {"bytes_warning", "-b"}, {"quiet", "-q"}, {"hash_randomization", "-R"}, + {"oom_fatal", "-o"}, {0} }; @@ -1365,9 +1366,9 @@ flags__doc__, /* doc */ flags_fields, /* fields */ #ifdef RISCOS + 14 +#else 13 -#else - 12 #endif }; @@ -1401,6 +1402,7 @@ SetFlag(Py_BytesWarningFlag); SetFlag(Py_QuietFlag); SetFlag(Py_HashRandomizationFlag); + SetFlag(Py_OomFatalFlag); #undef SetFlag if (PyErr_Occurred()) {