FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

gh-82626: Emit a warning when bool is used as a file descriptor by serhiy-storchaka · Pull Request #111275 · python/cpython · GitHub

/ cpython Public
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .c  (4) .py  (5) .rst  (2) All 3 file types selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
5 changes: 5 additions & 0 deletions Doc/whatsnew/3.13.rst
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ Other Language Changes
is rejected when the global is used in the :keyword:`else` block.
(Contributed by Irit Katriel in :gh:`111123`.)

* Many functions now emit a warning if a boolean value is passed as
a file descriptor argument.
This can help catch some errors earlier.
(Contributed by Serhiy Storchaka in :gh:`82626`.)

* Added a new environment variable :envvar:`PYTHON_FROZEN_MODULES`. It
determines whether or not frozen modules are ignored by the import machinery,
equivalent of the :option:`-X frozen_modules <-X>` command-line option.
Expand Down
5 changes: 5 additions & 0 deletions Lib/_pyio.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -1495,6 +1495,11 @@ def __init__(self, file, mode='r', closefd=True, opener=None):
if isinstance(file, float):
raise TypeError('integer argument expected, got float')
if isinstance(file, int):
if isinstance(file, bool):
import warnings
warnings.warn("bool is used as a file descriptor",
RuntimeWarning, stacklevel=2)
file = int(file)
fd = file
if fd < 0:
raise ValueError('negative file descriptor')
Expand Down
8 changes: 8 additions & 0 deletions Lib/test/test_fileio.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,14 @@ def testInvalidFd(self):
import msvcrt
self.assertRaises(OSError, msvcrt.get_osfhandle, make_bad_fd())

def testBooleanFd(self):
for fd in False, True:
with self.assertWarnsRegex(RuntimeWarning,
'bool is used as a file descriptor') as cm:
f = self.FileIO(fd, closefd=False)
f.close()
self.assertEqual(cm.filename, __file__)

def testBadModeArgument(self):
# verify that we get a sensible error message for bad mode argument
bad_mode = "qwerty"
Expand Down
6 changes: 6 additions & 0 deletions Lib/test/test_genericpath.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,12 @@ def test_exists_fd(self):
os.close(w)
self.assertFalse(self.pathmodule.exists(r))

def test_exists_bool(self):
for fd in False, True:
with self.assertWarnsRegex(RuntimeWarning,
'bool is used as a file descriptor'):
self.pathmodule.exists(fd)

def test_isdir(self):
filename = os_helper.TESTFN
bfilename = os.fsencode(filename)
Expand Down
14 changes: 14 additions & 0 deletions Lib/test/test_os.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -2195,12 +2195,15 @@ def test_chmod(self):
class TestInvalidFD(unittest.TestCase):
singles = ["fchdir", "dup", "fdatasync", "fstat",
"fstatvfs", "fsync", "tcgetpgrp", "ttyname"]
singles_fildes = {"fchdir", "fdatasync", "fsync"}
#singles.append("close")
#We omit close because it doesn't raise an exception on some platforms
def get_single(f):
def helper(self):
if hasattr(os, f):
self.check(getattr(os, f))
if f in self.singles_fildes:
self.check_bool(getattr(os, f))
return helper
for f in singles:
locals()["test_"+f] = get_single(f)
Expand All @@ -2214,8 +2217,16 @@ def check(self, f, *args, **kwargs):
self.fail("%r didn't raise an OSError with a bad file descriptor"
% f)

def check_bool(self, f, *args, **kwargs):
with warnings.catch_warnings():
warnings.simplefilter("error", RuntimeWarning)
for fd in False, True:
with self.assertRaises(RuntimeWarning):
f(fd, *args, **kwargs)

def test_fdopen(self):
self.check(os.fdopen, encoding="utf-8")
self.check_bool(os.fdopen, encoding="utf-8")

@unittest.skipUnless(hasattr(os, 'isatty'), 'test needs os.isatty()')
def test_isatty(self):
Expand Down Expand Up @@ -2277,11 +2288,14 @@ def test_fchown(self):
def test_fpathconf(self):
self.check(os.pathconf, "PC_NAME_MAX")
self.check(os.fpathconf, "PC_NAME_MAX")
self.check_bool(os.pathconf, "PC_NAME_MAX")
self.check_bool(os.fpathconf, "PC_NAME_MAX")

@unittest.skipUnless(hasattr(os, 'ftruncate'), 'test needs os.ftruncate()')
def test_ftruncate(self):
self.check(os.truncate, 0)
self.check(os.ftruncate, 0)
self.check_bool(os.truncate, 0)

@unittest.skipUnless(hasattr(os, 'lseek'), 'test needs os.lseek()')
def test_lseek(self):
Expand Down
7 changes: 7 additions & 0 deletions Lib/test/test_posix.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -1514,6 +1514,13 @@ def test_stat_dir_fd(self):
self.assertRaises(OverflowError,
posix.stat, name, dir_fd=10**20)

for fd in False, True:
with self.assertWarnsRegex(RuntimeWarning,
'bool is used as a file descriptor') as cm:
with self.assertRaises(OSError):
posix.stat('nonexisting', dir_fd=fd)
self.assertEqual(cm.filename, __file__)

@unittest.skipUnless(os.utime in os.supports_dir_fd, "test needs dir_fd support in os.utime()")
def test_utime_dir_fd(self):
with self.prepare_file() as (dir_fd, name, fullname):
Expand Down
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Many functions now emit a warning if a boolean value is passed as a file
descriptor argument.
7 changes: 7 additions & 0 deletions Modules/_io/fileio.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,13 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode,
self->fd = -1;
}

if (PyBool_Check(nameobj)) {
if (PyErr_WarnEx(PyExc_RuntimeWarning,
"bool is used as a file descriptor", 1))
{
return -1;
}
}
fd = PyLong_AsInt(nameobj);
if (fd < 0) {
if (!PyErr_Occurred()) {
Expand Down
7 changes: 7 additions & 0 deletions Modules/faulthandler.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,13 @@ faulthandler_get_fileno(PyObject **file_ptr)
}
}
else if (PyLong_Check(file)) {
if (PyBool_Check(file)) {
if (PyErr_WarnEx(PyExc_RuntimeWarning,
"bool is used as a file descriptor", 1))
{
return -1;
}
}
fd = PyLong_AsInt(file);
if (fd == -1 && PyErr_Occurred())
return -1;
Expand Down
7 changes: 7 additions & 0 deletions Modules/posixmodule.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,13 @@ _fd_converter(PyObject *o, int *p)
int overflow;
long long_value;

if (PyBool_Check(o)) {
if (PyErr_WarnEx(PyExc_RuntimeWarning,
"bool is used as a file descriptor", 1))
{
return 0;
}
}
PyObject *index = _PyNumber_Index(o);
if (index == NULL) {
return 0;
Expand Down
7 changes: 7 additions & 0 deletions Objects/fileobject.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,13 @@ PyObject_AsFileDescriptor(PyObject *o)
PyObject *meth;

if (PyLong_Check(o)) {
if (PyBool_Check(o)) {
if (PyErr_WarnEx(PyExc_RuntimeWarning,
"bool is used as a file descriptor", 1))
{
return -1;
}
}
fd = PyLong_AsInt(o);
}
else if (PyObject_GetOptionalAttr(o, &_Py_ID(fileno), &meth) < 0) {
Expand Down

Back | FazBrowse Home | New Git URL