comparison Python/bltinmodule.c @ 73392:421c8e291221 3.2

Issue #13342: input() used to ignore sys.stdin's and sys.stdout's unicode error handler in interactive mode (when calling into PyOS_Readline()).
author Antoine Pitrou <solipsis@pitrou.net>
date Sun, 06 Nov 2011 00:34:26 +0100
parents 09d0510e1c50
children 7b01b88aae44 992ba03d60a8
comparison
equal deleted inserted replaced
73390:5c1fcaf3cf1c 73392:421c8e291221
1638 } 1638 }
1639 } 1639 }
1640 1640
1641 /* If we're interactive, use (GNU) readline */ 1641 /* If we're interactive, use (GNU) readline */
1642 if (tty) { 1642 if (tty) {
1643 PyObject *po; 1643 PyObject *po = NULL;
1644 char *prompt; 1644 char *prompt;
1645 char *s; 1645 char *s = NULL;
1646 PyObject *stdin_encoding; 1646 PyObject *stdin_encoding = NULL, *stdin_errors = NULL;
1647 char *stdin_encoding_str; 1647 PyObject *stdout_encoding = NULL, *stdout_errors = NULL;
1648 char *stdin_encoding_str, *stdin_errors_str;
1648 PyObject *result; 1649 PyObject *result;
1649 size_t len; 1650 size_t len;
1650 1651
1651 stdin_encoding = PyObject_GetAttrString(fin, "encoding"); 1652 stdin_encoding = PyObject_GetAttrString(fin, "encoding");
1652 if (!stdin_encoding) 1653 stdin_errors = PyObject_GetAttrString(fin, "errors");
1654 if (!stdin_encoding || !stdin_errors)
1653 /* stdin is a text stream, so it must have an 1655 /* stdin is a text stream, so it must have an
1654 encoding. */ 1656 encoding. */
1655 return NULL; 1657 goto _readline_errors;
1656 stdin_encoding_str = _PyUnicode_AsString(stdin_encoding); 1658 stdin_encoding_str = _PyUnicode_AsString(stdin_encoding);
1657 if (stdin_encoding_str == NULL) { 1659 stdin_errors_str = _PyUnicode_AsString(stdin_errors);
1658 Py_DECREF(stdin_encoding); 1660 if (!stdin_encoding_str || !stdin_errors_str)
1659 return NULL; 1661 goto _readline_errors;
1660 }
1661 tmp = PyObject_CallMethod(fout, "flush", ""); 1662 tmp = PyObject_CallMethod(fout, "flush", "");
1662 if (tmp == NULL) 1663 if (tmp == NULL)
1663 PyErr_Clear(); 1664 PyErr_Clear();
1664 else 1665 else
1665 Py_DECREF(tmp); 1666 Py_DECREF(tmp);
1666 if (promptarg != NULL) { 1667 if (promptarg != NULL) {
1668 /* We have a prompt, encode it as stdout would */
1669 char *stdout_encoding_str, *stdout_errors_str;
1667 PyObject *stringpo; 1670 PyObject *stringpo;
1668 PyObject *stdout_encoding;
1669 char *stdout_encoding_str;
1670 stdout_encoding = PyObject_GetAttrString(fout, "encoding"); 1671 stdout_encoding = PyObject_GetAttrString(fout, "encoding");
1671 if (stdout_encoding == NULL) { 1672 stdout_errors = PyObject_GetAttrString(fout, "errors");
1672 Py_DECREF(stdin_encoding); 1673 if (!stdout_encoding || !stdout_errors)
1673 return NULL; 1674 goto _readline_errors;
1674 }
1675 stdout_encoding_str = _PyUnicode_AsString(stdout_encoding); 1675 stdout_encoding_str = _PyUnicode_AsString(stdout_encoding);
1676 if (stdout_encoding_str == NULL) { 1676 stdout_errors_str = _PyUnicode_AsString(stdout_errors);
1677 Py_DECREF(stdin_encoding); 1677 if (!stdout_encoding_str || !stdout_errors_str)
1678 Py_DECREF(stdout_encoding); 1678 goto _readline_errors;
1679 return NULL;
1680 }
1681 stringpo = PyObject_Str(promptarg); 1679 stringpo = PyObject_Str(promptarg);
1682 if (stringpo == NULL) { 1680 if (stringpo == NULL)
1683 Py_DECREF(stdin_encoding); 1681 goto _readline_errors;
1684 Py_DECREF(stdout_encoding);
1685 return NULL;
1686 }
1687 po = PyUnicode_AsEncodedString(stringpo, 1682 po = PyUnicode_AsEncodedString(stringpo,
1688 stdout_encoding_str, NULL); 1683 stdout_encoding_str, stdout_errors_str);
1689 Py_DECREF(stdout_encoding); 1684 Py_CLEAR(stdout_encoding);
1690 Py_DECREF(stringpo); 1685 Py_CLEAR(stdout_errors);
1691 if (po == NULL) { 1686 Py_CLEAR(stringpo);
1692 Py_DECREF(stdin_encoding); 1687 if (po == NULL)
1693 return NULL; 1688 goto _readline_errors;
1694 }
1695 prompt = PyBytes_AsString(po); 1689 prompt = PyBytes_AsString(po);
1696 if (prompt == NULL) { 1690 if (prompt == NULL)
1697 Py_DECREF(stdin_encoding); 1691 goto _readline_errors;
1698 Py_DECREF(po);
1699 return NULL;
1700 }
1701 } 1692 }
1702 else { 1693 else {
1703 po = NULL; 1694 po = NULL;
1704 prompt = ""; 1695 prompt = "";
1705 } 1696 }
1706 s = PyOS_Readline(stdin, stdout, prompt); 1697 s = PyOS_Readline(stdin, stdout, prompt);
1707 Py_XDECREF(po);
1708 if (s == NULL) { 1698 if (s == NULL) {
1709 if (!PyErr_Occurred()) 1699 if (!PyErr_Occurred())
1710 PyErr_SetNone(PyExc_KeyboardInterrupt); 1700 PyErr_SetNone(PyExc_KeyboardInterrupt);
1711 Py_DECREF(stdin_encoding); 1701 goto _readline_errors;
1712 return NULL;
1713 } 1702 }
1714 1703
1715 len = strlen(s); 1704 len = strlen(s);
1716 if (len == 0) { 1705 if (len == 0) {
1717 PyErr_SetNone(PyExc_EOFError); 1706 PyErr_SetNone(PyExc_EOFError);
1725 } 1714 }
1726 else { 1715 else {
1727 len--; /* strip trailing '\n' */ 1716 len--; /* strip trailing '\n' */
1728 if (len != 0 && s[len-1] == '\r') 1717 if (len != 0 && s[len-1] == '\r')
1729 len--; /* strip trailing '\r' */ 1718 len--; /* strip trailing '\r' */
1730 result = PyUnicode_Decode(s, len, stdin_encoding_str, NULL); 1719 result = PyUnicode_Decode(s, len, stdin_encoding_str,
1720 stdin_errors_str);
1731 } 1721 }
1732 } 1722 }
1733 Py_DECREF(stdin_encoding); 1723 Py_DECREF(stdin_encoding);
1724 Py_DECREF(stdin_errors);
1725 Py_XDECREF(po);
1734 PyMem_FREE(s); 1726 PyMem_FREE(s);
1735 return result; 1727 return result;
1728 _readline_errors:
1729 Py_XDECREF(stdin_encoding);
1730 Py_XDECREF(stdout_encoding);
1731 Py_XDECREF(stdin_errors);
1732 Py_XDECREF(stdout_errors);
1733 Py_XDECREF(po);
1734 return NULL;
1736 } 1735 }
1737 1736
1738 /* Fallback if we're not interactive */ 1737 /* Fallback if we're not interactive */
1739 if (promptarg != NULL) { 1738 if (promptarg != NULL) {
1740 if (PyFile_WriteObject(promptarg, fout, Py_PRINT_RAW) != 0) 1739 if (PyFile_WriteObject(promptarg, fout, Py_PRINT_RAW) != 0)