8000 Addressed PR Issues · python/cpython@9479848 · GitHub
[go: up one dir, main page]

Skip to content

Commit 9479848

Browse files
Addressed PR Issues
1 parent 5be18a1 commit 9479848

File tree

6 files changed

+153
-5
lines changed

6 files changed

+153
-5
lines changed

Include/objimpl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,9 @@ _PyObject_INIT(PyObject *op, PyTypeObject *typeobj)
138138
{
139139
assert(op != NULL);
140140
Py_TYPE(op) = typeobj;
141+
if (PyType_GetFlags(typeobj) & Py_TPFLAGS_HEAPTYPE) {
142+
Py_INCREF(typeobj);
143+
}
141144
_Py_NewReference(op);
142145
return op;
143146
}

Lib/test/test_os.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3324,6 +3324,24 @@ def test_os_all(self):
33243324
self.assertIn('walk', os.__all__)
33253325

33263326

3327+
class TestDirEntry(unittest.TestCase):
3328+
def setUp(self):
3329+
self.path = os.path.realpath(support.TESTFN)
3330+
self.addCleanup(support.rmtree, self.path)
3331+
os.mkdir(self.path)
3332+
3333+
def test_uninstantiable(self):
3334+
self.assertRaises(TypeError, os.DirEntry)
3335+
3336+
def test_unpickable(self):
3337+
filename = create_file(os.path.join(self.path, "file.txt"), b'python')
3338+
entry = [entry for entry in os.scandir(self.path)].pop()
3339+
self.assertIsInstance(entry, os.DirEntry)
3340+
self.assertEqual(entry.name, "file.txt")
3341+
import pickle
3342+
self.assertRaises(TypeError, pickle.dumps, entry, filename)
3343+
3344+
33273345
class TestScandir(unittest.TestCase):
33283346
check_no_resource_warning = support.check_no_resource_warning
33293347

@@ -3358,6 +3376,18 @@ def assert_stat_equal(self, stat1, stat2, skip_fields):
33583376
else:
33593377
self.assertEqual(stat1, stat2)
33603378

3379+
def test_uninstantiable(self):
3380+
scandir_iter = os.scandir(self.path)
3381+
self.assertRaises(TypeError, type(scandir_iter))
3382+
scandir_iter.close()
3383+
3384+
def test_unpickable(self):
3385+
filename = self.create_file("file.txt")
3386+
scandir_iter = os.scandir(self.path)
3387+
import pickle
3388+
self.assertRaises(TypeError, pickle.dumps, scandir_iter, filename)
3389+
scandir_iter.close()
3390+
33613391
def check_entry(self, entry, name, is_dir, is_file, is_symlink):
33623392
self.assertIsInstance(entry, os.DirEntry)
33633393
self.assertEqual(entry.name, name)

Misc/NEWS.d/next/C API/2018-12-02-22-39-41.bpo-35381.HjI3j_.rst

Lines changed: 0 additions & 1 deletion
This file was deleted.

Modules/clinic/posixmodule.c.h

Lines changed: 46 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Modules/posixmodule.c

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12020,13 +12020,22 @@ typedef struct {
1202012020
#endif
1202112021
} DirEntry;
1202212022

12023+
static PyObject *
12024+
DirEntry_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
12025+
{
12026+
PyErr_Format(PyExc_TypeError,
12027+
"cannot create '%.100s' instances", type->tp_name);
12028+
return NULL;
12029+
}
12030+
1202312031
static void
1202412032
DirEntry_dealloc(DirEntry *entry)
1202512033
{
1202612034
Py_XDECREF(entry->name);
1202712035
Py_XDECREF(entry->path);
1202812036
Py_XDECREF(entry->stat);
1202912037
Py_XDECREF(entry->lstat);
12038+
Py_DECREF(Py_TYPE(entry));
1203012039
Py_TYPE(entry)->tp_free((PyObject *)entry);
1203112040
}
1203212041

@@ -12287,6 +12296,37 @@ os_DirEntry_inode_impl(DirEntry *self)
1228712296
#endif
1228812297
}
1228912298

