Commit 31fdb20
authored
Allow fcntl functions to accept objects with fileno() function (RustPython#4144)
As specified in Python official documentation
(https://docs.python.org/3.10/library/fcntl.html)
> All functions in this module take a file descriptor fd as their first
> argument. This can be an integer file descriptor, such as returned by
> sys.stdin.fileno(), or an io.IOBase object, such as sys.stdin itself,
> which provides a fileno() that returns a genuine file descriptor.
And clarified more in fcntl.fcntl function:
> Perform the operation cmd on file descriptor fd (file objects
> providing a fileno() method are accepted as well).
All function in fcntl modules should accept either int fd or object with
fileno() function which returns int fd.
This was already implemented with for `fcntl.fcntl` function with
`io::Fildes` newtype helper which extracted either int fd or called
fileno() function, and it was also implemented with duplicated ad-hoc
code for `fcntl.ioctl`.
This commit replaces the ad-hoc implementation with `io::Fildes` and
adds it to missing functions: `fcntl.flock` and `fcntl.lockf`.
For more information that this is implemented in the same way as
CPython, you can check the corresponding CPython module:
https://github.com/python/cpython/blob/3.10/Modules/clinic/fcntlmodule.c.h
The functions are: `fcntl_fcntl`, `fcntl_ioctl`, `fcntl_flock` and
`fcntl_lockf`, all of these functions use
`_PyLong_FileDescriptor_Converter` which does the same thing as
RustPython's `io::Fildes`, meaning it either extracts the argument as
int fd or calls fileno() function on passed object that returns the int
fd.
Here is the implementation for `_PyLong_FileDescriptor_Converter`:
https://github.com/python/cpython/blob/3.10/Objects/fileobject.c#L227
which in turns calls `PyObject_AsFileDescriptor` which is located here
https://github.com/python/cpython/blob/3.10/Objects/fileobject.c#L180 in
the same file and we can see that it tries to convert it to int or call
fileno() function.
Note regarding the python unit tests `test_flock`,
`test_lockf_exclusive`, `test_lockf_shared`:
The tests no longer fail with `TypeError: 'BufferedRandom' object cannot
be interpreted as an integer` which makes `test_flock` pass the test,
but `test_lockf_exclusive` and `test_lockf_exclusive` still fail but not
on fcntl calls, they fail on `Process()` constructor with
`AttributeError: module 'os' has no attribute 'fork'` which seems
unrelated with this change.
This unrelated error was probably never detected as fcntl calls failed
earlier, before `Process()` could even be called.1 parent 8001ff8 commit 31fdb20
2 files changed
+5
-17
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
141 | 141 | | |
142 | 142 | | |
143 | 143 | | |
144 | | - | |
145 | | - | |
146 | 144 | | |
147 | 145 | | |
148 | 146 | | |
| |||
157 | 155 | | |
158 | 156 | | |
159 | 157 | | |
160 | | - | |
| 158 | + | |
161 | 159 | | |
162 | 160 | | |
163 | 161 | | |
| |||
170 | 168 | | |
171 | 169 | | |
172 | 170 | | |
173 | | - | |
| 171 | + | |
174 | 172 | | |
175 | 173 | | |
176 | 174 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
52 | 52 | | |
53 | 53 | | |
54 | 54 | | |
55 | | - | |
56 | 55 | | |
57 | 56 | | |
58 | 57 | | |
| |||
90 | 89 | | |
91 | 90 | | |
92 | 91 | | |
93 | | - | |
| 92 | + | |
94 | 93 | | |
95 | 94 | | |
96 | 95 | | |
97 | 96 | | |
98 | 97 | | |
99 | | - | |
100 | | - | |
101 | | - | |
102 | | - | |
103 | | - | |
104 | | - | |
105 | | - | |
106 | | - | |
107 | | - | |
108 | 98 | | |
109 | 99 | | |
110 | 100 | | |
| |||
153 | 143 | | |
154 | 144 | | |
155 | 145 | | |
156 | | - | |
| 146 | + | |
157 | 147 | | |
158 | 148 | | |
159 | 149 | | |
| |||
166 | 156 | | |
167 | 157 | | |
168 | 158 | | |
169 | | - | |
| 159 | + | |
170 | 160 | | |
171 | 161 | | |
172 | 162 | | |
| |||
0 commit comments