Unverified Commit b7e8d7d7 authored by Cao Yuhang's avatar Cao Yuhang Committed by GitHub
Browse files

Use f-string (#245)

* use f-string

* delete python3.5 sup

* minor fix

* fix supported python version

* fix format

* fix yapf

* remove redundant space

* fix typo
parent 1e8a2121
......@@ -14,8 +14,8 @@ class MomentumUpdaterHook(Hook):
if warmup is not None:
if warmup not in ['constant', 'linear', 'exp']:
raise ValueError(
'"{}" is not a supported type for warming up, valid types'
' are "constant" and "linear"'.format(warmup))
f'"{warmup}" is not a supported type for warming up, valid'
' types are "constant" and "linear"')
if warmup is not None:
assert warmup_iters > 0, \
'"warmup_iters" must be a positive integer'
......@@ -160,7 +160,7 @@ class CyclicMomentumUpdaterHook(MomentumUpdaterHook):
if len(target_ratio) == 1 else target_ratio
else:
raise ValueError('target_ratio should be either float '
'or tuple, got {}'.format(type(target_ratio)))
f'or tuple, got {type(target_ratio)}')
assert len(target_ratio) == 2, \
'"target_ratio" must be list or tuple of two floats'
......
......@@ -151,7 +151,7 @@ class Runner(object):
elif not isinstance(optimizer, torch.optim.Optimizer):
raise TypeError(
'optimizer must be either an Optimizer object or a dict, '
'but got {}'.format(type(optimizer)))
f'but got {type(optimizer)}')
return optimizer
def _add_file_handler(self,
......@@ -182,7 +182,7 @@ class Runner(object):
format='%(asctime)s - %(levelname)s - %(message)s', level=level)
logger = logging.getLogger(__name__)
if log_dir and self.rank == 0:
filename = '{}.log'.format(self.timestamp)
filename = f'{self.timestamp}.log'
log_file = osp.join(log_dir, filename)
self._add_file_handler(logger, log_file, level=level)
return logger
......@@ -369,15 +369,14 @@ class Runner(object):
if isinstance(mode, str): # self.train()
if not hasattr(self, mode):
raise ValueError(
'runner has no method named "{}" to run an epoch'.
format(mode))
f'runner has no method named "{mode}" to run an '
'epoch')
epoch_runner = getattr(self, mode)
elif callable(mode): # custom train()
epoch_runner = mode
else:
raise TypeError('mode in workflow must be a str or '
'callable function, not {}'.format(
type(mode)))
f'callable function, not {type(mode)}')
for _ in range(epochs):
if mode == 'train' and self.epoch >= max_epochs:
return
......
......@@ -8,7 +8,7 @@ import mmcv
def get_host_info():
return '{}@{}'.format(getuser(), gethostname())
return f'{getuser()}@{gethostname()}'
def get_time_str():
......@@ -42,8 +42,8 @@ def obj_from_dict(info, parent=None, default_args=None):
else:
obj_type = sys.modules[obj_type]
elif not isinstance(obj_type, type):
raise TypeError('type must be a str or valid type, but got {}'.format(
type(obj_type)))
raise TypeError('type must be a str or valid type, but '
f'got {type(obj_type)}')
if default_args is not None:
for name, value in default_args.items():
args.setdefault(name, value)
......
......@@ -25,8 +25,8 @@ class ConfigDict(Dict):
try:
value = super(ConfigDict, self).__getattr__(name)
except KeyError:
ex = AttributeError("'{}' object has no attribute '{}'".format(
self.__class__.__name__, name))
ex = AttributeError(f"'{self.__class__.__name__}' object has no "
f"attribute '{name}'")
except Exception as e:
ex = e
else:
......@@ -49,7 +49,7 @@ def add_args(parser, cfg, prefix=''):
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)))
print(f'cannot parse key {prefix + k} of type {type(v)}')
return parser
......@@ -142,9 +142,9 @@ class Config(object):
if isinstance(v, dict) and k in b and not v.pop(DELETE_KEY, False):
if not isinstance(b[k], dict):
raise TypeError(
'{}={} cannot be inherited from base because {} is a '
'dict in the child config. You may set `{}=True` to '
'ignore the base config'.format(k, v, k, DELETE_KEY))
f'{k}={v} cannot be inherited from base because {k} '
'is a dict in the child config. You may '
f'set `{DELETE_KEY}=True` to ignore the base config')
Config._merge_a_into_b(v, b[k])
else:
b[k] = v
......@@ -171,8 +171,8 @@ class Config(object):
if cfg_dict is None:
cfg_dict = dict()
elif not isinstance(cfg_dict, dict):
raise TypeError('cfg_dict must be a dict, but got {}'.format(
type(cfg_dict)))
raise TypeError('cfg_dict must be a dict, but '
f'got {type(cfg_dict)}')
super(Config, self).__setattr__('_cfg_dict', ConfigDict(cfg_dict))
super(Config, self).__setattr__('_filename', filename)
......@@ -210,10 +210,10 @@ class Config(object):
def _format_basic_types(k, v):
if isinstance(v, str):
v_str = "'{}'".format(v)
v_str = f"'{v}'"
else:
v_str = str(v)
attr_str = '{}={}'.format(str(k), v_str)
attr_str = f'{str(k)}={v_str}'
attr_str = _indent(attr_str, indent)
return attr_str
......@@ -223,9 +223,9 @@ class Config(object):
if all(isinstance(_, dict) for _ in v):
v_str = '[\n'
v_str += '\n'.join(
'dict({}),'.format(_indent(_format_dict(v_), indent))
f'dict({_indent(_format_dict(v_), indent)}),'
for v_ in v).rstrip(',')
attr_str = '{}={}'.format(str(k), v_str)
attr_str = f'{str(k)}={v_str}'
attr_str = _indent(attr_str, indent) + ']'
else:
attr_str = _format_basic_types(k, v)
......@@ -239,7 +239,7 @@ class Config(object):
end = '' if outest_level or is_last else ','
if isinstance(v, dict):
v_str = '\n' + _format_dict(v)
attr_str = '{}=dict({}'.format(str(k), v_str)
attr_str = f'{str(k)}=dict({v_str}'
attr_str = _indent(attr_str, indent) + ')' + end
elif isinstance(v, list):
attr_str = _format_list(k, v) + end
......@@ -256,8 +256,7 @@ class Config(object):
return text
def __repr__(self):
return 'Config (path: {}): {}'.format(self.filename,
self._cfg_dict.__repr__())
return f'Config (path: {self.filename}): {self._cfg_dict.__repr__()}'
def __len__(self):
return len(self._cfg_dict)
......
......@@ -90,4 +90,4 @@ def print_log(msg, logger=None, level=logging.INFO):
else:
raise TypeError(
'logger should be either a logging.Logger object, str, '
'"silent" or None, but got {}'.format(type(logger)))
f'"silent" or None, but got {type(logger)}')
......@@ -111,9 +111,8 @@ def slice_list(in_list, lens):
if not isinstance(lens, list):
raise TypeError('"indices" must be an integer or a list of integers')
elif sum(lens) != len(in_list):
raise ValueError(
'sum of lens and list length does not match: {} != {}'.format(
sum(lens), len(in_list)))
raise ValueError('sum of lens and list length does not '
f'match: {sum(lens)} != {len(in_list)}')
out_list = []
idx = 0
for i in range(len(lens)):
......@@ -182,7 +181,7 @@ def _check_py_package(package):
def _check_executable(cmd):
if subprocess.call('which {}'.format(cmd), shell=True) != 0:
if subprocess.call(f'which {cmd}', shell=True) != 0:
return False
else:
return True
......
......@@ -25,8 +25,8 @@ class ProgressBar(object):
def start(self):
if self.task_num > 0:
self.file.write('[{}] 0/{}, elapsed: 0s, ETA:'.format(
' ' * self.bar_width, self.task_num))
self.file.write(f'[{" " * self.bar_width}] 0/{self.task_num}, '
'elapsed: 0s, ETA:')
else:
self.file.write('completed: 0, elapsed: 0s')
self.file.flush()
......@@ -42,9 +42,9 @@ class ProgressBar(object):
if self.task_num > 0:
percentage = self.completed / float(self.task_num)
eta = int(elapsed * (1 - percentage) / percentage + 0.5)
msg = '\r[{{}}] {}/{}, {:.1f} task/s, elapsed: {}s, ETA: {:5}s' \
''.format(self.completed, self.task_num, fps,
int(elapsed + 0.5), eta)
msg = f'\r[{{}}] {self.completed}/{self.task_num}, ' \
f'{fps:.1f} task/s, elapsed: {int(elapsed + 0.5)}s, ' \
f'ETA: {eta:5}s'
bar_width = min(self.bar_width,
int(self.terminal_width - len(msg)) + 2,
......@@ -55,8 +55,8 @@ class ProgressBar(object):
self.file.write(msg.format(bar_chars))
else:
self.file.write(
'completed: {}, elapsed: {}s, {:.1f} tasks/s'.format(
self.completed, int(elapsed + 0.5), fps))
f'completed: {self.completed}, elapsed: {int(elapsed + 0.5)}s,'
f' {fps:.1f} tasks/s')
self.file.flush()
......
......@@ -22,8 +22,9 @@ class Registry(object):
return self.get(key) is not None
def __repr__(self):
format_str = self.__class__.__name__ + '(name={}, items={})'.format(
self._name, list(self._module_dict.keys()))
format_str = self.__class__.__name__ + \
f'(name={self._name}, ' \
f'items={list(self._module_dict.keys())})'
return format_str
@property
......@@ -47,12 +48,12 @@ class Registry(object):
def _register_module(self, module_class, force=False):
if not inspect.isclass(module_class):
raise TypeError('module must be a class, but got {}'.format(
type(module_class)))
raise TypeError('module must be a class, '
f'but got {type(module_class)}')
module_name = module_class.__name__
if not force and module_name in self._module_dict:
raise KeyError('{} is already registered in {}'.format(
module_name, self.name))
raise KeyError(f'{module_name} is already registered '
f'in {self.name}')
self._module_dict[module_name] = module_class
def register_module(self, cls=None, force=False):
......@@ -99,26 +100,24 @@ def build_from_cfg(cfg, registry, default_args=None):
if not (isinstance(cfg, dict) and 'type' in cfg):
raise TypeError('cfg must be a dict containing the key "type"')
if not isinstance(registry, Registry):
raise TypeError(
'registry must be an mmcv.Registry object, but got {}'.format(
type(registry)))
raise TypeError('registry must be an mmcv.Registry object, '
f'but got {type(registry)}')
if not (isinstance(default_args, dict) or default_args is None):
raise TypeError(
'default_args must be a dict or None, but got {}'.format(
type(default_args)))
raise TypeError('default_args must be a dict or None, '
f'but got {type(default_args)}')
args = cfg.copy()
obj_type = args.pop('type')
if is_str(obj_type):
obj_cls = registry.get(obj_type)
if obj_cls is None:
raise KeyError('{} is not in the {} registry'.format(
obj_type, registry.name))
raise KeyError(
f'{obj_type} is not in the {registry.name} registry')
elif inspect.isclass(obj_type):
obj_cls = obj_type
else:
raise TypeError('type must be a str or valid type, but got {}'.format(
type(obj_type)))
raise TypeError(
f'type must be a str or valid type, but got {type(obj_type)}')
if default_args is not None:
for name, value in default_args.items():
......
......@@ -166,8 +166,7 @@ class VideoReader(object):
"""
if frame_id < 0 or frame_id >= self._frame_cnt:
raise IndexError(
'"frame_id" must be between 0 and {}'.format(self._frame_cnt -
1))
f'"frame_id" must be between 0 and {self._frame_cnt - 1}')
if frame_id == self._position:
return self.read()
if self._cache:
......
......@@ -22,25 +22,22 @@ def flowread(flow_or_path, quantize=False, concat_axis=0, *args, **kwargs):
"""
if isinstance(flow_or_path, np.ndarray):
if (flow_or_path.ndim != 3) or (flow_or_path.shape[-1] != 2):
raise ValueError('Invalid flow with shape {}'.format(
flow_or_path.shape))
raise ValueError(f'Invalid flow with shape {flow_or_path.shape}')
return flow_or_path
elif not is_str(flow_or_path):
raise TypeError(
'"flow_or_path" must be a filename or numpy array, not {}'.format(
type(flow_or_path)))
raise TypeError(f'"flow_or_path" must be a filename or numpy array, '
f'not {type(flow_or_path)}')
if not quantize:
with open(flow_or_path, 'rb') as f:
try:
header = f.read(4).decode('utf-8')
except Exception:
raise IOError('Invalid flow file: {}'.format(flow_or_path))
raise IOError(f'Invalid flow file: {flow_or_path}')
else:
if header != 'PIEH':
raise IOError(
'Invalid flow file: {}, header does not contain PIEH'.
format(flow_or_path))
raise IOError(f'Invalid flow file: {flow_or_path}, '
'header does not contain PIEH')
w = np.fromfile(f, np.int32, 1).squeeze()
h = np.fromfile(f, np.int32, 1).squeeze()
......@@ -50,8 +47,8 @@ def flowread(flow_or_path, quantize=False, concat_axis=0, *args, **kwargs):
cat_flow = imread(flow_or_path, flag='unchanged')
if cat_flow.ndim != 2:
raise IOError(
'{} is not a valid quantized flow file, its dimension is {}.'.
format(flow_or_path, cat_flow.ndim))
f'{flow_or_path} is not a valid quantized flow file, '
f'its dimension is {cat_flow.ndim}.')
assert cat_flow.shape[concat_axis] % 2 == 0
dx, dy = np.split(cat_flow, 2, axis=concat_axis)
flow = dequantize_flow(dx, dy, *args, **kwargs)
......
......@@ -35,17 +35,17 @@ def convert_video(in_file,
for k, v in kwargs.items():
if isinstance(v, bool):
if v:
options.append('-{}'.format(k))
options.append(f'-{k}')
elif k == 'log_level':
assert v in [
'quiet', 'panic', 'fatal', 'error', 'warning', 'info',
'verbose', 'debug', 'trace'
]
options.append('-loglevel {}'.format(v))
options.append(f'-loglevel {v}')
else:
options.append('-{} {}'.format(k, v))
cmd = 'ffmpeg -y {} -i {} {} {}'.format(pre_options, in_file,
' '.join(options), out_file)
options.append(f'-{k} {v}')
cmd = f'ffmpeg -y {pre_options} -i {in_file} {" ".join(options)} ' \
f'{out_file}'
if print_cmd:
print(cmd)
subprocess.call(cmd, shell=True)
......@@ -79,15 +79,14 @@ def resize_video(in_file,
options = {'log_level': log_level}
if size:
if not keep_ar:
options['vf'] = 'scale={}:{}'.format(size[0], size[1])
options['vf'] = f'scale={size[0]}:{size[1]}'
else:
options['vf'] = ('scale=w={}:h={}:force_original_aspect_ratio'
'=decrease'.format(size[0], size[1]))
options['vf'] = f'scale=w={size[0]}:h={size[1]}:' \
'force_original_aspect_ratio=decrease'
else:
if not isinstance(ratio, tuple):
ratio = (ratio, ratio)
options['vf'] = 'scale="trunc(iw*{}):trunc(ih*{})"'.format(
ratio[0], ratio[1])
options['vf'] = f'scale="trunc(iw*{ratio[0]}):trunc(ih*{ratio[1]})"'
convert_video(in_file, out_file, print_cmd, **options)
......@@ -148,7 +147,7 @@ def concat_video(video_list,
_, tmp_filename = tempfile.mkstemp(suffix='.txt', text=True)
with open(tmp_filename, 'w') as f:
for filename in video_list:
f.write('file {}\n'.format(osp.abspath(filename)))
f.write(f'file {osp.abspath(filename)}\n')
options = {'log_level': log_level}
if vcodec is None:
options['vcodec'] = 'copy'
......
......@@ -48,4 +48,4 @@ def color_val(color):
color = color.astype(np.uint8)
return tuple(color)
else:
raise TypeError('Invalid type for color: {}'.format(type(color)))
raise TypeError(f'Invalid type for color: {type(color)}')
......@@ -130,9 +130,9 @@ def imshow_det_bboxes(img,
cv2.rectangle(
img, left_top, right_bottom, bbox_color, thickness=thickness)
label_text = class_names[
label] if class_names is not None else 'cls {}'.format(label)
label] if class_names is not None else f'cls {label}'
if len(bbox) > 4:
label_text += '|{:.02f}'.format(bbox[-1])
label_text += f'|{bbox[-1]:.02f}'
cv2.putText(img, label_text, (bbox_int[0], bbox_int[1] - 2),
cv2.FONT_HERSHEY_COMPLEX, font_scale, text_color)
......
......@@ -442,23 +442,23 @@ class TestGeometric:
patches = mmcv.imcrop(self.img, bboxes)
assert len(patches) == bboxes.shape[0]
for i in range(len(patches)):
ref_patch = np.load(patch_path + '/{}.npy'.format(i))
ref_patch = np.load(patch_path + f'/{i}.npy')
assert_array_equal(patches[i], ref_patch)
# crop with scaling and no padding
patches = mmcv.imcrop(self.img, bboxes, 1.2)
for i in range(len(patches)):
ref_patch = np.load(patch_path + '/scale_{}.npy'.format(i))
ref_patch = np.load(patch_path + f'/scale_{i}.npy')
assert_array_equal(patches[i], ref_patch)
# crop with scaling and padding
patches = mmcv.imcrop(self.img, bboxes, 1.2, pad_fill=[255, 255, 0])
for i in range(len(patches)):
ref_patch = np.load(patch_path + '/pad_{}.npy'.format(i))
ref_patch = np.load(patch_path + f'/pad_{i}.npy')
assert_array_equal(patches[i], ref_patch)
patches = mmcv.imcrop(self.img, bboxes, 1.2, pad_fill=0)
for i in range(len(patches)):
ref_patch = np.load(patch_path + '/pad0_{}.npy'.format(i))
ref_patch = np.load(patch_path + f'/pad0_{i}.npy')
assert_array_equal(patches[i], ref_patch)
def test_impad(self):
......
......@@ -37,16 +37,14 @@ class TestProgressBar(object):
# with total task num
reset_string_io(out)
prog_bar = mmcv.ProgressBar(10, bar_width=bar_width, file=out)
assert out.getvalue() == '[{}] 0/10, elapsed: 0s, ETA:'.format(
' ' * bar_width)
assert out.getvalue() == f'[{" " * bar_width}] 0/10, elapsed: 0s, ETA:'
reset_string_io(out)
prog_bar = mmcv.ProgressBar(
10, bar_width=bar_width, start=False, file=out)
assert out.getvalue() == ''
reset_string_io(out)
prog_bar.start()
assert out.getvalue() == '[{}] 0/10, elapsed: 0s, ETA:'.format(
' ' * bar_width)
assert out.getvalue() == f'[{" " * bar_width}] 0/10, elapsed: 0s, ETA:'
def test_update(self):
out = StringIO()
......@@ -63,9 +61,8 @@ class TestProgressBar(object):
time.sleep(1)
reset_string_io(out)
prog_bar.update()
assert out.getvalue() == ('\r[{}] 1/10, 1.0 task/s, '
'elapsed: 1s, ETA: 9s'.format('>' * 2 +
' ' * 18))
assert out.getvalue() == f'\r[{">" * 2 + " " * 18}] 1/10, 1.0 ' \
'task/s, elapsed: 1s, ETA: 9s'
def test_adaptive_length(self):
with patch.dict('os.environ', {'COLUMNS': '80'}):
......
......@@ -22,7 +22,7 @@ class TestCache(object):
def test_put(self):
cache = mmcv.Cache(3)
for i in range(1, 4):
cache.put('k{}'.format(i), i)
cache.put(f'k{i}', i)
assert cache.size == i
assert cache._cache == OrderedDict([('k1', 1), ('k2', 2), ('k3', 3)])
cache.put('k4', 4)
......@@ -139,7 +139,7 @@ class TestVideo(object):
v.cvt2frames(frame_dir)
assert osp.isdir(frame_dir)
for i in range(self.num_frames):
filename = '{}/{:06d}.jpg'.format(frame_dir, i)
filename = f'{frame_dir}/{i:06d}.jpg'
assert osp.isfile(filename)
os.remove(filename)
......@@ -147,7 +147,7 @@ class TestVideo(object):
v.cvt2frames(frame_dir, show_progress=False)
assert osp.isdir(frame_dir)
for i in range(self.num_frames):
filename = '{}/{:06d}.jpg'.format(frame_dir, i)
filename = f'{frame_dir}/{i:06d}.jpg'
assert osp.isfile(filename)
os.remove(filename)
......@@ -160,7 +160,7 @@ class TestVideo(object):
max_num=20)
assert osp.isdir(frame_dir)
for i in range(100, 120):
filename = '{}/{:03d}.JPEG'.format(frame_dir, i)
filename = f'{frame_dir}/{i:03d}.JPEG'
assert osp.isfile(filename)
os.remove(filename)
shutil.rmtree(frame_dir)
......@@ -171,7 +171,7 @@ class TestVideo(object):
v.cvt2frames(frame_dir)
assert osp.isdir(frame_dir)
for i in range(self.num_frames):
filename = '{}/{:06d}.jpg'.format(frame_dir, i)
filename = f'{frame_dir}/{i:06d}.jpg'
assert osp.isfile(filename)
out_filename = osp.join(tempfile.gettempdir(), 'mmcv_test.avi')
......@@ -192,7 +192,7 @@ class TestVideo(object):
assert len(v) == 40
for i in range(self.num_frames):
filename = '{}/{:06d}.jpg'.format(frame_dir, i)
filename = f'{frame_dir}/{i:06d}.jpg'
os.remove(filename)
shutil.rmtree(frame_dir)
os.remove(out_filename)
......
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