12299+
/*[clinic input]
12300+
os.DirEntry.__reduce__
12301+
12302+
returns null and raises an exception to avoid pickling
12303+
[clinic start generated code]*/
12304+
12305+
static PyObject *
12306+
os_DirEntry___reduce___impl(DirEntry *self)
12307+
/*[clinic end generated code: output=45167543e30c210c input=c1689a589f9c38f2]*/
12308+
{
12309+
PyErr_Format(PyExc_TypeError,
12310+
"cannot pickle '%.100s' instances", Py_TYPE(self)->tp_name);
12311+
return NULL;
12312+
}
12313+
12314+
/*[clinic input]
12315+
os.DirEntry.__reduce_ex__
12316+
12317+
protocol: int
12318+
/
12319+
12320+
Returns NULL and raises an exception to avoid pickling
12321+
[clinic start generated code]*/
12322+
12323+
static PyObject *
12324+
os_DirEntry___reduce_ex___impl(DirEntry *self, int protocol)
12325+
/*[clinic end generated code: output=a81881dfe241a631 input=1afbee3b136a7ece]*/
12326+
{
12327+
return os_DirEntry___reduce___impl(self);
12328+
}
12329+
1229012330
static PyObject *
1229112331
DirEntry_repr(DirEntry *self)
1229212332
{
@@ -12318,6 +12358,8 @@ static PyMemberDef DirEntry_members[] = {
1231812358
#include "clinic/posixmodule.c.h"
1231912359

1232012360
static PyMethodDef DirEntry_methods[] = {
12361+
OS_DIRENTRY___REDUCE___METHODDEF
12362+
OS_DIRENTRY___REDUCE_EX___METHODDEF
1232112363
OS_DIRENTRY_IS_DIR_METHODDEF
1232212364
OS_DIRENTRY_IS_FILE_METHODDEF
1232312365
OS_DIRENTRY_IS_SYMLINK_METHODDEF
@@ -12328,6 +12370,7 @@ static PyMethodDef DirEntry_methods[] = {
1232812370
};
1232912371

1233012372
static PyType_Slot DirEntryType_slots[] = {
12373+
{Py_tp_new, DirEntry_new},
1233112374
{Py_tp_dealloc, DirEntry_dealloc},
1233212375
{Py_tp_repr, DirEntry_repr},
1233312376
{Py_tp_methods, DirEntry_methods},
@@ -12734,23 +12777,49 @@ ScandirIterator_finalize(ScandirIterator *iterator)
1273412777
PyErr_Restore(error_type, error_value, error_traceback);
1273512778
}
1273612779

12780+
static PyObject *
12781+
ScandirIterator_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
12782+
{
12783+
PyErr_Format(PyExc_TypeError,
12784+
"cannot create '%.100s' instances", type->tp_name);
12785+
return NULL;
12786+
}
12787+
12788+
static PyObject *
12789+
ScandirIterator_reduce(PyObject *self, PyObject *args, PyObject *kwargs)
12790+
{
12791+
PyErr_Format(PyExc_TypeError,
12792+
"cannot pickle '%.100s' instances", Py_TYPE(self)->tp_name);
12793+
return NULL;
12794+
}
12795+
12796+
static PyObject *
12797+
ScandirIterator_reduce_ex(PyObject *self, PyObject *arg)
12798+
{
12799+
return ScandirIterator_reduce(self, NULL, NULL);
12800+
}
12801+
1273712802
static void
1273812803
ScandirIterator_dealloc(ScandirIterator *iterator)
1273912804
{
1274012805
if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
1274112806
return;
1274212807

12808+
Py_DECREF(Py_TYPE(iterator));
1274312809
Py_TYPE(iterator)->tp_free((PyObject *)iterator);
1274412810
}
1274512811

1274612812
static PyMethodDef ScandirIterator_methods[] = {
12813+
{"__reduce__", (PyCFunction)ScandirIterator_reduce, METH_NOARGS},
12814+
{"__reduce_ex__", (PyCFunction)ScandirIterator_reduce_ex, METH_O},
1274712815
{"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
1274812816
{"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
1274912817
{"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
1275012818
{NULL}
1275112819
};
1275212820

1275312821
static PyType_Slot ScandirIteratorType_slots[] = {
12822+
{Py_tp_new, ScandirIterator_new},
1275412823
{Py_tp_dealloc, ScandirIterator_dealloc},
1275512824
{Py_tp_finalize, ScandirIterator_finalize},
1275612825
{Py_tp_iter, PyObject_SelfIter},

Objects/object.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,9 @@ PyObject_Init(PyObject *op, PyTypeObject *tp)
230230
return PyErr_NoMemory();
231231
/* Any changes should be reflected in PyObject_INIT (objimpl.h) */
232232
Py_TYPE(op) = tp;
233+
if (PyType_GetFlags(tp) & Py_TPFLAGS_HEAPTYPE) {
234+
Py_INCREF(tp);
235+
}
233236
_Py_NewReference(op);
234237
return op;
235238
}
@@ -240,9 +243,8 @@ PyObject_InitVar(PyVarObject *op, PyTypeObject *tp, Py_ssize_t size)
240243
if (op == NULL)
241244
return (PyVarObject *) PyErr_NoMemory();
242245
/* Any changes should be reflected in PyObject_INIT_VAR */
243-
op->ob_size = size;
244-
Py_TYPE(op) = tp;
245-
_Py_NewReference((PyObject *)op);
246+
Py_SIZE(op) = size;
247+
PyObject_Init((PyObject *)op, tp);
246248
return op;
247249
}
248250

0 commit comments

Comments
 (0)
0