This test was marked as an expected failure. Because the garbage
collector is missing, that meant that the `os.scandir` object went
unclosed. This object was squatting on the file descriptors of all the
files contained in the test directory, which was breaking test_zipfile.
In cpython, they use `_PyTime_ROUND_FLOOR` to read time.
But in RustPython, we use `[Duration::from_secs_f64](https://doc.rust-lang.org/std/time/struct.Duration.html#method.try_from_secs_f64)` to read time.
Therefore, RustPython isn't affected by the rounding issue in the way
that cpython does. We can safely ignore the `0.5*1e-9` bit in
`ns_to_sec` function.
Initially this is only meant to be a small update for `test_io.py`.
But it turns out that `test.support` need a lot of cleanup especially
for `test.support.warnings_helper`.
Change `perform_on_metadata` to fit python document and tests.
From python document ->
> Return True if this entry is a directory or a symbolic link pointing to a directory;
> return False if the entry is or points to any other kind of file, or if it doesn’t exist anymore.
> ...
> This method can raise OSError, such as PermissionError, but FileNotFoundError is caught and not raised.
> - [python doc](https://docs.python.org/3/library/os.html?highlight=direntry#os.DirEntry.is_dir)
Use `std::os::unix::fs::DirEntryExt` on unix to get inode and
use `stat_inner` for other platfrom to get stat and cache
inode into `AtomicCell<Option<u64>>`.
Currently on windows platform in `stat_inner` inode will only contains
default value (0).
Following code used to fail due to the way used to define
os.open in rust. To fix this, we need to use `FromArgs`
to define `struct OpenArgs {...}`.
```
f = os.open(path=__file__, flags=os.O_RDONLY, mode=0o777, dir_fd=None)
```
Noted that the original `open` is now rename to `os_open`
and is exported as `open`.
Related to #1175