Unverified Commit 12e5913b authored by Kai Chen's avatar Kai Chen Committed by GitHub
Browse files

Remove supports for python 2.7 and bump version to 0.4.0 (#211)

* remove supports for python 2.7

* fix the unit test for python 3.5

* add python 3.8 in CI

* try ubuntu 18.04 as the environment
parent 2624090f
dist: xenial
dist: bionic
sudo: required
language: python
before_install:
- sudo add-apt-repository -y ppa:mc3man/xerus-media
- sudo apt-get update
- sudo apt-get install -y ffmpeg libjpeg-turbo*
- sudo apt-get install -y ffmpeg libturbojpeg
- pip install -U git+git://github.com/lilohuang/PyTurboJPEG.git
install:
- pip install torch==1.4.0+cpu torchvision==0.5.0+cpu -f https://download.pytorch.org/whl/torch_stable.html
- rm -rf .eggs && pip install -e . codecov flake8 yapf isort mock
- rm -rf .eggs && pip install -e .
cache:
pip: true
......@@ -23,8 +22,10 @@ python:
- "3.5"
- "3.6"
- "3.7"
- "3.8"
before_script:
- pip install codecov flake8 yapf isort
- flake8
- isort -rc --diff mmcv/ tests/ examples/
- yapf -r -d mmcv/ tests/ examples/
......@@ -41,7 +42,7 @@ deploy:
on:
branch: master
tags: true
python: "3.6"
python: "3.7"
distributions: sdist bdist_wheel
skip_cleanup: true
skip_upload_docs: true
......@@ -30,7 +30,7 @@ It provides the following functionalities.
See the `documentation <http://mmcv.readthedocs.io/en/latest>`_ for more features and usage.
Note: MMCV currently supports both Python 2.7 and 3.5+, but we plan to remove the support for Python 2. Please migrate to Python 3 as soon as possible.
Note: MMCV requires Python 3.5+.
Installation
......
......@@ -55,7 +55,7 @@ class TxtHandler1(mmcv.BaseFileHandler):
Here is an example of `PickleHandler`.
```python
from six.moves import cPickle as pickle
import pickle
class PickleHandler(mmcv.BaseFileHandler):
......
......@@ -2,9 +2,7 @@
from abc import ABCMeta, abstractmethod
class BaseFileHandler(object):
__metaclass__ = ABCMeta # python 2 compatibility
class BaseFileHandler(metaclass=ABCMeta):
@abstractmethod
def load_from_fileobj(self, file, **kwargs):
......
# Copyright (c) Open-MMLab. All rights reserved.
from six.moves import cPickle as pickle
import pickle
from .base import BaseFileHandler
......
......@@ -5,8 +5,8 @@ from .misc import (check_prerequisites, concat_list, is_list_of, is_seq_of,
is_str, is_tuple_of, iter_cast, list_cast,
requires_executable, requires_package, slice_list,
tuple_cast)
from .path import (FileNotFoundError, check_file_exist, fopen, is_filepath,
mkdir_or_exist, scandir, symlink)
from .path import (check_file_exist, fopen, is_filepath, mkdir_or_exist,
scandir, symlink)
from .progressbar import (ProgressBar, track_iter_progress,
track_parallel_progress, track_progress)
from .registry import Registry, build_from_cfg
......@@ -17,7 +17,7 @@ __all__ = [
'list_cast', 'tuple_cast', 'is_seq_of', 'is_list_of', 'is_tuple_of',
'slice_list', 'concat_list', 'check_prerequisites', 'requires_package',
'requires_executable', 'is_filepath', 'fopen', 'check_file_exist',
'mkdir_or_exist', 'symlink', 'scandir', 'FileNotFoundError', 'ProgressBar',
'track_progress', 'track_iter_progress', 'track_parallel_progress',
'Registry', 'build_from_cfg', 'Timer', 'TimerError', 'check_time'
'mkdir_or_exist', 'symlink', 'scandir', 'ProgressBar', 'track_progress',
'track_iter_progress', 'track_parallel_progress', 'Registry',
'build_from_cfg', 'Timer', 'TimerError', 'check_time'
]
......@@ -5,11 +5,11 @@ import shutil
import sys
import tempfile
from argparse import ArgumentParser
from collections import abc
from importlib import import_module
from addict import Dict
from .misc import collections_abc
from .path import check_file_exist
BASE_KEY = '_base_'
......@@ -46,7 +46,7 @@ def add_args(parser, cfg, prefix=''):
parser.add_argument('--' + prefix + k, action='store_true')
elif isinstance(v, dict):
add_args(parser, v, prefix + k + '.')
elif isinstance(v, collections_abc.Iterable):
elif isinstance(v, abc.Iterable):
parser.add_argument('--' + prefix + k, type=type(v[0]), nargs='+')
else:
print('cannot parse key {} of type {}'.format(prefix + k, type(v)))
......
# Copyright (c) Open-MMLab. All rights reserved.
import collections
import functools
import itertools
import subprocess
from collections import abc
from importlib import import_module
import six
# ABCs from collections will be deprecated in python 3.8+,
# while collections.abc is not available in python 2.7
try:
import collections.abc as collections_abc
except ImportError:
import collections as collections_abc
def is_str(x):
"""Whether the input is an string instance."""
return isinstance(x, six.string_types)
"""Whether the input is an string instance.
Note: This method is deprecated since python 2 is no longer supported.
"""
return isinstance(x, str)
def iter_cast(inputs, dst_type, return_type=None):
......@@ -32,12 +26,12 @@ def iter_cast(inputs, dst_type, return_type=None):
Returns:
iterator or specified type: The converted object.
"""
if not isinstance(inputs, collections_abc.Iterable):
if not isinstance(inputs, abc.Iterable):
raise TypeError('inputs must be an iterable object')
if not isinstance(dst_type, type):
raise TypeError('"dst_type" must be a valid type')
out_iterable = six.moves.map(dst_type, inputs)
out_iterable = map(dst_type, inputs)
if return_type is None:
return out_iterable
......@@ -73,7 +67,7 @@ def is_seq_of(seq, expected_type, seq_type=None):
bool: Whether the sequence is valid.
"""
if seq_type is None:
exp_seq_type = collections_abc.Sequence
exp_seq_type = abc.Sequence
else:
assert isinstance(seq_type, type)
exp_seq_type = seq_type
......
# Copyright (c) Open-MMLab. All rights reserved.
import os
import os.path as osp
import sys
from pathlib import Path
import six
from .misc import is_str
if sys.version_info <= (3, 3):
FileNotFoundError = IOError
else:
FileNotFoundError = FileNotFoundError
def is_filepath(x):
if is_str(x) or isinstance(x, Path):
......@@ -37,11 +29,7 @@ def mkdir_or_exist(dir_name, mode=0o777):
if dir_name == '':
return
dir_name = osp.expanduser(dir_name)
if six.PY3:
os.makedirs(dir_name, mode=mode, exist_ok=True)
else:
if not osp.isdir(dir_name):
os.makedirs(dir_name, mode=mode)
os.makedirs(dir_name, mode=mode, exist_ok=True)
def symlink(src, dst, overwrite=True, **kwargs):
......@@ -50,7 +38,9 @@ def symlink(src, dst, overwrite=True, **kwargs):
os.symlink(src, dst, **kwargs)
def _scandir_py35(dir_path, suffix=None):
def scandir(dir_path, suffix=None):
if (suffix is not None) and not isinstance(suffix, (str, tuple)):
raise TypeError('"suffix" must be a string or tuple of strings')
for entry in os.scandir(dir_path):
if not entry.is_file():
continue
......@@ -61,25 +51,6 @@ def _scandir_py35(dir_path, suffix=None):
yield filename
def _scandir_py(dir_path, suffix=None):
for filename in os.listdir(dir_path):
if not osp.isfile(osp.join(dir_path, filename)):
continue
if suffix is None:
yield filename
elif filename.endswith(suffix):
yield filename
def scandir(dir_path, suffix=None):
if suffix is not None and not isinstance(suffix, (str, tuple)):
raise TypeError('"suffix" must be a string or tuple of strings')
if sys.version_info >= (3, 5):
return _scandir_py35(dir_path, suffix)
else:
return _scandir_py(dir_path, suffix)
def find_vcs_root(path, markers=('.git', )):
"""Finds the root directory (including itself) of specified markers.
......
# Copyright (c) Open-MMLab. All rights reserved.
import sys
from collections.abc import Iterable
from multiprocessing import Pool
from shutil import get_terminal_size
from .misc import collections_abc
from .timer import Timer
......@@ -19,10 +20,6 @@ class ProgressBar(object):
@property
def terminal_width(self):
if sys.version_info > (3, 3):
from shutil import get_terminal_size
else:
from backports.shutil_get_terminal_size import get_terminal_size
width, _ = get_terminal_size()
return width
......@@ -79,11 +76,11 @@ def track_progress(func, tasks, bar_width=50, file=sys.stdout, **kwargs):
"""
if isinstance(tasks, tuple):
assert len(tasks) == 2
assert isinstance(tasks[0], collections_abc.Iterable)
assert isinstance(tasks[0], Iterable)
assert isinstance(tasks[1], int)
task_num = tasks[1]
tasks = tasks[0]
elif isinstance(tasks, collections_abc.Iterable):
elif isinstance(tasks, Iterable):
task_num = len(tasks)
else:
raise TypeError(
......@@ -145,11 +142,11 @@ def track_parallel_progress(func,
"""
if isinstance(tasks, tuple):
assert len(tasks) == 2
assert isinstance(tasks[0], collections_abc.Iterable)
assert isinstance(tasks[0], Iterable)
assert isinstance(tasks[1], int)
task_num = tasks[1]
tasks = tasks[0]
elif isinstance(tasks, collections_abc.Iterable):
elif isinstance(tasks, Iterable):
task_num = len(tasks)
else:
raise TypeError(
......@@ -193,11 +190,11 @@ def track_iter_progress(tasks, bar_width=50, file=sys.stdout, **kwargs):
"""
if isinstance(tasks, tuple):
assert len(tasks) == 2
assert isinstance(tasks[0], collections_abc.Iterable)
assert isinstance(tasks[0], Iterable)
assert isinstance(tasks[1], int)
task_num = tasks[1]
tasks = tasks[0]
elif isinstance(tasks, collections_abc.Iterable):
elif isinstance(tasks, Iterable):
task_num = len(tasks)
else:
raise TypeError(
......
# Copyright (c) Open-MMLab. All rights reserved.
__version__ = '0.3.2'
__version__ = '0.4.0'
......@@ -17,6 +17,6 @@ line_length = 79
multi_line_output = 0
known_standard_library = pkg_resources,setuptools
known_first_party = mmcv
known_third_party = Cython,addict,cv2,mock,numpy,pytest,resnet_cifar,six,torch,torchvision,yaml
known_third_party = Cython,addict,cv2,numpy,pytest,resnet_cifar,torch,torchvision,yaml
no_lines_before = STDLIB,LOCALFOLDER
default_section = THIRDPARTY
import platform
import re
import sys
from io import open # for Python 2 (identical to builtin in Python 3)
from pkg_resources import DistributionNotFound, get_distribution
from setuptools import Extension, dist, find_packages, setup
......@@ -24,11 +22,7 @@ def choose_requirement(primary, secondary):
return str(primary)
install_requires = ['addict', 'numpy', 'pyyaml', 'six']
if sys.version_info < (3, ):
install_requires.extend(
['backports.shutil_get_terminal_size', 'enum34', 'pathlib'])
install_requires = ['addict', 'numpy', 'pyyaml']
# If first not installed install second package
CHOOSE_INSTALL_REQUIRES = [('opencv-python-headless>=3', 'opencv-python>=3')]
......@@ -82,12 +76,11 @@ setup(
'Development Status :: 4 - Beta',
'License :: OSI Approved :: Apache Software License',
'Operating System :: OS Independent',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Topic :: Utilities',
],
url='https://github.com/open-mmlab/mmcv',
......
# Copyright (c) Open-MMLab. All rights reserved.
import json
import os.path as osp
import sys
import pytest
from mmcv import Config, FileNotFoundError
from mmcv import Config
def test_construct():
......@@ -25,7 +26,11 @@ def test_construct():
assert isinstance(cfg, Config)
assert cfg.filename == cfg_file
assert cfg.text == open(cfg_file, 'r').read()
assert cfg.dump() == format_text
if sys.version_info >= (3, 6):
assert cfg.dump() == format_text
else:
loaded = json.loads(cfg.dump())
assert set(loaded.keys()) == set(cfg_dict)
def test_fromfile():
......
import os.path as osp
import sys
import warnings
from mock import MagicMock
from unittest.mock import MagicMock
import mmcv.runner
......
......@@ -52,7 +52,7 @@ def test_requires_package(capsys):
def func_b():
pass
@mmcv.requires_package('six')
@mmcv.requires_package('numpy')
def func_c():
return 1
......
# Copyright (c) Open-MMLab. All rights reserved.
import os.path as osp
import sys
from pathlib import Path
import pytest
......@@ -22,12 +21,8 @@ def test_fopen():
def test_check_file_exist():
mmcv.check_file_exist(__file__)
if sys.version_info > (3, 3):
with pytest.raises(FileNotFoundError): # noqa
mmcv.check_file_exist('no_such_file.txt')
else:
with pytest.raises(IOError):
mmcv.check_file_exist('no_such_file.txt')
with pytest.raises(FileNotFoundError):
mmcv.check_file_exist('no_such_file.txt')
def test_scandir():
......@@ -43,4 +38,4 @@ def test_scandir():
])
assert set(mmcv.scandir(folder, '.png')) == set()
with pytest.raises(TypeError):
mmcv.scandir(folder, 111)
list(mmcv.scandir(folder, 111))
# Copyright (c) Open-MMLab. All rights reserved.
import os
import sys
import time
try:
......@@ -13,8 +12,6 @@ try:
except ImportError:
from io import StringIO
import pytest # isort:skip
import mmcv # isort:skip
......@@ -23,10 +20,6 @@ def reset_string_io(io):
io.seek(0)
if sys.version_info[0] == 2:
pytest.skip('skipping tests for python 2', allow_module_level=True)
class TestProgressBar(object):
def test_start(self):
......
......@@ -3,8 +3,7 @@ import os.path as osp
import sys
import tempfile
import warnings
from mock import MagicMock
from unittest.mock import MagicMock
sys.modules['wandb'] = MagicMock()
......@@ -59,6 +58,6 @@ def test_wandb_hook():
})
runner.register_hook(hook)
runner.run([loader, loader], [('train', 1), ('val', 1)], 1)
hook.wandb.init.assert_called()
hook.wandb.init.assert_called_with()
hook.wandb.log.assert_called_with({'accuracy/val': 0.98}, step=5)
hook.wandb.join.assert_called()
hook.wandb.join.assert_called_with()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment