diff -r 82b58807f481 Include/pydebug.h --- a/Include/pydebug.h Sat Nov 16 19:10:57 2013 +0200 +++ b/Include/pydebug.h Mon Jan 20 15:13:58 2014 -0600 @@ -13,6 +13,7 @@ PyAPI_DATA(int) Py_OptimizeFlag; PyAPI_DATA(int) Py_NoSiteFlag; PyAPI_DATA(int) Py_BytesWarningFlag; +PyAPI_DATA(int) Py_BytesComplatibleFormatFlag; PyAPI_DATA(int) Py_UseClassExceptionsFlag; PyAPI_DATA(int) Py_FrozenFlag; PyAPI_DATA(int) Py_IgnoreEnvironmentFlag; diff -r 82b58807f481 Modules/main.c --- a/Modules/main.c Sat Nov 16 19:10:57 2013 +0200 +++ b/Modules/main.c Mon Jan 20 15:13:58 2014 -0600 @@ -43,7 +43,7 @@ static int orig_argc; /* command line options */ -#define BASE_OPTS L"bBc:dEhiIJm:OqRsStuvVW:xX:?" +#define BASE_OPTS L"bBc:dEhiIJm:OqRsStuvVW:xX:2?" #define PROGRAM_OPTS BASE_OPTS @@ -86,6 +86,7 @@ -X opt : set implementation-specific option\n\ "; static char *usage_4 = "\ +-2 : enable extra Python 2.x backwards compatibility features\n\ file : program read from script file\n\ - : program read from stdin (default; interactive mode if a tty)\n\ arg ...: arguments passed to program in sys.argv[1:]\n\n\ @@ -414,6 +415,12 @@ } switch (c) { + case '2': + /* features we want disabled by default but ease porting + of Python 2.x code */ + Py_BytesComplatibleFormatFlag++; + break; + case 'b': Py_BytesWarningFlag++; break; diff -r 82b58807f481 Python/pythonrun.c --- a/Python/pythonrun.c Sat Nov 16 19:10:57 2013 +0200 +++ b/Python/pythonrun.c Mon Jan 20 15:13:58 2014 -0600 @@ -116,15 +116,16 @@ int Py_InteractiveFlag; /* Needed by Py_FdIsInteractive() below */ int Py_InspectFlag; /* Needed to determine whether to exit at SystemExit */ int Py_NoSiteFlag; /* Suppress 'import site' */ +int Py_BytesComplatibleFormatFlag; /* enable %s and %r */ int Py_BytesWarningFlag; /* Warn on str(bytes) and str(buffer) */ int Py_DontWriteBytecodeFlag; /* Suppress writing bytecode files (*.py[co]) */ int Py_UseClassExceptionsFlag = 1; /* Needed by bltinmodule.c: deprecated */ int Py_FrozenFlag; /* Needed by getpath.c */ int Py_IgnoreEnvironmentFlag; /* e.g. PYTHONPATH, PYTHONHOME */ -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_IsolatedFlag = 0; /* for -I, isolate from user's env */ +int Py_NoUserSiteDirectory; /* for -s and site.py */ +int Py_UnbufferedStdioFlag; /* Unbuffered binary std{in,out,err} */ +int Py_HashRandomizationFlag; /* for -R and PYTHONHASHSEED */ +int Py_IsolatedFlag; /* for -I, isolate from user's env */ PyThreadState *_Py_Finalizing = NULL; diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c --- b/Objects/bytesobject.c +++ a/Objects/bytesobject.c~ @@ -517,6 +517,14 @@ } return result; } + if (Py_BytesComplatibleFormatFlag) { + PyObject *temp = PyObject_Str(v); + if (temp == NULL) + return NULL; + result = _PyUnicode_AsASCIIString(temp, "strict"); + Py_DECREF(temp); + return result; + } PyErr_Format(PyExc_TypeError, "Type '%.100s' doesn't define __bytes__, encoding required?", Py_TYPE(v)->tp_name); @@ -748,17 +756,27 @@ len = 1; break; case 'a': + case 'r': + if (c != 'r' || Py_BytesComplatibleFormatFlag) { + temp2 = PyObject_ASCII(v); + if (temp2 == NULL) + goto error; + temp = PyUnicode_AsLatin1String(temp2); + Py_DECREF(temp2); + if (temp == NULL) + goto error; + pbuf = PyBytes_AS_STRING(temp); + len = PyBytes_GET_SIZE(temp); + if (prec >= 0 && len > prec) + len = prec; + } + else { + PyErr_Format(PyExc_ValueError, + "bytes does not support format character '%c' (0x%x) " + "at index %zd", + c, c, (Py_ssize_t)(fmt - 1 - PyBytes_AsString(format))); - temp2 = PyObject_ASCII(v); - if (temp2 == NULL) goto error; + } - temp = PyUnicode_AsLatin1String(temp2); - Py_DECREF(temp2); - if (temp == NULL) - goto error; - pbuf = PyBytes_AS_STRING(temp); - len = PyBytes_GET_SIZE(temp); - if (prec >= 0 && len > prec) - len = prec; break; case 's': if (_getbuffer(v, &buf) < 0) {