This also fixes a bug in the log2() implementation, where very large
negative integer arguments would not raise an exception (and instead
would turn into NaNs).
Though it actually create a getset descriptor,
we didn't change the name because its concept was a property for writers.
Now we have `pymember`, another property-like descriptor. So naming them under
same level would be less confusing instead of telling everybody
"it is a getset but we call it pyproperty"
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.