Files
pytorch/torch/utils/file_baton.py
Hugo van Kemenade 09896eda14 Fix version comparisons for Python 3.6, 3.10 and 4 (#32389)
Summary:
There's some code which uses `six.PY3`, similar to:

```python
if six.PY3:
    print("Python 3+ code")
else:
    print "Python 2 code"
```

Where:

```python
PY3 = sys.version_info[0] == 3
```

When run on Python 4, this will run the Python 2 code! Instead, use `six.PY2` and avoid `six.PY3`.

 ---

Similarly, there's some `sys.version_info[0] == 3` checks, better done as `sys.version_info[0] >= 3`.

 ---

Also, it's better to avoid comparing the `sys.version` string, as it makes assumptions that each version component is exactly one character long, which will break in Python 3.10:

```pycon
>>> sys.version
'3.8.1 (v3.8.1:1b293b6006, Dec 18 2019, 14:08:53) \n[Clang 6.0 (clang-600.0.57)]'
>>> sys.version < "3.3"
False
>>> fake_v3_10 = '3.10.1 (v3.8.1:1b293b6006, Dec 18 2019, 14:08:53) \n[Clang 6.0 (clang-600.0.57)]'
>>> fake_v3_10 < "3.3"
True
```

 ---

Finally, I think the intention here is to skip when the Python version is < 3.6:

```python
unittest.skipIf(sys.version_info[0] < 3 and sys.version_info[1] < 6, "dict not ordered")
```

However, it will really skip for Python 0.0-0.5, 1.0-1.5 and 2.0-2.5. It's best to compare to the `sys.version_info` tuple and not `sys.version_info[1]`:

```python
    unittest.skipIf(sys.version_info < (3, 6), "dict not ordered")
```

 ---

Found using https://github.com/asottile/flake8-2020:
```console
$ pip install -U flake8-2020
$ flake8 --select YTT
```

Pull Request resolved: https://github.com/pytorch/pytorch/pull/32389

Reviewed By: zou3519

Differential Revision: D24424662

Pulled By: ezyang

fbshipit-source-id: 1266c4dbcc8ae4d2e2e9b1d7357cba854562177c
2020-10-21 11:52:50 -07:00

50 lines
1.4 KiB
Python

import os
import time
class FileBaton:
'''A primitive, file-based synchronization utility.'''
def __init__(self, lock_file_path, wait_seconds=0.1):
'''
Creates a new :class:`FileBaton`.
Args:
lock_file_path: The path to the file used for locking.
wait_seconds: The seconds to periorically sleep (spin) when
calling ``wait()``.
'''
self.lock_file_path = lock_file_path
self.wait_seconds = wait_seconds
self.fd = None
def try_acquire(self):
'''
Tries to atomically create a file under exclusive access.
Returns:
True if the file could be created, else False.
'''
try:
self.fd = os.open(self.lock_file_path, os.O_CREAT | os.O_EXCL)
return True
except FileExistsError:
return False
def wait(self):
'''
Periodically sleeps for a certain amount until the baton is released.
The amount of time slept depends on the ``wait_seconds`` parameter
passed to the constructor.
'''
while os.path.exists(self.lock_file_path):
time.sleep(self.wait_seconds)
def release(self):
'''Releases the baton and removes its file.'''
if self.fd is not None:
os.close(self.fd)
os.remove(self.lock_file_path)