Skip to content

Commit 4332aec

Browse files
committed
bpo-40549: posixmodule.c uses defining_class
Pass PEP 573 defining_class to os.DirEntry methods. The module state is now retrieve from defining_class rather than Py_TYPE(self), to support subclasses (even if DirEntry doesn't support subclasses yet).
1 parent 7443d42 commit 4332aec

File tree

2 files changed

+84
-91
lines changed

2 files changed

+84
-91
lines changed

Modules/clinic/posixmodule.c.h

+35-56
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Modules/posixmodule.c

+49-35
Original file line numberDiff line numberDiff line change
@@ -12747,17 +12747,20 @@ DirEntry_dealloc(DirEntry *entry)
1274712747

1274812748
/* Forward reference */
1274912749
static int
12750-
DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
12750+
DirEntry_test_mode(PyTypeObject *defining_class, DirEntry *self,
12751+
int follow_symlinks, unsigned short mode_bits);
1275112752

1275212753
/*[clinic input]
1275312754
os.DirEntry.is_symlink -> bool
12755+
defining_class: defining_class
12756+
/
1275412757
1275512758
Return True if the entry is a symbolic link; cached per entry.
1275612759
[clinic start generated code]*/
1275712760

1275812761
static int
12759-
os_DirEntry_is_symlink_impl(DirEntry *self)
12760-
/*[clinic end generated code: output=42244667d7bcfc25 input=1605a1b4b96976c3]*/
12762+
os_DirEntry_is_symlink_impl(DirEntry *self, PyTypeObject *defining_class)
12763+
/*[clinic end generated code: output=293096d589b6d47c input=e9acc5ee4d511113]*/
1276112764
{
1276212765
#ifdef MS_WINDOWS
1276312766
return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
@@ -12766,21 +12769,16 @@ os_DirEntry_is_symlink_impl(DirEntry *self)
1276612769
if (self->d_type != DT_UNKNOWN)
1276712770
return self->d_type == DT_LNK;
1276812771
else
12769-
return DirEntry_test_mode(self, 0, S_IFLNK);
12772+
return DirEntry_test_mode(defining_class, self, 0, S_IFLNK);
1277012773
#else
1277112774
/* POSIX without d_type */
12772-
return DirEntry_test_mode(self, 0, S_IFLNK);
12775+
return DirEntry_test_mode(defining_class, self, 0, S_IFLNK);
1277312776
#endif
1277412777
}
1277512778

12776-
static inline PyObject*
12777-
DirEntry_get_module(DirEntry *self)
12778-
{
12779-
return PyType_GetModule(Py_TYPE(self));
12780-
}
12781-
1278212779
static PyObject *
12783-
DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
12780+
DirEntry_fetch_stat(PyTypeObject *defining_class, DirEntry *self,
12781+
int follow_symlinks)
1278412782
{
1278512783
int result;
1278612784
STRUCT_STAT st;
@@ -12816,18 +12814,18 @@ DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
1281612814
if (result != 0)
1281712815
return path_object_error(self->path);
1281812816

12819-
return _pystat_fromstructstat(DirEntry_get_module(self), &st);
12817+
return _pystat_fromstructstat(PyType_GetModule(defining_class), &st);
1282012818
}
1282112819

1282212820
static PyObject *
12823-
DirEntry_get_lstat(DirEntry *self)
12821+
DirEntry_get_lstat(PyTypeObject *defining_class, DirEntry *self)
1282412822
{
1282512823
if (!self->lstat) {
1282612824
#ifdef MS_WINDOWS
12827-
self->lstat = _pystat_fromstructstat(DirEntry_get_module(self),
12825+
self->lstat = _pystat_fromstructstat(PyType_GetModule(defining_class),
1282812826
&self->win32_lstat);
1282912827
#else /* POSIX */
12830-
self->lstat = DirEntry_fetch_stat(self, 0);
12828+
self->lstat = DirEntry_fetch_stat(defining_class, self, 0);
1283112829
#endif
1283212830
}
1283312831
Py_XINCREF(self->lstat);
@@ -12836,27 +12834,34 @@ DirEntry_get_lstat(DirEntry *self)
1283612834

1283712835
/*[clinic input]
1283812836
os.DirEntry.stat
12837+
defining_class: defining_class
12838+
/
1283912839
*
1284012840
follow_symlinks: bool = True
1284112841
1284212842
Return stat_result object for the entry; cached per entry.
1284312843
[clinic start generated code]*/
1284412844

1284512845
static PyObject *
12846-
os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
12847-
/*[clinic end generated code: output=008593b3a6d01305 input=280d14c1d6f1d00d]*/
12846+
os_DirEntry_stat_impl(DirEntry *self, PyTypeObject *defining_class,
12847+
int follow_symlinks)
12848+
/*[clinic end generated code: output=23f803e19c3e780e input=e816273c4e67ee98]*/
1284812849
{
12849-
if (!follow_symlinks)
12850-
return DirEntry_get_lstat(self);
12850+
if (!follow_symlinks) {
12851+
return DirEntry_get_lstat(defining_class, self);
12852+
}
1285112853

1285212854
if (!self->stat) {
12853-
int result = os_DirEntry_is_symlink_impl(self);
12854-
if (result == -1)
12855+
int result = os_DirEntry_is_symlink_impl(self, defining_class);
12856+
if (result == -1) {
1285512857
return NULL;
12856-
else if (result)
12857-
self->stat = DirEntry_fetch_stat(self, 1);
12858-
else
12859-
self->stat = DirEntry_get_lstat(self);
12858+
}
12859+
if (result) {
12860+
self->stat = DirEntry_fetch_stat(defining_class, self, 1);
12861+
}
12862+
else {
12863+
self->stat = DirEntry_get_lstat(defining_class, self);
12864+
}
1286012865
}
1286112866

1286212867
Py_XINCREF(self->stat);
@@ -12865,7 +12870,8 @@ os_DirEntry_stat_impl(DirEntry *self, int follow_symlinks)
1286512870

1286612871
/* Set exception and return -1 on error, 0 for False, 1 for True */
1286712872
static int
12868-
DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
12873+
DirEntry_test_mode(PyTypeObject *defining_class, DirEntry *self,
12874+
int follow_symlinks, unsigned short mode_bits)
1286912875
{
1287012876
PyObject *stat = NULL;
1287112877
PyObject *st_mode = NULL;
@@ -12890,7 +12896,7 @@ DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits
1289012896
#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
1289112897
if (need_stat) {
1289212898
#endif
12893-
stat = os_DirEntry_stat_impl(self, follow_symlinks);
12899+
stat = os_DirEntry_stat_impl(self, defining_class, follow_symlinks);
1289412900
if (!stat) {
1289512901
if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
1289612902
/* If file doesn't exist (anymore), then return False
@@ -12900,7 +12906,7 @@ DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits
1290012906
}
1290112907
goto error;
1290212908
}
12903-
st_mode = PyObject_GetAttr(stat, get_posix_state(DirEntry_get_module(self))->st_mode);
12909+
st_mode = PyObject_GetAttr(stat, get_posix_state(PyType_GetModule(defining_class))->st_mode);
1290412910
if (!st_mode)
1290512911
goto error;
1290612912

@@ -12943,32 +12949,38 @@ DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits
1294312949

1294412950
/*[clinic input]
1294512951
os.DirEntry.is_dir -> bool
12952+
defining_class: defining_class
12953+
/
1294612954
*
1294712955
follow_symlinks: bool = True
1294812956
1294912957
Return True if the entry is a directory; cached per entry.
1295012958
[clinic start generated code]*/
1295112959

1295212960
static int
12953-
os_DirEntry_is_dir_impl(DirEntry *self, int follow_symlinks)
12954-
/*[clinic end generated code: output=ad2e8d54365da287 input=0135232766f53f58]*/
12961+
os_DirEntry_is_dir_impl(DirEntry *self, PyTypeObject *defining_class,
12962+
int follow_symlinks)
12963+
/*[clinic end generated code: output=0cd453b9c0987fdf input=1a4ffd6dec9920cb]*/
1295512964
{
12956-
return DirEntry_test_mode(self, follow_symlinks, S_IFDIR);
12965+
return DirEntry_test_mode(defining_class, self, follow_symlinks, S_IFDIR);
1295712966
}
1295812967

1295912968
/*[clinic input]
1296012969
os.DirEntry.is_file -> bool
12970+
defining_class: defining_class
12971+
/
1296112972
*
1296212973
follow_symlinks: bool = True
1296312974
1296412975
Return True if the entry is a file; cached per entry.
1296512976
[clinic start generated code]*/
1296612977

1296712978
static int
12968-
os_DirEntry_is_file_impl(DirEntry *self, int follow_symlinks)
12969-
/*[clinic end generated code: output=8462ade481d8a476 input=0dc90be168b041ee]*/
12979+
os_DirEntry_is_file_impl(DirEntry *self, PyTypeObject *defining_class,
12980+
int follow_symlinks)
12981+
/*[clinic end generated code: output=f7c277ab5ba80908 input=0a64c5a12e802e3b]*/
1297012982
{
12971-
return DirEntry_test_mode(self, follow_symlinks, S_IFREG);
12983+
return DirEntry_test_mode(defining_class, self, follow_symlinks, S_IFREG);
1297212984
}
1297312985

1297412986
/*[clinic input]
@@ -13496,6 +13508,8 @@ static PyType_Spec ScandirIteratorType_spec = {
1349613508
MODNAME ".ScandirIterator",
1349713509
sizeof(ScandirIterator),
1349813510
0,
13511+
// bpo-40549: Py_TPFLAGS_BASETYPE should not be used, since
13512+
// PyType_GetModule(Py_TYPE(self)) doesn't work on a subclass instance.
1349913513
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_FINALIZE,
1350013514
ScandirIteratorType_slots
1350113515
};

0 commit comments

Comments
 (0)