Skip to content

Commit

Permalink
Fix flake8 C408: unnecessary collecion calls.
Browse files Browse the repository at this point in the history
`dict`, `list` or `tuple` calls can be rewritten as empty literals.
The former is slower because the name `dict` must be looked up in
the global scope in case it has been rebound.
  • Loading branch information
martinhoyer committed Apr 20, 2023
1 parent 51a3ac8 commit 9ffff4d
Show file tree
Hide file tree
Showing 17 changed files with 77 additions and 78 deletions.
2 changes: 1 addition & 1 deletion examples/plugins/provision.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def go(self):
print("go() called")

# Data dictionary is used to pass information among classes.
data = dict(what='Another default what. Object variable can be used.')
data = {'what': 'Another default what. Object variable can be used.'}

for opt in ['what', 'switch']:
val = self.get(opt)
Expand Down
1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ select = [
"RUF", # ruff
]
ignore = [
"C408", # Unnecessary `dict` call (rewrite as a literal)
"C416", # Unnecessary `list` comprehension (rewrite using `list()`)
"C401", # Unnecessary generator (rewrite as a `set` comprehension)
"C405", # Unnecessary `list` literal (rewrite as a `set` literal)
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/test_adjust.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def check(condition, expected):

def test_empty():
""" Empty relevancy """
assert relevancy_to_adjust('') == list()
assert relevancy_to_adjust('') == []


def test_comments(full):
Expand Down
26 changes: 13 additions & 13 deletions tests/unit/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,17 @@ def test_invalid_yaml_syntax():

def test_test_defaults(root_logger):
""" Test default test attributes """
test = tmt.Test.from_dict(logger=root_logger, mapping=dict(test='./test.sh'), name='/smoke')
test = tmt.Test.from_dict(logger=root_logger, mapping={'test': './test.sh'}, name='/smoke')
assert test.name == '/smoke'
assert test.component == list()
assert test.component == []
assert str(test.test) == './test.sh'
assert test.path == Path('/')
assert test.require == list()
assert test.environment == dict()
assert test.require == []
assert test.environment == {}
assert test.duration == '5m'
assert test.enabled is True
assert test.result == 'respect'
assert test.tag == list()
assert test.tag == []


def test_test_invalid(root_logger):
Expand Down Expand Up @@ -100,20 +100,20 @@ def test_link():
assert Links(data=['one', 'two']).get() == [
Link(relation='relates', target='one'), Link(relation='relates', target='two')]
# Multiple string mixed relation
assert Links(data=['implicit', dict(duplicates='explicit')]).get() == [
assert Links(data=['implicit', {'duplicates': 'explicit'}]).get() == [
Link(relation='relates', target='implicit'),
Link(relation='duplicates', target='explicit')]
# Multiple strings (explicit relation)
assert Links(data=[dict(parent='mom'), dict(child='son')]).get() == [
assert Links(data=[{'parent': 'mom'}, {'child': 'son'}]).get() == [
Link(relation='parent', target='mom'), Link(relation='child', target='son')]

# Single dictionary (default relation)
assert Links(data=dict(name='foo')).get() == [
assert Links(data={'name': 'foo'}).get() == [
Link(relation='relates', target=FmfId(name='foo'))]
# Single dictionary (explicit relation)
assert Links(data=dict(verifies='foo')).get() == [Link(relation='verifies', target='foo')]
assert Links(data={'verifies': 'foo'}).get() == [Link(relation='verifies', target='foo')]
# Multiple dictionaries
family = [dict(parent='mom', note='foo'), dict(child='son')]
family = [{'parent': 'mom', 'note': 'foo'}, {'child': 'son'}]
assert Links(data=family).get() == [
Link(relation='parent', target='mom', note='foo'), Link(relation='child', target='son')
]
Expand Down Expand Up @@ -142,12 +142,12 @@ def test_link():
with pytest.raises(SpecificationError, match='Invalid link'):
Links(data=123)
with pytest.raises(SpecificationError, match='Multiple relations'):
Links(data=dict(verifies='one', blocks='another'))
Links(data={'verifies': 'one', 'blocks': 'another'})
with pytest.raises(SpecificationError, match='Invalid link relation'):
Links(data=dict(depends='other'))
Links(data={'depends': 'other'})

# Searching for links
links = Links(data=[dict(parent='mom', note='foo'), dict(child='son', note='bar')])
links = Links(data=[{'parent': 'mom', 'note': 'foo'}, {'child': 'son', 'note': 'bar'}])
assert links.has_link()
assert links.has_link(needle=LinkNeedle())
assert links.has_link(needle=LinkNeedle(relation=r'.*', target=r'.*'))
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@ def test_listify():
assert listify('abc') == ['abc']
assert listify('a b c') == ['a b c']
assert listify('a b c', split=True) == ['a', 'b', 'c']
assert listify(dict(a=1, b=2)) == dict(a=[1], b=[2])
assert listify(dict(a=1, b=2), keys=['a']) == dict(a=[1], b=2)
assert listify({'a': 1, 'b': 2}) == {'a': [1], 'b': [2]}
assert listify({'a': 1, 'b': 2}, keys=['a']) == {'a': [1], 'b': 2}


def test_config():
Expand Down
12 changes: 6 additions & 6 deletions tmt/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -631,7 +631,7 @@ def _export(self, *, keys: Optional[List[str]] = None) -> tmt.export._RawExporte
keys = self._keys()

# Always include node name, add requested keys, ignore adjust
data: Dict[str, Any] = dict(name=self.name)
data: Dict[str, Any] = {'name': self.name}
for key in keys:
# TODO: provide more mature solution for https://github.com/teemtee/tmt/issues/1688
# Until that, do not export fields that start with an underscore, to avoid leaking
Expand Down Expand Up @@ -956,7 +956,7 @@ def show(self) -> None:
[require.to_minimal_spec() for require in cast(List[Require], value)]
))
continue
if value not in [None, list(), dict()]:
if value not in [None, [], {}]:
echo(tmt.utils.format(key, value))
if self.opt('verbose'):
self._show_additional_keys()
Expand All @@ -967,7 +967,7 @@ def show(self) -> None:
if key in self._keys():
continue
value = self.node.get(key)
if value not in [None, list(), dict()]:
if value not in [None, [], {}]:
echo(tmt.utils.format(key, value, key_color='blue'))

def _lint_manual(self, test_path: Path) -> bool:
Expand Down Expand Up @@ -1262,7 +1262,7 @@ def _get_environment_vars(self, node: fmf.Tree) -> EnvironmentType:
# Environment variables from key, make sure that values are string
environment = {
key: str(value) for key, value
in node.get('environment', dict()).items()}
in node.get('environment', {}).items()}

# Combine both sources into one ('environment' key takes precendence)
combined.update(environment)
Expand Down Expand Up @@ -2407,7 +2407,7 @@ def __init__(self,
self._workdir_path: WorkdirArgumentType = id_ or True
self._tree = tree
self._plans: Optional[List[Plan]] = None
self._environment_from_workdir: EnvironmentType = dict()
self._environment_from_workdir: EnvironmentType = {}
self._environment_from_options: Optional[EnvironmentType] = None
self.remove = self.opt('remove')

Expand Down Expand Up @@ -2453,7 +2453,7 @@ def environment(self) -> EnvironmentType:
# Gather environment variables from options only once
if self._environment_from_options is None:
assert self.tree is not None # narrow type
self._environment_from_options = dict()
self._environment_from_options = {}
# Variables gathered from 'environment-file' options
self._environment_from_options.update(
tmt.utils.environment_files_to_dict(
Expand Down
2 changes: 1 addition & 1 deletion tmt/beakerlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ def _library_cache(self) -> Dict[str, 'Library']:
# Initialize library cache (indexed by the repository name)
# FIXME: cast() - https://github.com/teemtee/tmt/issues/1372
if not hasattr(self.parent, '_library_cache'):
cast(CommonWithLibraryCache, self.parent)._library_cache = dict()
cast(CommonWithLibraryCache, self.parent)._library_cache = {}

return cast(CommonWithLibraryCache, self.parent)._library_cache

Expand Down
22 changes: 11 additions & 11 deletions tmt/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ def write_markdown(path: Path, content: Dict[str, str]) -> None:
def add_link(target: str, data: NitrateDataType,
system: int = SYSTEM_BUGZILLA, type_: str = 'relates') -> None:
""" Add relevant link into data under the 'link' key """
new_link = dict()
new_link = {}
if system == SYSTEM_BUGZILLA:
new_link[type_] = f"{BUGZILLA_URL}{target}"
elif system == SYSTEM_JIRA:
Expand Down Expand Up @@ -201,7 +201,7 @@ def read_datafile(
Returns task name and a dictionary of the collected values.
"""

data: NitrateDataType = dict()
data: NitrateDataType = {}
makefile_regex_test = r'^run:.*\n\t(.*)$'
if filename == 'Makefile':
regex_task = r'Name:[ \t]*(.*)$'
Expand Down Expand Up @@ -657,8 +657,8 @@ def read_nitrate(
echo("Multiple test cases found for '{0}'.".format(beaker_task))

# Process individual test cases
individual_data = list()
md_content = dict()
individual_data = []
md_content = {}
for testcase in testcases:
# Testcase data must be fetched due to
# https://github.com/psss/python-nitrate/issues/24
Expand Down Expand Up @@ -704,8 +704,8 @@ def read_nitrate(
common_data.pop('description')

# Find common data from individual test cases
common_candidates = dict()
histogram = dict()
common_candidates = {}
histogram = {}
for testcase in individual_data:
if individual_data.index(testcase) == 0:
common_candidates = copy.copy(testcase)
Expand Down Expand Up @@ -1032,7 +1032,7 @@ def write(path: Path, data: NitrateDataType) -> None:
'adjust', 'extra-nitrate',
'extra-summary', 'extra-task',
'extra-hardware', 'extra-pepa']
sorted_data = dict()
sorted_data = {}
for key in tmt.base.Test._keys() + extra_keys:
try:
sorted_data[key] = data[key]
Expand All @@ -1056,8 +1056,8 @@ def relevancy_to_adjust(
Expects a string or list of strings with relevancy rules.
Returns a list of dictionaries with adjust rules.
"""
rules = list()
rule = dict()
rules = []
rule = {}
if isinstance(relevancy, list):
relevancy = '\n'.join(str(line) for line in relevancy)

Expand Down Expand Up @@ -1089,7 +1089,7 @@ def relevancy_to_adjust(
f"Invalid test case relevancy decision '{decision}'.")

# Adjust condition syntax
expressions = list()
expressions = []
for expression in re.split(r'\s*&&?\s*', condition):
search_result = re.search(RELEVANCY_EXPRESSION, expression)
if search_result is None:
Expand Down Expand Up @@ -1132,6 +1132,6 @@ def relevancy_to_adjust(
rule['when'] = ' and '.join(expressions)
rule['continue'] = False
rules.append(rule)
rule = dict()
rule = {}

return rules
2 changes: 1 addition & 1 deletion tmt/export/nitrate.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ def convert_manual_to_nitrate(test_md: Path) -> SectionsReturnType:
break

def concatenate_headings_content(headings: Tuple[str, ...]) -> HeadingsType:
content = list()
content = []
for v in headings:
content += sections_headings[v]
return content
Expand Down
2 changes: 1 addition & 1 deletion tmt/log.py
Original file line number Diff line number Diff line change
Expand Up @@ -655,7 +655,7 @@ def _log(
labels=self.labels,
labels_padding=self.labels_padding)

self._logger._log(level, message, tuple(), extra={'details': details})
self._logger._log(level, message, (), extra={'details': details})

def print(
self,
Expand Down
4 changes: 2 additions & 2 deletions tmt/steps/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1072,7 +1072,7 @@ def phases(cls, step: Step) -> List[int]:
@classmethod
def _parse_phases(cls, step: Step) -> Dict[str, List[int]]:
""" Parse options and store phase order """
phases = dict()
phases = {}
options: List[str] = cls._opt('step', default=[])

# Use the end of the last enabled step if no --step given
Expand Down Expand Up @@ -1112,7 +1112,7 @@ def _parse_phases(cls, step: Step) -> Dict[str, List[int]]:
# Convert 'start' and 'end' aliases
try:
phase = cast(Dict[str, int],
dict(start=PHASE_START, end=PHASE_END))[phase]
{'start': PHASE_START, 'end': PHASE_END})[phase]
except KeyError:
raise tmt.utils.GeneralError(f"Invalid phase '{phase}'.")
# Store the phase for given step
Expand Down
2 changes: 1 addition & 1 deletion tmt/steps/discover/shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ def fetch_remote_repository(
def go(self) -> None:
""" Discover available tests """
super(DiscoverShell, self).go()
tests = fmf.Tree(dict(summary='tests'))
tests = fmf.Tree({'summary': 'tests'})

assert self.workdir is not None
testdir = self.workdir / "tests"
Expand Down
44 changes: 22 additions & 22 deletions tmt/steps/prepare/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,48 +177,48 @@ def go(self) -> None:
])

if requires:
data: _RawPrepareStepData = dict(
how='install',
name='requires',
summary='Install required packages',
order=tmt.utils.DEFAULT_PLUGIN_ORDER_REQUIRES,
package=[
data: _RawPrepareStepData = {
'how': 'install',
'name': 'requires',
'summary': 'Install required packages',
'order': tmt.utils.DEFAULT_PLUGIN_ORDER_REQUIRES,
'package': [
require.to_spec()
for require in tmt.base.assert_simple_requirements(
requires,
'After beakerlib processing, tests may have only simple requirements',
self._logger)
])
]}
self._phases.append(PreparePlugin.delegate(self, raw_data=data))

# Recommended packages
recommends = uniq(self.plan.discover.recommends())
if recommends:
data = dict(
how='install',
name='recommends',
summary='Install recommended packages',
order=tmt.utils.DEFAULT_PLUGIN_ORDER_RECOMMENDS,
package=[
data = {
'how': 'install',
'name': 'recommends',
'summary': 'Install recommended packages',
'order': tmt.utils.DEFAULT_PLUGIN_ORDER_RECOMMENDS,
'package': [
recommend.to_spec()
for recommend in tmt.base.assert_simple_requirements(
recommends,
'After beakerlib processing, tests may have only simple requirements',
self._logger)
],
missing='skip')
'missing': 'skip'}
self._phases.append(PreparePlugin.delegate(self, raw_data=data))

# Implicit multihost setup
if self.plan.provision.is_multihost:
data = dict(
how='multihost',
name='multihost',
summary='Setup guest for multihost testing',
order=tmt.utils.DEFAULT_PLUGIN_ORDER_MULTIHOST,
roles=self._prepare_roles(),
hosts=self._prepare_hosts(),
)
data = {
'how': 'multihost',
'name': 'multihost',
'summary': 'Setup guest for multihost testing',
'order': tmt.utils.DEFAULT_PLUGIN_ORDER_MULTIHOST,
'roles': self._prepare_roles(),
'hosts': self._prepare_hosts(),
}
self._phases.append(PreparePlugin.delegate(self, raw_data=data))

# Prepare guests (including workdir sync)
Expand Down
6 changes: 3 additions & 3 deletions tmt/steps/provision/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ def is_ready(self) -> bool:
@classmethod
def options(cls, how: Optional[str] = None) -> List[tmt.options.ClickOptionDecoratorType]:
""" Prepare command line options related to guests """
return list()
return []

def load(self, data: GuestData) -> None:
"""
Expand Down Expand Up @@ -310,8 +310,8 @@ def _prepare_environment(
""" Prepare dict of environment variables """
# Prepare environment variables so they can be correctly passed
# to shell. Create a copy to prevent modifying source.
environment: tmt.utils.EnvironmentType = dict()
environment.update(execute_environment or dict())
environment: tmt.utils.EnvironmentType = {}
environment.update(execute_environment or {})
# Plan environment and variables provided on the command line
# override environment provided to execute().
# FIXME: cast() - https://github.com/teemtee/tmt/issues/1372
Expand Down
2 changes: 1 addition & 1 deletion tmt/steps/provision/local.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def execute(self,
**kwargs: Any) -> tmt.utils.CommandOutput:
""" Execute command on localhost """
# Prepare the environment (plan/cli variables override)
environment: tmt.utils.EnvironmentType = dict()
environment: tmt.utils.EnvironmentType = {}
environment.update(env or {})
environment.update(self.parent.plan.environment)

Expand Down
Loading

0 comments on commit 9ffff4d

Please sign in to comment.