diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c72d1f93b..9200adbb6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,4 +22,4 @@ repos: rev: v3.20.0 hooks: - id: pyupgrade - args: [--py3-only] + args: [--py310-plus] diff --git a/taskflow/atom.py b/taskflow/atom.py index 5e173a8f2..a6eba50e5 100644 --- a/taskflow/atom.py +++ b/taskflow/atom.py @@ -377,7 +377,7 @@ class Atom(metaclass=abc.ABCMeta): """ def __str__(self): - return '"{}=={}"'.format(self.name, misc.get_version_string(self)) + return f'"{self.name}=={misc.get_version_string(self)}"' def __repr__(self): - return '<{} {}>'.format(reflection.get_class_name(self), self) + return f'<{reflection.get_class_name(self)} {self}>' diff --git a/taskflow/engines/action_engine/compiler.py b/taskflow/engines/action_engine/compiler.py index b3019d0ce..92517d460 100644 --- a/taskflow/engines/action_engine/compiler.py +++ b/taskflow/engines/action_engine/compiler.py @@ -49,7 +49,7 @@ class Terminator: def __init__(self, flow): self._flow = flow - self._name = "{}[$]".format(self._flow.name) + self._name = f"{self._flow.name}[$]" @property def flow(self): diff --git a/taskflow/engines/worker_based/proxy.py b/taskflow/engines/worker_based/proxy.py index 7ff9b68e4..311e4065d 100644 --- a/taskflow/engines/worker_based/proxy.py +++ b/taskflow/engines/worker_based/proxy.py @@ -143,7 +143,7 @@ class Proxy: def _make_queue(self, routing_key, exchange, channel=None): """Make a named queue for the given exchange.""" - queue_name = "{}_{}".format(self._exchange_name, routing_key) + queue_name = f"{self._exchange_name}_{routing_key}" return kombu.Queue(name=queue_name, routing_key=routing_key, durable=False, exchange=exchange, auto_delete=True, diff --git a/taskflow/examples/create_parallel_volume.py b/taskflow/examples/create_parallel_volume.py index c579566c9..add1baaf0 100644 --- a/taskflow/examples/create_parallel_volume.py +++ b/taskflow/examples/create_parallel_volume.py @@ -43,7 +43,7 @@ def show_time(name): start = time.time() yield end = time.time() - print(" -- {} took {:0.3f} seconds".format(name, end - start)) + print(f" -- {name} took {end - start:0.3f} seconds") # This affects how many volumes to create and how much time to *simulate* @@ -83,7 +83,7 @@ class VolumeCreator(task.Task): # volume create can be resumed/revert, and is much easier to use for # audit and tracking purposes. base_name = reflection.get_callable_name(self) - super().__init__(name="{}-{}".format(base_name, volume_id)) + super().__init__(name=f"{base_name}-{volume_id}") self._volume_id = volume_id def execute(self): diff --git a/taskflow/examples/dump_memory_backend.py b/taskflow/examples/dump_memory_backend.py index ad093b4ff..798b15c62 100644 --- a/taskflow/examples/dump_memory_backend.py +++ b/taskflow/examples/dump_memory_backend.py @@ -65,6 +65,6 @@ print("---------") for path in backend.memory.ls_r(backend.memory.root_path, absolute=True): value = backend.memory[path] if value: - print("{} -> {}".format(path, value)) + print(f"{path} -> {value}") else: print("%s" % (path)) diff --git a/taskflow/examples/fake_billing.py b/taskflow/examples/fake_billing.py index c16672a53..435e3a395 100644 --- a/taskflow/examples/fake_billing.py +++ b/taskflow/examples/fake_billing.py @@ -137,7 +137,7 @@ class ActivateDriver(task.Task): def update_progress(self, progress, **kwargs): # Override the parent method to also print out the status. super().update_progress(progress, **kwargs) - print("{} is {:0.2f}% done".format(self.name, progress * 100)) + print(f"{self.name} is {progress * 100:0.2f}% done") class DeclareSuccess(task.Task): diff --git a/taskflow/examples/graph_flow.py b/taskflow/examples/graph_flow.py index 253545029..e90d8158c 100644 --- a/taskflow/examples/graph_flow.py +++ b/taskflow/examples/graph_flow.py @@ -97,7 +97,7 @@ print("Single threaded engine result %s" % result) for (name, value) in expected: actual = result.get(name) if actual != value: - sys.stderr.write("{} != {}\n".format(actual, value)) + sys.stderr.write(f"{actual} != {value}\n") unexpected += 1 result = taskflow.engines.run( @@ -107,7 +107,7 @@ print("Multi threaded engine result %s" % result) for (name, value) in expected: actual = result.get(name) if actual != value: - sys.stderr.write("{} != {}\n".format(actual, value)) + sys.stderr.write(f"{actual} != {value}\n") unexpected += 1 if unexpected: diff --git a/taskflow/examples/hello_world.py b/taskflow/examples/hello_world.py index 26fd952da..e048d8f6a 100644 --- a/taskflow/examples/hello_world.py +++ b/taskflow/examples/hello_world.py @@ -41,7 +41,7 @@ class PrinterTask(task.Task): def execute(self, output): if self._show_name: - print("{}: {}".format(self.name, output)) + print(f"{self.name}: {output}") else: print(output) diff --git a/taskflow/examples/jobboard_produce_consume_colors.py b/taskflow/examples/jobboard_produce_consume_colors.py index 54dd05277..aa197cfee 100644 --- a/taskflow/examples/jobboard_produce_consume_colors.py +++ b/taskflow/examples/jobboard_produce_consume_colors.py @@ -82,9 +82,9 @@ def dispatch_work(job): def safe_print(name, message, prefix=""): with STDOUT_LOCK: if prefix: - print("{} {}: {}".format(prefix, name, message)) + print(f"{prefix} {name}: {message}") else: - print("{}: {}".format(name, message)) + print(f"{name}: {message}") def worker(ident, client, consumed): @@ -136,7 +136,7 @@ def producer(ident, client): safe_print(name, "started") with backends.backend(name, SHARED_CONF.copy(), client=client) as board: for i in range(0, PRODUCER_UNITS): - job_name = "{}-{}".format(name, i) + job_name = f"{name}-{i}" details = { 'color': random.choice(['red', 'blue']), } diff --git a/taskflow/examples/pseudo_scoping.py b/taskflow/examples/pseudo_scoping.py index 5ad08956c..736d050ab 100644 --- a/taskflow/examples/pseudo_scoping.py +++ b/taskflow/examples/pseudo_scoping.py @@ -65,7 +65,7 @@ class CallTask(task.Task): """Task that calls person by number.""" def execute(self, person, number): - print('Calling {} {}.'.format(person, number)) + print(f'Calling {person} {number}.') # This is how it works for one person: @@ -82,7 +82,7 @@ taskflow.engines.run(simple_flow, store={'person': 'Josh'}) # we use `rebind` argument of task constructor. def subflow_factory(prefix): def pr(what): - return '{}-{}'.format(prefix, what) + return f'{prefix}-{what}' return lf.Flow(pr('flow')).add( FetchNumberTask(pr('fetch'), diff --git a/taskflow/examples/resume_from_backend.py b/taskflow/examples/resume_from_backend.py index 911deeae9..47fcdbb7d 100644 --- a/taskflow/examples/resume_from_backend.py +++ b/taskflow/examples/resume_from_backend.py @@ -60,7 +60,7 @@ import example_utils as eu # noqa def print_task_states(flowdetail, msg): eu.print_wrapped(msg) - print("Flow '{}' state: {}".format(flowdetail.name, flowdetail.state)) + print(f"Flow '{flowdetail.name}' state: {flowdetail.state}") # Sort by these so that our test validation doesn't get confused by the # order in which the items in the flow detail can be in. items = sorted((td.name, td.version, td.state, td.results) diff --git a/taskflow/examples/resume_many_flows/resume_all.py b/taskflow/examples/resume_many_flows/resume_all.py index 682c200dc..cc8098b67 100644 --- a/taskflow/examples/resume_many_flows/resume_all.py +++ b/taskflow/examples/resume_many_flows/resume_all.py @@ -37,7 +37,7 @@ FINISHED_STATES = (states.SUCCESS, states.FAILURE, states.REVERTED) def resume(flowdetail, backend): - print('Resuming flow {} {}'.format(flowdetail.name, flowdetail.uuid)) + print(f'Resuming flow {flowdetail.name} {flowdetail.uuid}') engine = taskflow.engines.load_from_detail(flow_detail=flowdetail, backend=backend) engine.run() diff --git a/taskflow/examples/resume_vm_boot.py b/taskflow/examples/resume_vm_boot.py index 1e68cb57a..8ba8ac187 100644 --- a/taskflow/examples/resume_vm_boot.py +++ b/taskflow/examples/resume_vm_boot.py @@ -110,7 +110,7 @@ class DownloadImages(task.Task): def execute(self, image_locations): for src, loc in image_locations.items(): with slow_down(1): - print("Downloading from {} => {}".format(src, loc)) + print(f"Downloading from {src} => {loc}") return sorted(image_locations.values()) @@ -149,7 +149,7 @@ class WriteNetworkSettings(task.Task): def execute(self, download_paths, network_settings): for j, path in enumerate(download_paths): with slow_down(1): - print("Mounting {} to /tmp/{}".format(path, j)) + print(f"Mounting {path} to /tmp/{j}") for i, setting in enumerate(network_settings): filename = ("/tmp/etc/sysconfig/network-scripts/" "ifcfg-eth%s" % (i)) diff --git a/taskflow/examples/run_by_iter_enumerate.py b/taskflow/examples/run_by_iter_enumerate.py index 0e9ef5301..91c613019 100644 --- a/taskflow/examples/run_by_iter_enumerate.py +++ b/taskflow/examples/run_by_iter_enumerate.py @@ -49,4 +49,4 @@ e.compile() e.prepare() for i, st in enumerate(e.run_iter(), 1): - print("Transition {}: {}".format(i, st)) + print(f"Transition {i}: {st}") diff --git a/taskflow/examples/share_engine_thread.py b/taskflow/examples/share_engine_thread.py index d4d248e40..7984e6fff 100644 --- a/taskflow/examples/share_engine_thread.py +++ b/taskflow/examples/share_engine_thread.py @@ -45,7 +45,7 @@ class DelayedTask(task.Task): self._wait_for = random.random() def execute(self): - print("Running '{}' in thread '{}'".format(self.name, tu.get_ident())) + print(f"Running '{self.name}' in thread '{tu.get_ident()}'") time.sleep(self._wait_for) diff --git a/taskflow/examples/switch_graph_flow.py b/taskflow/examples/switch_graph_flow.py index ca32a4e95..fb4c19313 100644 --- a/taskflow/examples/switch_graph_flow.py +++ b/taskflow/examples/switch_graph_flow.py @@ -62,7 +62,7 @@ while entries: path = entries.pop() value = backend.memory[path] if value: - print("{} -> {}".format(path, value)) + print(f"{path} -> {value}") else: print("%s" % (path)) entries.extend(os.path.join(path, child) diff --git a/taskflow/examples/tox_conductor.py b/taskflow/examples/tox_conductor.py index 92b20884c..ed79c3bc2 100644 --- a/taskflow/examples/tox_conductor.py +++ b/taskflow/examples/tox_conductor.py @@ -58,7 +58,7 @@ from taskflow.utils import threading_utils RUN_TIME = 5 REVIEW_CREATION_DELAY = 0.5 SCAN_DELAY = 0.1 -NAME = "{}_{}".format(socket.getfqdn(), os.getpid()) +NAME = f"{socket.getfqdn()}_{os.getpid()}" # This won't really use zookeeper but will use a local version of it using # the zake library that mimics an actual zookeeper cluster using threads and diff --git a/taskflow/formatters.py b/taskflow/formatters.py index 69bc5bfc2..dc660736d 100644 --- a/taskflow/formatters.py +++ b/taskflow/formatters.py @@ -120,7 +120,7 @@ class FailureFormatter: atom_attrs['provides'] = self._mask_keys( provides, self._mask_outputs_keys) if atom_attrs: - return "Atom '{}' {}".format(atom_name, atom_attrs) + return f"Atom '{atom_name}' {atom_attrs}" else: return "Atom '%s'" % (atom_name) else: @@ -170,7 +170,7 @@ class FailureFormatter: rooted_tree = builder(graph, atom) child_count = rooted_tree.child_count(only_direct=False) buff.write_nl( - '{} {} (most recent first):'.format(child_count, kind)) + f'{child_count} {kind} (most recent first):') formatter = functools.partial(self._format_node, storage, cache) direct_child_count = rooted_tree.child_count(only_direct=True) for i, child in enumerate(rooted_tree, 1): diff --git a/taskflow/jobs/backends/impl_etcd.py b/taskflow/jobs/backends/impl_etcd.py index d598f4373..2a0e500d4 100644 --- a/taskflow/jobs/backends/impl_etcd.py +++ b/taskflow/jobs/backends/impl_etcd.py @@ -377,14 +377,14 @@ class EtcdJobBoard(base.JobBoard): """Returns how many jobs are on this jobboard.""" return len(self._job_cache) - def get_owner_data(self, job: EtcdJob) -> typing.Optional[dict]: + def get_owner_data(self, job: EtcdJob) -> dict | None: owner_key = job.key + self.LOCK_POSTFIX owner_data = self.get_one(owner_key) if not owner_data: return None return jsonutils.loads(owner_data) - def find_owner(self, job: EtcdJob) -> typing.Optional[dict]: + def find_owner(self, job: EtcdJob) -> dict | None: """Gets the owner of the job if one exists.""" data = self.get_owner_data(job) if data: @@ -396,7 +396,7 @@ class EtcdJobBoard(base.JobBoard): return self.get_one(key) def get_owner_and_data(self, job: EtcdJob) -> tuple[ - typing.Optional[str], typing.Optional[bytes]]: + str | None, bytes | None]: if self._client is None: raise exc.JobFailure("Cannot retrieve information, " "not connected") diff --git a/taskflow/listeners/timing.py b/taskflow/listeners/timing.py index ec80fc2f1..284b4600a 100644 --- a/taskflow/listeners/timing.py +++ b/taskflow/listeners/timing.py @@ -118,7 +118,7 @@ class PrintingDurationListener(DurationListener): def _receiver(self, item_type, item_name, state): super()._receiver(item_type, item_name, state) if state in STARTING_STATES: - self._printer("'{}' {} started.".format(item_name, item_type)) + self._printer(f"'{item_name}' {item_type} started.") class EventTimeListener(base.Listener): diff --git a/taskflow/persistence/backends/__init__.py b/taskflow/persistence/backends/__init__.py index 628653e47..a4a1a8303 100644 --- a/taskflow/persistence/backends/__init__.py +++ b/taskflow/persistence/backends/__init__.py @@ -62,7 +62,7 @@ def fetch(conf, namespace=BACKEND_NAMESPACE, **kwargs): invoke_kwds=kwargs) return mgr.driver except RuntimeError as e: - raise exc.NotFound("Could not find backend {}: {}".format(backend, e)) + raise exc.NotFound(f"Could not find backend {backend}: {e}") @contextlib.contextmanager diff --git a/taskflow/test.py b/taskflow/test.py index 99bfe482c..d57ab3028 100644 --- a/taskflow/test.py +++ b/taskflow/test.py @@ -36,7 +36,7 @@ class GreaterThanEqual: def match(self, other): if other >= self.source: return None - return matchers.Mismatch("{} was not >= {}".format(other, self.source)) + return matchers.Mismatch(f"{other} was not >= {self.source}") class FailureRegexpMatcher: diff --git a/taskflow/tests/unit/persistence/base.py b/taskflow/tests/unit/persistence/base.py index 9f8a0628d..5096963ca 100644 --- a/taskflow/tests/unit/persistence/base.py +++ b/taskflow/tests/unit/persistence/base.py @@ -71,7 +71,7 @@ class PersistenceTestMixin: lb_ids = {} for i in range(0, 10): lb_id = uuidutils.generate_uuid() - lb_name = 'lb-{}-{}'.format(i, lb_id) + lb_name = f'lb-{i}-{lb_id}' lb = models.LogBook(name=lb_name, uuid=lb_id) lb_ids[lb_id] = True diff --git a/taskflow/tests/unit/persistence/test_sql_persistence.py b/taskflow/tests/unit/persistence/test_sql_persistence.py index 28c03ca72..b292683ad 100644 --- a/taskflow/tests/unit/persistence/test_sql_persistence.py +++ b/taskflow/tests/unit/persistence/test_sql_persistence.py @@ -59,7 +59,7 @@ def _get_connect_string(backend, user, passwd, database=None, variant=None): raise Exception("Unrecognized backend: '%s'" % backend) if not database: database = '' - return "{}://{}:{}@localhost/{}".format(backend, user, passwd, database) + return f"{backend}://{user}:{passwd}@localhost/{database}" def _mysql_exists(): diff --git a/taskflow/tests/unit/worker_based/test_proxy.py b/taskflow/tests/unit/worker_based/test_proxy.py index 4525fe6bc..1d77d22be 100644 --- a/taskflow/tests/unit/worker_based/test_proxy.py +++ b/taskflow/tests/unit/worker_based/test_proxy.py @@ -70,7 +70,7 @@ class TestProxy(test.MockTestCase): self.resetMasterMock() def _queue_name(self, topic): - return "{}_{}".format(self.exchange, topic) + return f"{self.exchange}_{topic}" def proxy_start_calls(self, calls, exc_type=mock.ANY): return [ diff --git a/taskflow/types/graph.py b/taskflow/types/graph.py index c22f88716..bb38f0cb6 100644 --- a/taskflow/types/graph.py +++ b/taskflow/types/graph.py @@ -29,15 +29,15 @@ def _common_format(g, edge_notation): lines.append("Nodes: %s" % g.number_of_nodes()) for n, n_data in g.nodes(data=True): if n_data: - lines.append(" - {} ({})".format(n, n_data)) + lines.append(f" - {n} ({n_data})") else: lines.append(" - %s" % n) lines.append("Edges: %s" % g.number_of_edges()) for (u, v, e_data) in g.edges(data=True): if e_data: - lines.append(" {} {} {} ({})".format(u, edge_notation, v, e_data)) + lines.append(f" {u} {edge_notation} {v} ({e_data})") else: - lines.append(" {} {} {}".format(u, edge_notation, v)) + lines.append(f" {u} {edge_notation} {v}") return lines diff --git a/taskflow/types/sets.py b/taskflow/types/sets.py index 679d80d7a..f9c24d429 100644 --- a/taskflow/types/sets.py +++ b/taskflow/types/sets.py @@ -64,7 +64,7 @@ class OrderedSet(abc.Set, abc.Hashable): return tuple(self) def __repr__(self): - return "{}({})".format(type(self).__name__, list(self)) + return f"{type(self).__name__}({list(self)})" def copy(self): """Return a shallow copy of a set.""" diff --git a/taskflow/utils/banner.py b/taskflow/utils/banner.py index 8242f2b9d..9ed2175e6 100644 --- a/taskflow/utils/banner.py +++ b/taskflow/utils/banner.py @@ -86,9 +86,9 @@ def make_banner(what, chapters): sections = chapter_contents for j, section in enumerate(sections): if j + 1 < len(sections): - buf.write_nl(" {}. {}".format(j + 1, section)) + buf.write_nl(f" {j + 1}. {section}") else: - buf.write(" {}. {}".format(j + 1, section)) + buf.write(f" {j + 1}. {section}") else: raise TypeError("Unsupported chapter contents" " type: one of dict, list, tuple, set expected" diff --git a/taskflow/utils/kazoo_utils.py b/taskflow/utils/kazoo_utils.py index be931c900..becd4d74a 100644 --- a/taskflow/utils/kazoo_utils.py +++ b/taskflow/utils/kazoo_utils.py @@ -39,7 +39,7 @@ def _parse_hosts(hosts): if isinstance(hosts, (dict)): host_ports = [] for (k, v) in hosts.items(): - host_ports.append("{}:{}".format(k, v)) + host_ports.append(f"{k}:{v}") hosts = host_ports if isinstance(hosts, (list, set, tuple)): return ",".join([str(h) for h in hosts]) @@ -63,7 +63,7 @@ def prettify_failures(failures, limit=-1): pass pretty_op += "(%s)" % (", ".join(selected_attrs)) pretty_cause = reflection.get_class_name(r, fully_qualified=False) - prettier.append("{}@{}".format(pretty_cause, pretty_op)) + prettier.append(f"{pretty_cause}@{pretty_op}") if limit <= 0 or len(prettier) <= limit: return ", ".join(prettier) else: diff --git a/taskflow/utils/misc.py b/taskflow/utils/misc.py index 5ac88ec54..b5765c441 100644 --- a/taskflow/utils/misc.py +++ b/taskflow/utils/misc.py @@ -187,7 +187,7 @@ def find_subclasses(locations, base_cls, exclude_hidden=True): except ValueError: module = importutils.import_module(item) else: - obj = importutils.import_class('{}.{}'.format(pkg, cls)) + obj = importutils.import_class(f'{pkg}.{cls}') if not reflection.is_subclass(obj, base_cls): raise TypeError("Object '%s' (%s) is not a '%s' subclass" % (item, type(item), base_cls)) diff --git a/taskflow/version.py b/taskflow/version.py index ccf75f7a4..272acadd0 100644 --- a/taskflow/version.py +++ b/taskflow/version.py @@ -26,4 +26,4 @@ def version_string_with_package(): if TASK_PACKAGE is None: return version_string() else: - return "{}-{}".format(version_string(), TASK_PACKAGE) + return f"{version_string()}-{TASK_PACKAGE}" diff --git a/tools/state_graph.py b/tools/state_graph.py index ea86cd0cd..3535f4b33 100755 --- a/tools/state_graph.py +++ b/tools/state_graph.py @@ -185,7 +185,7 @@ def main(): print(g.to_string().strip()) g.write(options.filename, format=options.format) - print("Created {} at '{}'".format(options.format, options.filename)) + print(f"Created {options.format} at '{options.filename}'") # To make the svg more pretty use the following: # $ xsltproc ../diagram-tools/notugly.xsl ./states.svg > pretty-states.svg