mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-29 11:14:38 +08:00
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.