Repository: pywbem/pywbemtools (language: python)

Issue:
Applied pyupgrade on source files
For details, see the commit message.


Discussion / hints:

[![Coverage Status](https://coveralls.io/builds/69047268/badge)](https://coveralls.io/builds/69047268)

coverage: 92.97% (+0.1%) from 92.869%
when pulling **b599fa090379bdd00724a790c46069f22a27e622 on andy/pyupgrade**
into **7308fc8abc218ad319214115ba48c1f225a2e1fd on master**.

I have done your two suggestions in this PR, plus removed the `run_sphinx` switch in the Makefile.

There are still the following changes to be looked at:
* `PYWBEM_1_0_0` conditional flag
* `NEWSTYLE_SUPPORTED` conditional flag - that one is now always True, but do we still support old style mock scripts ?
* Several uses of `sys.version_info` (some related to old style mock scripts)
We discussed the remaining version condition flags, and decided to address them in separate PRs:
* https://github.com/pywbem/pywbemtools/issues/1406
* https://github.com/pywbem/pywbemtools/issues/1405
* https://github.com/pywbem/pywbemtools/issues/1407


Fix patch:
diff --git a/docs/changes.rst b/docs/changes.rst
index d02352c7..3c02cd9e 100644
--- a/docs/changes.rst
+++ b/docs/changes.rst
@@ -173,6 +173,9 @@ Released: 2024-04-20
 * Changed the format of the README and README_PYPI files from RST to Markdown,
   to address formatting issues with badges on the Github site (issue #1376).
 
+* Changed string formatting statements (ex. click.echo, click.ClickException,
+  etc.) to use f-string formating as much as is logical rather than .format(...).
+
 
 pywbemtools 1.2.0
 -----------------
diff --git a/docs/pywbemcli/mock_support.rst b/docs/pywbemcli/mock_support.rst
index 3d36334c..07e1ee50 100644
--- a/docs/pywbemcli/mock_support.rst
+++ b/docs/pywbemcli/mock_support.rst
@@ -902,8 +902,8 @@ of the target CIM instance and returns that property in an output parameter
                 if isinstance(localobject, CIMClassName):
                     raise CIMError(
                         CIM_ERR_INVALID_PARAMETER,
-                        "CIM method {0} must be invoked on a CIM instance".
-                        format(methodname))
+                        f"CIM method {methodname} must be invoked on a "
+                        "CIM instance")
                 return self.Method1(localobject, params)
             else:
                 raise CIMError(CIM_ERR_METHOD_NOT_AVAILABLE)
diff --git a/pywbemtools/_click_extensions.py b/pywbemtools/_click_extensions.py
index 3db4fc81..ff5685ff 100644
--- a/pywbemtools/_click_extensions.py
+++ b/pywbemtools/_click_extensions.py
@@ -273,9 +273,8 @@ def __init__(self, *args, **kwargs):
         # If flag set, add comment to help
         if self.mutually_exclusive and show_mutually_exclusive_flag:
             help_txt = kwargs.get('help', '')
-            kwargs['help'] = "{0} This option is mutually exclusive with " \
-                "options: ({1}).". \
-                format(help_txt, self._mutually_exclusive_display())
+            kwargs['help'] = f"{help_txt} This option is mutually exclusive " \
+                f"with options: ({self._mutually_exclusive_display()})."
 
         super().__init__(*args, **kwargs)
 
@@ -286,11 +285,11 @@ def handle_parse_result(self, ctx, opts, args):
         """
         me_internal = {i.replace('-', '_') for i in self.mutually_exclusive}
         if me_internal.intersection(opts) and self.name in opts:
+            lname = self.name.replace('_', '-')
+            ldisp = self._mutually_exclusive_display()
             raise click.UsageError(
-                "Conflicting options: `{0}` is mutually exclusive with "
-                "options: ({1}).".
-                format(self.name.replace('_', '-'),
-                       self._mutually_exclusive_display()))
+                f"Conflicting options: `{lname}` is mutually exclusive with "
+                f"options: ({ldisp}).")
 
         return super().handle_parse_result(
             ctx, opts, args)
diff --git a/pywbemtools/_common_cmd_actions.py b/pywbemtools/_common_cmd_actions.py
index c52690c5..2839d4b5 100644
--- a/pywbemtools/_common_cmd_actions.py
+++ b/pywbemtools/_common_cmd_actions.py
@@ -115,12 +115,10 @@ def get_subjects_summary_as_table(subject_names, obj, title=None):
 
     # If multiple matches, return summary of all that match
     if len(partial_subjects) > 1:
-        title = "{0} Input: `{1}` matches multiple subjects:` `{2}`". \
-            format(minimum_subjects_table_title,
-                   subject, ', '.join(partial_subjects))
+        title = f"{minimum_subjects_table_title} Input: `{subject}` " \
+                f"matches multiple subjects:` `{', '.join(partial_subjects)}`"
 
         return get_subjects_summary_as_table(partial_subjects, obj, title)
 
-    raise click.ClickException("'{}' is not a valid help subject. "
-                               "Try commandd:'help' for list of subjects.".
-                               format(subject))
+    raise click.ClickException(f"'{subject}' is not a valid help subject. "
+                               "Try commandd:'help' for list of subjects.")
diff --git a/pywbemtools/_output_formatting.py b/pywbemtools/_output_formatting.py
index ee1aad86..e8c25b0b 100644
--- a/pywbemtools/_output_formatting.py
+++ b/pywbemtools/_output_formatting.py
@@ -200,11 +200,11 @@ def validate_output_format(output_format, valid_format_groups,
             if name in valid_format_groups:
                 if valid_formats:
                     valid_formats += "; "
-                valid_formats += '{} formats: "({})"'.format(
-                    name, '", "'.join(fmt_list))
-        raise click.ClickException('Output format "{}" not allowed for this '
-                                   'command. Only {} allowed.'.
-                                   format(output_format, valid_formats))
+                valid_formats += f'{name} formats: "({", ".join(fmt_list)})'
+
+        raise click.ClickException(
+            f'Output format "{output_format}" not allowed for this '
+            f"command. Only {valid_formats} allowed.")
 
     assert output_format is None
 
@@ -328,8 +328,7 @@ def column_is_empty(rows, column):
     # Remove empty rows
     len_hdr = len(headers)
     for row in rows:
-        assert len(row) == len_hdr, "row: {}\nhdrs: {}". \
-            format(row, headers)
+        assert len(row) == len_hdr, f"row: {row}\nhdrs: {headers}"
     for column in range(len(headers) - 1, -1, -1):
         if column_is_empty(rows, column):
             if isinstance(headers, tuple):
@@ -413,8 +412,7 @@ def format_table(rows, headers, title=None, table_format='simple',
     if table_format == 'table':
         table_format = 'psql'
     if not output_format_is_table(table_format):
-        raise click.ClickException('Invalid table format {}.'
-                                   .format(table_format))
+        raise click.ClickException(f'Invalid table format {table_format}.')
 
     # Required because tabulate applies an internally defined format
     # when floatfmt not defined.
diff --git a/pywbemtools/pywbemcli/_association_shrub.py b/pywbemtools/pywbemcli/_association_shrub.py
index 30cb7cd2..eb98b09a 100644
--- a/pywbemtools/pywbemcli/_association_shrub.py
+++ b/pywbemtools/pywbemcli/_association_shrub.py
@@ -257,9 +257,8 @@ def get_reference_instnames(self, reference_instances):
                 reference_instnames = [ri.path for ri in reference_instances]
                 ref_clns = {n.classname for n in reference_instnames}
                 warning_msg(
-                    'Option --assoc-name "{}" not found in associator names '
-                    '({})" from server'.format(self.assoc_class,
-                                               ", ".join(ref_clns)))
+                    f'Option --assoc-name "{self.assoc_class}" not found in '
+                    f'associator names ({", ".join(ref_clns)})" from server')
         else:
             reference_instnames = [ri.path for ri in reference_instances]
         return reference_instnames
@@ -322,8 +321,8 @@ class so that the resulting output shows what would be the association
             # Test for --role as valid role for this request and do warning.
             roles = list(self.instance_shrub)
             if tst_role not in [r.lower() for r in roles]:
-                warning_msg('Option --role ({}) not found in roles: ({}). '
-                            'Ignored'.format(self.role, ', '.join(roles)))
+                warning_msg(f"option --role ({self.role}) not found in roles: "
+                            f"({', '.join(roles)}). ")
             else:
                 # Remove any roles not defined in instance_shrub
                 remove_roles = [r for r in roles if r.lower() != tst_role]
@@ -458,8 +457,8 @@ def build_shrub_tree(self, summary):
 
                         disp_assoc_cln = assoc_cln
 
-                        key = "{}(ResultClass)({} insts)". \
-                            format(disp_assoc_cln, len(inst_names_tup))
+                        key = f"{disp_assoc_cln}(ResultClass)" \
+                              f"({len(inst_names_tup)} insts)"
 
                         # Build dictionary of associated instance names
                         assoc_clns_dict[key] = OrderedDict()
@@ -481,7 +480,7 @@ def build_shrub_tree(self, summary):
 
                 # Add the reference class element. Include namespace if
                 # different than conn default namespace
-                disp_ref_cln = "{}(AssocClass)". format(ref_cln)
+                disp_ref_cln = f"{ref_cln}(AssocClass)"
 
                 elementstree[disp_ref_cln] = rrole_dict
 
@@ -512,13 +511,15 @@ def fmt_inst_col(iname_tuples, max_len, summary, ternary):
                 return len(iname_tuples)
 
             if ternary:
-                return "\n".join("{}(refinst:{})".format(
-                    self.to_wbem_uri_folded(t[0], max_len=max_len), t[1])
-                                 for t in iname_tuples)  # noqa E128
+                return "\n".join(
+                    "{}(refinst:{})".
+                    format(self.to_wbem_uri_folded(t[0], max_len=max_len),
+                           t[1])
+                           for t in iname_tuples)  # noqa E128
 
-            return "\n".join("{}".format(
-                self.to_wbem_uri_folded(t[0], max_len=max_len))
-                             for t in iname_tuples)  # noqa E128
+            return "\n".join("{}".format(self.to_wbem_uri_folded(
+                                         t[0], max_len=max_len))
+                                         for t in iname_tuples)  # noqa E128
 
         # Display shrub as table
         inst_hdr = "Assoc Inst Count" if summary else "Assoc Inst paths"
@@ -546,8 +547,8 @@ def fmt_inst_col(iname_tuples, max_len, summary, ternary):
                                      assoc_cln,
                                      inst_col])
 
-        title = 'Shrub of {}: {}'.format(self.source_path,
-                                         'summary' if summary else 'paths')
+        rslt_type = 'summary' if summary else 'paths'
+        title = f"Shrub of {self.source_path}: {rslt_type}"
         return format_table(rows, headers, title, table_format=output_format)
 
     def build_assoc_name_tuples(self, assoc_inames, assoc_cln,
@@ -718,8 +719,8 @@ def build_inst_names(self, inst_names_tuple, ref_cln, replacements):
             # to the defining reference instance so the user can match
             # the instances to reference instances.
             if is_ternary:
-                iname_display = '{}(refinst:{})'.format(iname_display,
-                                                        inst_name_tuple.RefInst)
+                iname_display = \
+                    f'{iname_display}(refinst:{inst_name_tuple.RefInst})'
 
             # builds dict with empty value to be ascii_tree compatible
             modified_inames[iname_display] = OrderedDict()
@@ -818,6 +819,9 @@ def _get_role_result_roles(self, roles, ref_classname):
             if refs:
                 rtn_roles[tst_role] = [r for r in roles if r != tst_role]
         if self.verbose:
-            print('ResultRoles: class={} ResultClass={} ResultRoles={}'
-                  .format(self.source_path.classname, ref_classname, rtn_roles))
+            click.echo(
+                f'ResultRoles: class={self.source_path.classname}  '
+                f'ResultClass={self.source_path.classname} '
+                f'ResultRoles={rtn_roles}')
+
         return rtn_roles
diff --git a/pywbemtools/pywbemcli/_cimvalueformatter.py b/pywbemtools/pywbemcli/_cimvalueformatter.py
index 38d73433..4b74ed33 100644
--- a/pywbemtools/pywbemcli/_cimvalueformatter.py
+++ b/pywbemtools/pywbemcli/_cimvalueformatter.py
@@ -186,8 +186,8 @@ def _scalar_value_tomof(value, type, indent, maxline, line_pos=0, end_space=0,
         return _mofval(val, indent, maxline, line_pos, end_space)
     else:
         assert isinstance(value, float), \
-            "Scalar value of CIM type {} has invalid Python type {} " \
-            "for conversion to a MOF string".format(type, builtin_type(value))
+            f"Scalar value of CIM type {type} has invalid Python type " \
+            f"{builtin_type(value)} for conversion to a MOF string"
         val = repr(value)
         return _mofval(val, indent, maxline, line_pos, end_space)
 
@@ -438,9 +438,9 @@ def _mofstr(value, indent, maxline, line_pos, end_space, avoid_splits=False,
         # A safety check for endless loops
         assert value != saved_value, \
             "Endless loop in _mofstr() with state: " \
-            "mof_str={0}, value={1}, avl_len={2}, end_space={3}, " \
-            "split_pos={4} with maxline={5} input". \
-            format(''.join(mof), value, avl_len, end_space, split_pos, maxline)
+            f"mof_str={''.join(mof)}, value={value}, avl_len={avl_len}, " \
+            f"end_space={end_space}, " \
+            f"split_pos={split_pos} with maxline={maxline} input"
 
     mof_str = ''.join(mof)
     return mof_str, line_pos
diff --git a/pywbemtools/pywbemcli/_cmd_class.py b/pywbemtools/pywbemcli/_cmd_class.py
index 6d75ad35..38087763 100644
--- a/pywbemtools/pywbemcli/_cmd_class.py
+++ b/pywbemtools/pywbemcli/_cmd_class.py
@@ -765,14 +765,14 @@ def cmd_class_find(context, classname_glob, options):
 
             if output_format_is_table(context.output_format):
                 headers = ['Namespace', 'Class count']
-                click.echo(format_table(rows,
-                                        headers,
-                                        title='Find class counts {}'.
-                                        format(classname_glob),
-                                        table_format=output_format))
+                click.echo(format_table(
+                    rows,
+                    headers,
+                    title=f'Find class counts {classname_glob}',
+                    table_format=output_format))
             else:
                 for ns, count in rows:
-                    click.echo('  {}: {}'. format(ns, count))
+                    click.echo(f'  {ns}: {count}')
             return
 
         # Not summary. Build rows of namespace, classname for each namespace
@@ -909,21 +909,22 @@ def cmd_class_delete(context, classname, options):
             ClassName=classname, namespace=namespace)
     except Error as exc:
         raise pywbem_error_exception(
-            exc, "Cannot enumerate instance names of class {} in "
-            "namespace {}".format(classname, namespace))
+            exc,
+            f"Cannot enumerate instance names of class {classname} in "
+            f"namespace {namespace}")
 
     if instnames and not include_instances:
         raise click.ClickException(
-            "Cannot delete class {} because it has {} instances".
-            format(classname, len(instnames)))
+            f"Cannot delete class {classname} because it has "
+            f"{len(instnames)} instances")
 
     depending_cln_list = depending_classnames(
         classname, namespace, conn)
 
     if depending_cln_list:
         raise click.ClickException(
-            "Cannot delete class {} because these classes depend on it: {}".
-            format(classname, ', '.join(depending_cln_list)))
+            f"Cannot delete class {classname} because these classes "
+            f"depend on it: {', '.join(depending_cln_list)}")
 
     context.spinner_stop()
     if include_instances:
@@ -941,6 +942,6 @@ def cmd_class_delete(context, classname, options):
             conn.DeleteClass(classname)
         except Error as exc:
             raise pywbem_error_exception(
-                exc, "Cannot delete class {} in namespace {}".
-                format(classname, namespace))
+                exc,
+                f"Cannot delete class {classname} in namespace {namespace}")
     click.echo(f'{dry_run_prefix}Deleted class {classname}')
diff --git a/pywbemtools/pywbemcli/_cmd_connection.py b/pywbemtools/pywbemcli/_cmd_connection.py
index 630e0b2b..bd9a4bd4 100644
--- a/pywbemtools/pywbemcli/_cmd_connection.py
+++ b/pywbemtools/pywbemcli/_cmd_connection.py
@@ -393,7 +393,7 @@ def show_connection_information(context, connection,
         if is_default_connection(context, connection):
             state.append("default")
         if state:
-            state_str = ' ({})'.format(", ".join(state))
+            state_str = f' ({", ".join(state)})'
 
     if connection.password:
         disp_password = connection.password if show_password else '******'
@@ -476,21 +476,21 @@ def pick_connection(name, context, connections_repo):
 
     if not connections_repo.file_exists():
         raise click.ClickException(
-            'Connections file "{0}" does not exist'.
-            format(connections_repo.connections_file))
+            f'Connections file "{connections_repo.connections_file}" does '
+            'not exist')
 
     if name:
         if name in connections_repo:
             return name
         raise click.ClickException(
-            'Connection definition "{0}" not found in connections file "{1}"'.
-            format(name, connections_repo.connections_file))
+            f'Connection definition "{name}" not found in connections '
+            f'file "{connections_repo.connections_file}"')
 
     conn_names = sorted(list(connections_repo.keys()))
     if not conn_names:
         raise click.ClickException(
-            "No connections found in connection repository {0}".
-            format(connections_repo.connections_file))
+            "No connections found in connection repository "
+            f"{connections_repo.connections_file}")
     return pick_one_from_list(context, conn_names,
                               "Select a connection or Ctrl-C to abort.")
 
@@ -531,8 +531,8 @@ def cimcall(request, *pargs, **kwargs):
     # Find a valid instance to use in tests.
     test_instances = conn.EnumerateInstanceNames(test_class)
     if not test_instances:
-        raise click.ClickException("No instances found for test class {}".
-                                   format(test_class))
+        raise click.ClickException(
+            f"No instances found for test class {test_class}")
     test_instance = test_instances[0]
 
     # execute each command and append the results to rows as a tuple
@@ -586,29 +586,26 @@ def _set_default_connection(connections_repo, connection_name, verify=None):
     old_default = connections_repo.default_connection_name
     if old_default:
         if old_default == connection_name:
-            click.echo("{0} already set as default connection definition for "
-                       "connections file {1}.".
-                       format(connection_name,
-                              connections_repo.connections_file))
+            click.echo(f"{connection_name} already set as default connection "
+                       "definition for connections file "
+                       f"{connections_repo.connections_file}.")
             return
     else:
         if connection_name is None:
             click.echo("Default connection definition already cleared; "
-                       "connections file {0}.".
-                       format(connections_repo.connections_file))
+                       f"connections file {connections_repo.connections_file}.")
             return
 
     if verify:
         if connection_name is None:
-            if not verify_operation("Clear connection default in connections "
-                                    "file {0}".
-                                    format(connections_repo.connections_file)):
+            if not verify_operation(
+                    "Clear connection default in connections file "
+                    f"{connections_repo.connections_file}"):
                 raise click.ClickException("Default not changed.")
         else:
-            if not verify_operation("Set {0} as connection default in "
-                                    "connections file {1}".
-                                    format(connection_name,
-                                           connections_repo.connections_file)):
+            if not verify_operation(
+                    f"Set {connection_name} as connection default in "
+                    f"connections file {connections_repo.connections_file}"):
                 raise click.ClickException("Default not changed.")
 
     if old_default is None:
@@ -692,13 +689,13 @@ def cmd_connection_show(context, name, options):
     if connections_repo.file_exists():
         if name not in connections_repo:
             raise click.ClickException(
-                'Connection definition "{}" not found in connections file '
-                '"{}"'.format(name, connections_repo.connections_file))
+                f'Connection definition "{name}" not found in connections '
+                f'file "{connections_repo.connections_file}"')
         connection = connections_repo[name]
     else:   # no connections file
         raise click.ClickException(
-            'Name: "{}" not current and no connections file {}'.format(
-                name, connections_repo.connections_file))
+            f'Name: "{name}" not current and no connections file '
+            f'{connections_repo.connections_file}')
 
     show_connection_information(context,
                                 connection,
@@ -728,13 +725,10 @@ def cmd_connection_test(context, options):
             if ce.status_code == 'CIM_ERR_NOT_SUPPORTED':
                 conn.EnumerateInstances(test_classname)
         except Error as er:
-            raise click.ClickException('Cannot interact with WBEM Server '
-                                       '{}. EnumerateInstanceNames exception '
-                                       '{} and EnumerateInstances {} exception '
-                                       ' {} '.format(conn.url,
-                                                     ce.status_code,
-                                                     test_classname,
-                                                     er))
+            raise click.ClickException(
+                f'Cannot interact with WBEM Server {conn.url}. '
+                f'EnumerateInstanceNames exception {ce.status_code} and '
+                f'EnumerateInstances {test_classname} exception {er}')
     except Error as er:
         raise pywbem_error_exception(er)
 
@@ -744,8 +738,8 @@ def cmd_connection_test(context, options):
         else:
             test_class = classnames[0]
     else:
-        raise click.ClickException('No classes found to test in namespace {}.'.
-                                   format(conn.defaultnamespace))
+        raise click.ClickException(
+            f'No classes found to test in namespace {conn.defaultnamespace}.')
 
     if options['test_pull']:
         result = test_pull_operations(context, test_class)
@@ -754,8 +748,8 @@ def cmd_connection_test(context, options):
             headers = ['Operation', 'Result']
             click.echo(format_table(
                 result, headers,
-                title='Pull Operation test results (Connection OK): {}'.
-                format(conn.host),
+                title=f'Pull Operation test results (Connection OK): '
+                      f'{conn.host}',
                 table_format=output_format))
         else:
             click.echo(f'Connection OK: {conn.host}')
@@ -905,10 +899,10 @@ def build_row(options, name, svr):
         if connections_repo.file_exists():
             # Add connection that is current but not in connections repo
             if cname not in connections_repo:
-                cname = '{}{}'.format('*', cname)
+                cname = f"{'*'}{cname}"
                 rows.append(build_row(options, cname, current_connection))
         else:
-            cname = '{}{}'.format('*', cname)
+            cname = f"{'*'}{cname}"
             rows.append(build_row(options, cname, current_connection))
 
     # NOTE: Does not show ca_certs because that creates a very big table
@@ -925,10 +919,8 @@ def build_row(options, name, svr):
     click.echo(format_table(
         sorted(rows),
         headers,
-        title='WBEM server connections({}): ({}: default, {}: '
-              'current)\nfile: {}'.format(
-                  table_type, dflt_sym, cur_sym,
-                  connections_repo.connections_file),
+        title=f'WBEM server connections({table_type}): ({dflt_sym}: default, '
+              f'{cur_sym}: current)\nfile: {connections_repo.connections_file}',
         table_format=output_format))
 
 
diff --git a/pywbemtools/pywbemcli/_cmd_instance.py b/pywbemtools/pywbemcli/_cmd_instance.py
index 847df01e..41eed604 100644
--- a/pywbemtools/pywbemcli/_cmd_instance.py
+++ b/pywbemtools/pywbemcli/_cmd_instance.py
@@ -560,8 +560,7 @@ def instance_invokemethod(context, instancename, methodname, **options):
 @click.option('--ql', '--query-language', 'query_language', type=str,
               metavar='QUERY-LANGUAGE', default=DEFAULT_QUERY_LANGUAGE,
               help='The query language to be used with --query. '
-              'Default: {default}.'.
-              format(default=DEFAULT_QUERY_LANGUAGE))
+              f'Default: {DEFAULT_QUERY_LANGUAGE}.')
 @add_options(namespace_option)
 @add_options(summary_option)
 @add_options(help_option)
@@ -886,9 +885,9 @@ def validate_namespace_option(class_path):
         if class_path.namespace:
             if options['namespace']:
                 raise click.ClickException(
-                    "Using --namespace option: {} conflicts with specifying "
-                    "namespace in INSTANCENAME: {}".format(options['namespace'],
-                                                           instancename))
+                    f"Using --namespace option: {options['namespace']} "
+                    "conflicts with specifying namespace in "
+                    f"INSTANCENAME: {instancename}")
 
     # If option is a tuple, expand option to get list of all namespaces
     # defined. Option may be multiple uses of the option and/or comma-separated
@@ -904,8 +903,7 @@ def validate_namespace_option(class_path):
         if options['key']:
             raise click.ClickException(
                 "Using the --key option conflicts with specifying a "
-                "wildcard keybinding in INSTANCENAME: {}".
-                format(instancename))
+                f"wildcard keybinding in INSTANCENAME: {instancename}")
 
         class_uri = instancename[:-2]
         try:
@@ -975,7 +973,7 @@ def validate_namespace_option(class_path):
         except ValueError as exc:
             raise click.ClickException(str(exc))
 
-        instancename_kb = "{}.{}".format(instancename, ','.join(kb_strs))
+        instancename_kb = f"{instancename}.{','.join(kb_strs)}"
 
         try:
             instance_path = CIMInstanceName.from_wbem_uri(instancename_kb)
@@ -1094,9 +1092,8 @@ def cmd_instance_create(context, classname, options):
     except CIMError as ce:
         if ce.status_code == CIM_ERR_NOT_FOUND:
             raise click.ClickException(
-                'CIMClass: "{}" does not exist in namespace "{}" in WEB '
-                'server: {}.'.
-                format(classname, ns, conn))
+                f'CIMClass: "{classname}" does not exist in '
+                f'namespace "{ns}" in WEB server: {conn}.')
         raise pywbem_error_exception(ce)
 
     except Error as er:
@@ -1119,9 +1116,8 @@ def cmd_instance_create(context, classname, options):
         click.echo(f'{name}')
     except Error as er:
         raise click.ClickException(
-            'Server Error creating instance in namespace {}. Exception: '
-            '{}: {}'.
-            format(ns, er.__class__.__name__, er))
+            f'Server Error creating instance in namespace {ns}. Exception: '
+            f'{er.__class__.__name__}: {er}')
 
 
 def cmd_instance_modify(context, instancename, options):
@@ -1149,8 +1145,8 @@ def cmd_instance_modify(context, instancename, options):
     except CIMError as ce:
         if ce.status_code == CIM_ERR_NOT_FOUND:
             raise click.ClickException(
-                'CIMClass: {!r} does not exist in WEB server: {}'
-                .format(instancepath.classname, conn.url))
+                f'CIMClass: {instancepath.classname!r} does not exist in '
+                f'WEB server: {conn.url}')
 
         raise pywbem_error_exception(ce)
     except Error as er:
@@ -1253,8 +1249,9 @@ def enumerate_instances(conn, context, options, namespace, classname,
     except ValueError as ve:
         raise click.ClickException(
             'Instance enumerate failed because FilterQuery not allowed with '
-            'traditional EnumerateInstance. --use-pull: {}. Exception: {}: {}'
-            .format(context.pywbem_server.use_pull, ve.__class__.__name__, ve))
+            'traditional EnumerateInstance. '
+            f'--use-pull: {context.pywbem_server.use_pull}. '
+            f'Exception: {ve.__class__.__name__}: {ve}')
 
 
 def cmd_instance_enumerate(context, classname, options):
@@ -1345,9 +1342,9 @@ def cmd_instance_references(context, instancename, options):
         except ValueError as ve:
             raise click.ClickException(
                 'Instance references failed because FilterQuery not allowed '
-                'with traditional References. --use-pull {}. Exception: {}: {}'
-                .format(context.pywbem_server.use_pull, ve.__class__.__name__,
-                        ve))
+                'with traditional References. '
+                f'--use-pull {context.pywbem_server.use_pull}. '
+                f'Exception: {ve.__class__.__name__}: {ve}')
     results.display()
 
 
@@ -1407,10 +1404,9 @@ def cmd_instance_associators(context, instancename, options):
         except ValueError as ve:
             raise click.ClickException(
                 'Instance associators failed because FilterQuery not allowed '
-                'with traditional Associators. --use-pull: {}. Exception: {}: '
-                '{}'
-                .format(context.pywbem_server.use_pull, ve.__class__.__name__,
-                        ve))
+                'with traditional Associators. '
+                f'--use-pull: {context.pywbem_server.use_pull}. '
+                f'Exception: {ve.__class__.__name__}: {ve}')
 
     results.display()
 
@@ -1488,9 +1484,8 @@ def cmd_instance_count(context, classname, options):
         try:
             inst_names = conn.EnumerateInstanceNames(cln, namespace=ns)
         except CIMError as ce:
-            warning_msg("Server CIMError {} with namepace={}, class={}. "
-                        "Continuing scan."
-                        .format(ce.status_code_name, ns, cln))
+            warning_msg(f"Server CIMError {ce.status_code_name} with "
+                        f"namepace={ns}, class={cln}. Continuing scan.")
             display_tuple = (ns, cln, f"CIMError {ce.status_code_name}")
             display_data.append(display_tuple)
             continue
@@ -1498,9 +1493,8 @@ def cmd_instance_count(context, classname, options):
         # item to the display with Server Fail message instead of count
         except Error as er:
             error = er
-            warning_msg("Server Error {} with namepace={}, class={}. "
-                        "Terminating scan."
-                        .format(er, ns, cln))
+            warning_msg(f"Server Error {er} with namepace={ns}, class={cln}. "
+                        "Terminating scan.")
             display_tuple = (ns, cln, "Server Fail")
             display_data.append(display_tuple)
             continue
@@ -1533,8 +1527,8 @@ def cmd_instance_count(context, classname, options):
                             table_format=output_fmt))
     if error:
         raise click.ClickException(
-            "Server Error {} at namespace={}, class:{}. Scan incomplete."
-            .format(error, ns, cln))
+            f"Server Error {error} at namespace={ns}, class:{cln}. "
+            "Scan incomplete.")
 
 
 def cmd_instance_query(context, query, options):
diff --git a/pywbemtools/pywbemcli/_cmd_namespace.py b/pywbemtools/pywbemcli/_cmd_namespace.py
index 6cb31ae9..2b32041d 100644
--- a/pywbemtools/pywbemcli/_cmd_namespace.py
+++ b/pywbemtools/pywbemcli/_cmd_namespace.py
@@ -233,8 +233,8 @@ def cmd_namespace_delete(context, namespace, options):
     interop_ns = wbem_server.interop_ns  # Determines the Interop namespace
     if namespace == interop_ns:
         raise click.ClickException(
-            "Cannot delete namespace {} because it is the Interop "
-            "namespace".format(namespace))
+            f"Cannot delete namespace {namespace} because it is the "
+            "Interop namespace")
 
     # Check whether the namespace is empty.
     # We do not check for instances, because classes are a prerequisite for
@@ -246,21 +246,20 @@ def cmd_namespace_delete(context, namespace, options):
             namespace=namespace, ClassName=None, DeepInheritance=False)
     except Error as exc:
         raise pywbem_error_exception(
-            exc, "Cannot enumerate top-level class names in namespace {}".
-            format(namespace))
+            exc,
+            f"Cannot enumerate top-level class names in namespace {namespace}")
     try:
         qualifiers = conn.EnumerateQualifiers(namespace=namespace)
     except Error as exc:
         raise pywbem_error_exception(
-            exc, "Cannot enumerate qualifier types in namespace {}".
-            format(namespace))
+            exc, f"Cannot enumerate qualifier types in namespace {namespace}")
     non_empty = top_class_paths or qualifiers
 
     if non_empty and not include_objects:
         raise click.ClickException(
-            "Cannot delete namespace {} because it has {} qualifier types "
-            "and {} top-level classes (and possibly instances)".
-            format(namespace, len(top_class_paths), len(qualifiers)))
+            f"Cannot delete namespace {namespace} because it has "
+            f"{len(qualifiers)} qualifier types and {len(top_class_paths)} "
+            f"top-level classes (and possibly instances)")
 
     if top_class_paths:
 
@@ -276,8 +275,9 @@ def cmd_namespace_delete(context, namespace, options):
                     namespace=namespace, ClassName=classname)
             except Error as exc:
                 raise pywbem_error_exception(
-                    exc, "Cannot enumerate instance names of class {} in "
-                    "namespace {}".format(classname, namespace))
+                    exc,
+                    f"Cannot enumerate instance names of class {classname} "
+                    f"in namespace {namespace}")
             for inst_path in inst_paths:
                 # Skip instances of subclasses. This only happens in dry-run
                 # mode, but we execute it always to minimize differences
@@ -291,8 +291,7 @@ def cmd_namespace_delete(context, namespace, options):
                     except Error as exc:
                         raise pywbem_error_exception(
                             exc, f"Cannot delete instance {inst_path}")
-                click.echo('{}Deleted instance {}'.
-                           format(dry_run_prefix, inst_path))
+                click.echo(f'{dry_run_prefix}Deleted instance {inst_path}')
         for classname in classnames_depsorted:
             if not dry_run:
                 try:
@@ -300,10 +299,10 @@ def cmd_namespace_delete(context, namespace, options):
                         namespace=namespace, ClassName=classname)
                 except Error as exc:
                     raise pywbem_error_exception(
-                        exc, "Cannot delete class {} in namespace {}".
-                        format(classname, namespace))
-            click.echo('{}Deleted class {}'.
-                       format(dry_run_prefix, classname))
+                        exc,
+                        f"Cannot delete class {classname} in namespace "
+                        f"{namespace}")
+            click.echo(f'{dry_run_prefix}Deleted class {classname}')
 
     if qualifiers:
         context.spinner_stop()
@@ -315,10 +314,11 @@ def cmd_namespace_delete(context, namespace, options):
                         namespace=namespace, QualifierName=qualifiername)
                 except Error as exc:
                     raise pywbem_error_exception(
-                        exc, "Cannot delete qualifier type {} in namespace {}".
-                        format(qualifiername, namespace))
-            click.echo('{}Deleted qualifier type {}'.
-                       format(dry_run_prefix, qualifiername))
+                        exc,
+                        f"Cannot delete qualifier type {qualifiername} "
+                        f"in namespace {namespace}")
+            click.echo(
+                f'{dry_run_prefix}Deleted qualifier type {qualifiername}')
 
     context.spinner_stop()
     if not dry_run:
diff --git a/pywbemtools/pywbemcli/_cmd_profile.py b/pywbemtools/pywbemcli/_cmd_profile.py
index 02cf7f37..cd819589 100644
--- a/pywbemtools/pywbemcli/_cmd_profile.py
+++ b/pywbemtools/pywbemcli/_cmd_profile.py
@@ -261,8 +261,8 @@ def cmd_profile_centralinsts(context, options):
                 profile_disp[profile_name] = cis
             # Output warning that above call failed and continue
             except Exception as ex:  # pylint: disable=broad-except
-                click.echo('Exception: profile: {} path: {} exc: {}'.
-                           format(profile_name, inst.path, ex))
+                click.echo(f"Exception: profile: {profile_name} "
+                           f"path: {inst.path} exc: {ex}")
 
         # Get max length for profile name for table output.
         max_profile_name = max(map(len, profile_disp))
@@ -281,9 +281,10 @@ def cmd_profile_centralinsts(context, options):
                         "\n".join([to_wbem_uri_folded(path,
                                                       max_len=max_path_width)
                                    for path in paths]))
-                except ValueError as ve:  # pylint: disable=broad-except
-                    click.echo('Exception: profile: {} path: {} exc: {}'.
-                               format(profile_name, paths, ve))
+                # pylint: disable=broad-except
+                except ValueError as ve:
+                    click.echo(f"Exception: profile: {profile_name} "
+                               f"path: {paths} exc: {ve}")
                     click.echo("Continue with other profiles")
             rows.append(row)
 
diff --git a/pywbemtools/pywbemcli/_cmd_statistics.py b/pywbemtools/pywbemcli/_cmd_statistics.py
index 02f269b3..2159a277 100644
--- a/pywbemtools/pywbemcli/_cmd_statistics.py
+++ b/pywbemtools/pywbemcli/_cmd_statistics.py
@@ -237,15 +237,14 @@ def get_objmgr_inst(context):
         # Use warning_msg here rather than python Warnings class since this
         # is to be always output.
         if len(objmanager_insts) > 1:
-            warning_msg(
-                "Server returned multiple  ObjectManager {} instances. Using "
-                "first instance.".format(objmanager_insts[0].classname))
+            warning_msg("Server returned multiple  ObjectManager "
+                        f"{objmanager_insts[0].classname} instances. Using "
+                        "first instance.")
 
     except Error as er:
         raise click.ClickException(
-            'Failure trying to access object manager instances of class {} '
-            'namespace {}. Error: {}'.
-            format(OBJMGR_CLN, interop_ns, er))
+            'Failure trying to access object manager instances of class '
+            f'{OBJMGR_CLN} namespace {interop_ns}. Error: {er}')
     objmgr_inst = objmanager_insts[0]
 
     return objmgr_inst
@@ -283,12 +282,12 @@ def set_server_statistics(context, desired_state):
         cur_state = objmgr[OBJMGR_STAT_PROPERTY_NAME]
     except KeyError as ke:
         raise click.ClickException(
-            'Failure accessing class {} property {}. namespace {}:Error: {}'.
-            format(OBJMGR_CLN, OBJMGR_STAT_PROPERTY_NAME, interop_ns, ke))
+            f'Failure accessing class {OBJMGR_CLN} property '
+            f'{OBJMGR_STAT_PROPERTY_NAME}. namespace {interop_ns}:Error: {ke}')
 
     if cur_state == desired_state:
-        click.echo("Server statistics gathering was already {}".
-                   format(to_on_off(desired_state)))
+        click.echo("Server statistics gathering was already "
+                   f"{to_on_off(desired_state)}")
         return
 
     objmgr[OBJMGR_STAT_PROPERTY_NAME] = desired_state
@@ -299,19 +298,18 @@ def set_server_statistics(context, desired_state):
                             IncludeQualifiers=False)
     except Error as ce:
         raise click.ClickException('Modification of GatherStatisticalData '
-                                   'property in instance {} on server failed: '
-                                   'Exception {}'.format(objmgr.path, ce))
+                                   f'property in instance {objmgr.path} on '
+                                   f'server failed: Exception {ce}')
 
     modified_objmgr = conn.GetInstance(objmgr.path)
 
     if modified_objmgr[OBJMGR_STAT_PROPERTY_NAME] != desired_state:
         raise click.ClickException(
-            'The WBEM server reported success when changing the {} property '
-            'in its {} instance to {} but did not actually change it.'.
-            format(OBJMGR_STAT_PROPERTY_NAME, OBJMGR_CLN, interop_ns))
+            'The WBEM server reported success when changing the '
+            f'{OBJMGR_STAT_PROPERTY_NAME} property in its {OBJMGR_CLN} '
+            f'instance to {interop_ns} but did not actually change it.')
 
-    click.echo("Server statistics gathering set to {}".
-               format(to_on_off(desired_state)))
+    click.echo(f"Server statistics gathering set to {to_on_off(desired_state)}")
 
 
 ###############################################################
@@ -373,8 +371,8 @@ def cmd_statistics_status(context):
                 ['server statistics gathering', svr_status]]
         click.echo(format_table(rows, headers, "Statistics status"))
     else:
-        click.echo("Statistics status: client={}; server={}".
-                   format(pywbemcli_stats_status, svr_status))
+        click.echo(f"Statistics status: client={pywbemcli_stats_status}; "
+                   f"server={svr_status}")
 
 
 def cmd_statistics_reset(context):
@@ -469,8 +467,8 @@ def avg_time_ms(total_time, num_ops):
         svr_status = f"Not settable {er}"
 
     if isinstance(svr_status, str):
-        raise click.ClickException("ObjectManager config setting not found {}".
-                                   format(svr_status))
+        raise click.ClickException(
+            f"ObjectManager config setting not found {svr_status}")
 
     if not svr_status:
         raise click.ClickException("WBEM server CIM_ObjectManager "
@@ -503,13 +501,12 @@ def avg_time_ms(total_time, num_ops):
 
     if not results:
         raise click.ClickException(
-            "No WBEM server class {} or class returns no data on "
-            "WBEM Server".
-            format(CIMOM_STATISTICAL_DATA_CLASS))
+            f"No WBEM server class {CIMOM_STATISTICAL_DATA_CLASS} or class "
+            "returns no data on WBEM Server")
 
     if context.verbose:
-        click.echo("{} returns instances in namespace {}".
-                   format(CIMOM_STATISTICAL_DATA_CLASS, stats_namespace))
+        click.echo(f"{CIMOM_STATISTICAL_DATA_CLASS} returns instances in "
+                   f"namespace {stats_namespace}")
 
     try:
         op_type_vm = ValueMapping.for_property(conn, stats_namespace,
@@ -525,8 +522,8 @@ def avg_time_ms(total_time, num_ops):
             IncludeClassOrigin=False)
         if not results:
             raise click.ClickException(
-                "WBEM server Class {} returns no data".
-                format(CIMOM_STATISTICAL_DATA_CLASS))
+                f"WBEM server Class {CIMOM_STATISTICAL_DATA_CLASS} returns no "
+                "data")
 
         row_tuples = []
         for inst in results:
@@ -592,6 +589,5 @@ def avg_time_ms(total_time, num_ops):
             title='Server statistics',
             table_format=output_fmt))
     except Error as er:
-        raise click.ClickException("Statistics retrieval from WBEM server "
-                                   "failed. Exception {}".
-                                   format(er))
+        raise click.ClickException(
+            f"Statistics retrieval from WBEM server failed. Exception {er}")
diff --git a/pywbemtools/pywbemcli/_cmd_subscription.py b/pywbemtools/pywbemcli/_cmd_subscription.py
index 6b19a8af..ede0feb3 100644
--- a/pywbemtools/pywbemcli/_cmd_subscription.py
+++ b/pywbemtools/pywbemcli/_cmd_subscription.py
@@ -53,6 +53,7 @@
 
 OWNED_STR = True
 ALL_STR = 'all'
+EOL = '\n'
 
 ownedadd_flag_option = [              # pylint: disable=invalid-name
     click.option("--owned/--permanent", default=True,
@@ -215,7 +216,7 @@ def subscription_add_destination(context, identity, **options):
               default=DEFAULT_QUERY_LANGUAGE,
               help="Filter query language for this subscription The query "
                    "languages normally implemented are 'DMTF:CQL' and 'WQL' . "
-                   " Default: {}".format(DEFAULT_QUERY_LANGUAGE))
+                   f" Default: {DEFAULT_QUERY_LANGUAGE}")
 @click.option('--source-namespaces', type=str, metavar='TEXT',
               required=False, default=None,
               multiple=True,
@@ -708,8 +709,8 @@ def get_destinations(self, owned_flag):
 
         except Error as er:
             raise click.ClickException(
-                self.err_msg("Get {0} destinations failed".
-                             format(owned_flag_str(owned_flag)), er))
+                self.err_msg(f"Get {owned_flag_str(owned_flag)} destinations "
+                             "failed", er))
 
     def get_filters(self, owned_flag):
         """
@@ -738,8 +739,8 @@ def get_filters(self, owned_flag):
 
         except Error as er:
             raise click.ClickException(
-                self.err_msg("Get {0} filters failed".
-                             format(owned_flag_str(owned_flag)), er))
+                self.err_msg(f"Get {owned_flag_str(owned_flag)} filters failed",
+                             er))
 
     def get_subscriptions(self, owned_flag):
         """
@@ -764,8 +765,9 @@ def get_subscriptions(self, owned_flag):
 
         except Error as er:
             raise click.ClickException(
-                self.err_msg("Get {0} subscriptions failed".
-                             format(owned_flag_str(owned_flag)), er))
+                self.err_msg(
+                    f"Get {owned_flag_str(owned_flag)} subscriptions failed",
+                    er))
 
     def add_destination(self, listener_url, owned_flag, destination_id,
                         destination_name, persistence_type=None):
@@ -797,8 +799,8 @@ def add_destination(self, listener_url, owned_flag, destination_id,
                 f"add-destination failed: {ve}")
         except Error as er:
             raise click.ClickException(
-                self.err_msg("add-destination {0} failed".
-                             format(owned_flag_str(owned_flag)), er))
+                self.err_msg(f"add-destination {owned_flag_str(owned_flag)} "
+                             "failed", er))
 
     def add_filter(self, source_namespaces, query,
                    query_language=DEFAULT_QUERY_LANGUAGE, owned_flag=True,
@@ -832,9 +834,8 @@ def add_filter(self, source_namespaces, query,
             if ce.status_code == CIM_ERR_ALREADY_EXISTS:
                 name_value = filter_id or name
                 raise click.ClickException(
-                    "add-filter Failed. Filter name='{0}' already exists".
-                    format(name_value))
-
+                    f"add-filter Failed. Filter name='{name_value}' already "
+                    "exists")
             raise click.ClickException(
                 self.err_msg("add-filter failed with server exception", ce))
         except Error as er:
@@ -858,7 +859,7 @@ def add_subscriptions(self, filter_path, destination_paths=None,
         except ValueError as ex:
             raise click.ClickException(
                 "add-subscription failed. pybwem SubscriptionManager "
-                "exception: {}.".format(ex))
+                f"exception: {ex}.")
         except Error as er:
             raise click.ClickException(
                 self.err_msg("add-subscription failed", er))
@@ -891,8 +892,8 @@ def remove_filter(self, filter_path):
             return self.submgr.remove_filter(self.server_id, filter_path)
         except Error as er:
             raise click.ClickException(
-                self.err_msg("remove-filter failed: {0} path: {1} failed".
-                             format(er, filter_path), er))
+                self.err_msg(f"remove-filter failed: {er} path: {filter_path} "
+                             "failed", er))
 
     def remove_subscriptions(self, subscription_paths):
         """
@@ -1246,8 +1247,8 @@ def pick_one_path_from_instances_list(csm, instances, pick_msg):
         display_list = \
             [IndicationSubscription(csm, i).select_id_str() for i in instances]
     else:
-        click.echo("Class {0} is not one of pywbem subscription mgr classes".
-                   format(paths[0].classname))
+        click.echo(f"Class {paths[0].classname} is not one of pywbem "
+                   "subscription mgr classes")
         display_list = paths
     try:
         index = pick_one_index_from_list(csm.context, display_list, pick_msg)
@@ -1296,8 +1297,8 @@ def resolve_instances(csm, instances, identity, obj_type_name,
     """
     # Exception, at least one instance must exist.
     if not instances:
-        raise click.ClickException("No {0} found for identity: {1}".
-                                   format(obj_type_name, identity))
+        raise click.ClickException(
+            f"No {obj_type_name} found for identity: {identity}")
     # Return the single item
     if len(instances) == 1:
         return instances[0]
@@ -1306,16 +1307,17 @@ def resolve_instances(csm, instances, identity, obj_type_name,
     if select_opt:
         # FUTURE: Need better than path for prompt info.
         inst = pick_one_inst_from_instances_list(
-            csm, instances, "Pick one {0} to use for {1}:".
-            format(obj_type_name, cmd_str))
+            csm,
+            instances,
+            f"Pick one {obj_type_name} to use for {cmd_str}:")
         return inst
 
     # Generate an exception with summary info on the instances
     paths_str = "\n  *".join([str(i.path) for i in instances])
     raise click.ClickException(
-        "The identity: '{0}' returned multiple {1} instances. "
-        "Use --select option to pick one instance from:\n  * {2}".
-        format(identity, obj_type_name, paths_str))
+        f"The identity: '{identity}' returned multiple {obj_type_name} "
+        "instances. Use --select option to pick one instance from:"
+        f"\n  * {paths_str}")
 
 
 def get_insts_for_subscription_identities(csm, destination_identity,
@@ -1359,8 +1361,8 @@ def get_insts_for_subscription_identities(csm, destination_identity,
     # If Identity not specifically owned, look also in owned with the owned
     # prefix. This may result  in multiples that must be resolved
     if not filter_id_owned:
-        f2 = csm.find_filters_for_name("{}:{}".format(
-            csm.owned_filter_prefix, filter_identity))
+        f2 = csm.find_filters_for_name(
+            f"{csm.owned_filter_prefix}:{filter_identity}")
         if f2:
             filter_instances.extend(f2)
 
@@ -1417,12 +1419,11 @@ def cmd_subscription_add_destination(context, identity, options):
         if dests:
             dests_str = ", ".join([str(d.path) for d in dests])
             raise click.ClickException(
-                "{0} destination: Name=[{1}] add failed. Duplicates URL of "
-                "existing destination(s): [{2}. Pywbemcli does not allow "
-                "permanent destinations with same Name property to keep Name "
-                "properties unique.".
-                format(owned_flag_str(owned_flag_opt), destination_name,
-                       dests_str))
+                f"{owned_flag_str(owned_flag_opt)} destination: "
+                f"Name=[{destination_name}] add failed. Duplicates URL of "
+                f"existing destination(s): [{dests_str}. Pywbemcli does not "
+                "allow permanent destinations with same Name property to "
+                "keep Name properties unique.")
 
     destination_result = csm.add_destination(
         options['listener_url'], owned_flag_opt, destination_id,
@@ -1437,22 +1438,20 @@ def cmd_subscription_add_destination(context, identity, options):
             f":{destination_id}"):
         rslt_info = IndicationDestination(csm, destination_result)
         raise click.ClickException(
-            "{0} destination: Name={1} Not added. Duplicates URL of "
-            "existing {2} destination: {3} URL: {4} PersistenceType: {5}.".
-            format(owned_flag_str(owned_flag_opt),
-                   destination_id,
-                   rslt_info.owned_flag_str,
-                   destination_result['Name'],
-                   destination_result['Destination'],
-                   destination_result['PersistenceType']))
+            f"{owned_flag_str(owned_flag_opt)} destination: "
+            f"Name={destination_id} Not added. Duplicates URL of "
+            f"existing {rslt_info.owned_flag_str} "
+            f"destination: {destination_result['Name']} URL: "
+            f"{destination_result['Destination']} "
+            f"PersistenceType: {destination_result['PersistenceType']}.")
+
     click.echo(
-        "Added {0} destination: Name={1}".
-        format(owned_flag_str(owned_flag_opt), destination_result['Name']))
+        f"Added {owned_flag_str(owned_flag_opt)} destination: "
+        f"Name={destination_result['Name']}")
 
     if context.verbose:
-        click.echo("\npath={0}\n\n{1}".
-                   format(str(destination_result.path),
-                          destination_result.tomof()))
+        click.echo(f"\npath={str(destination_result.path)}\n"
+                   f"\n{destination_result.tomof()}")
 
 
 def cmd_subscription_add_filter(context, identity, options):
@@ -1481,12 +1480,11 @@ def cmd_subscription_add_filter(context, identity, options):
         if filters:
             filters_str = ", ".join([str(f.path) for f in filters])
             raise click.ClickException(
-                "{0} filter: Name=[{1}] add failed. Duplicates URL of "
-                "existing filters(s): [{2}. Pywbemcli does not allow "
-                "permanent filters with same Name property to keep Name "
-                "properties unique.".
-                format(owned_flag_str(owned_flag_opt), filter_name,
-                       filters_str))
+                f"{owned_flag_str(owned_flag_opt)} filter: "
+                f"Name=[{filter_name}] add failed. Duplicates URL of "
+                f"existing filters(s): [{filters_str}. Pywbemcli does not "
+                "allow permanent filters with same Name property to keep Name "
+                "properties unique.")
 
     result_inst = csm.add_filter(source_namespaces, options['query'],
                                  options['query_language'],
@@ -1495,12 +1493,11 @@ def cmd_subscription_add_filter(context, identity, options):
 
     # Success: Show resulting name and conditionally, details
     context.spinner_stop()
-    click.echo("Added {0} filter: Name={1}".
-               format(owned_flag_str(owned_flag_opt), result_inst['Name']))
+    click.echo(f"Added {owned_flag_str(owned_flag_opt)} filter: "
+               f"Name={result_inst['Name']}")
 
     if context.verbose:
-        click.echo("\npath={0}\n\n{1}".
-                   format(str(result_inst.path), result_inst.tomof()))
+        click.echo(f"\npath={str(result_inst.path)}\n\n{result_inst.tomof()}")
 
 
 def cmd_subscription_add_subscription(context, destination_identity,
@@ -1611,8 +1608,8 @@ def cmd_subscription_list(context, options):
                      sum([r[3] for r in rows])])
 
     summary_str = "summary" if summary_opt else ""
-    title = "Subscription instance {0} counts: submgr-id={1}, svr-id={2}". \
-            format(summary_str, csm.submgr_id, csm.server_id)
+    title = f"Subscription instance {summary_str} counts: " \
+            f"submgr-id={csm.submgr_id}, svr-id={csm.server_id}"
 
     context.spinner_stop()
     if output_format_is_table(output_format):
@@ -1714,17 +1711,15 @@ def cmd_subscription_list_destinations(context, options):
 
             rows.append(row)
 
-        title = "Indication Destinations: submgr-id={0}, svr-id={1}, " \
-            "type={2}". \
-            format(csm.submgr_id, csm.server_id, ownedchoice_opt)
+        title = f"Indication Destinations: submgr-id={csm.submgr_id}, " \
+                f"svr-id={csm.server_id}, type={ownedchoice_opt}"
 
         context.spinner_stop()
         click.echo(format_table(rows, headers, title=title,
                                 table_format=output_format))
 
     else:
-        assert False, "{0} Invalid output format for this command". \
-            format(output_format)
+        assert False, f"{output_format} Invalid output format for this command"
 
 
 def cmd_subscription_list_filters(context, options):
@@ -1789,16 +1784,15 @@ def cmd_subscription_list_filters(context, options):
                     f.instance_property('SystemCreationClassName'),
                     f.instance_property('SystemName')])
             rows.append(row)
-        title = "Indication Filters: submgr-id={0}, svr-id={1} type={2}". \
-            format(csm.submgr_id, csm.server_id, filterchoice_opt)
+        title = f"Indication Filters: submgr-id={csm.submgr_id}, " \
+                f"svr-id={csm.server_id} type={filterchoice_opt}"
 
         context.spinner_stop()
         click.echo(format_table(rows, headers, title=title,
                                 table_format=output_format))
 
     else:
-        assert False, "{0} Invalid output format for this command". \
-            format(output_format)
+        assert False, f"{output_format} Invalid output format for this command"
 
 
 def cmd_subscription_list_subscriptions(context, options):
@@ -1888,16 +1882,15 @@ def cmd_subscription_list_subscriptions(context, options):
                     is_.instance_property('SystemCreationClassName')])
             rows.append(row)
 
-        title = "Indication Subscriptions: submgr-id={}, svr-id={}, " \
-            "type={}".format(csm.submgr_id, csm.server_id, options['type'])
+        title = f"Indication Subscriptions: submgr-id={csm.submgr_id}, " \
+                f"svr-id={csm.server_id}, type={options['type']}"
 
         context.spinner_stop()
         click.echo(format_table(rows, headers, title=title,
                                 table_format=output_format))
 
     else:
-        assert False, "{0} Invalid output format for this command". \
-            format(output_format)
+        assert False, f"{output_format} Invalid output format for this command"
 
 
 def verify_instances_removal(instance_names, instance_type):
@@ -1908,8 +1901,8 @@ def verify_instances_removal(instance_names, instance_type):
     else:
         verify_paths = instance_names
 
-    verify_msg = "Verify {0} instance(s) to be removed:\n {1}". \
-        format(instance_type, verify_paths)
+    verify_msg = \
+        f"Verify {instance_type} instance(s) to be removed:\n{verify_paths}"
 
     if not verify_operation(verify_msg):
         raise click.ClickException("Instances not removed.")
@@ -1932,30 +1925,32 @@ def cmd_subscription_remove_destination(context, identity, options):
 
     if not matching_destinations:
         raise click.ClickException(
-            "No {0} destination found for identity={1}, Name-property={2}".
-            format(owned_flag_str(owned_flag_opt), identity, target_name))
+            f"No {owned_flag_str(owned_flag_opt)} destination found for "
+            f"identity={identity}, Name-property={target_name}")
 
     if len(matching_destinations) == 1:
         destination_path = matching_destinations[0].path
 
     else:  # Multiple instances returned
         context.spinner_stop()
-        click.echo('{0} "{1}" multiple matching destinations'.
-                   format(owned_flag_str(owned_flag_opt), identity))
+        click.echo(f'{owned_flag_str(owned_flag_opt)} '
+                   f'"{identity}" multiple matching destinations')
 
         if options['select']:
             destination_path = pick_one_path_from_instances_list(
                 csm, matching_destinations,
                 "Pick indication destination to remove")
         else:
-            inst_display = [IndicationDestination(csm, d).select_id_str() for
-                            d in matching_destinations]
+            inst_ids = [IndicationDestination(csm, d).select_id_str() for
+                        d in matching_destinations]
+            # put each on new line with leading *
+            inst_display_line = "".join([f"EOL * {i}" for i in inst_ids])
+            owned = owned_flag_str(owned_flag_opt)
             raise click.ClickException(
                 "Remove failed. Multiple destinations meet criteria "
-                "identity={0}, owned={1}. Use --select option to pick one "
-                "destination:\n  * {2}".
-                format(identity, owned_flag_str(owned_flag_opt),
-                       "\n  * ".join(inst_display)))
+                f"{identity=}, {owned=}. "
+                "Use --select option to pick one destination:"
+                f"{inst_display_line}")
 
     if options['verify']:
         verify_instances_removal(destination_path, 'destination')
@@ -1964,8 +1959,9 @@ def cmd_subscription_remove_destination(context, identity, options):
     csm.remove_destinations(destination_path)
 
     context.spinner_stop()
-    click.echo("Removed {0} indication destination: identity={1}, Name={2}.".
-               format(owned_flag_str(owned_flag_opt), identity, name_property))
+    click.echo(f"Removed {owned_flag_str(owned_flag_opt)} "
+               f"indication destination: identity={identity}, "
+               f"Name={name_property}.")
     if context.verbose:
         click.echo(f"indication destination path: {destination_path}.")
 
@@ -1993,27 +1989,31 @@ def cmd_subscription_remove_filter(context, identity, options):
 
     if not matching_filters:
         raise click.ClickException(
-            "No {0} filter found for identity={1}, Name-property={2}, ".
-            format(owned_flag_str(owned_flag_opt), identity, target_name))
+            f"No {owned_flag_str(owned_flag_opt)} filter found for "
+            f"identity={identity}, Name-property={target_name}, ")
+
     # Multiples can only occur if outside client has added filters that match
     # name but not other components of path. Owned flag on cmd eliminates
     # multiples if permanent and owned ids are the same.
     if len(matching_filters) > 1:
         context.spinner_stop()
-        click.echo('{0} "{1}" multiple matching filters.'.
-                   format(owned_flag_str(owned_flag_opt), identity))
+        click.echo(f'{owned_flag_str(owned_flag_opt)} "{identity}" multiple '
+                   'matching filters.')
 
         if options['select']:
             filter_path = pick_one_path_from_instances_list(
                 csm, matching_filters, "Pick indication filter to remove")
         else:
-            inst_disp = [IndicationFilter(csm, f).select_id_str()
-                         for f in matching_filters]
+
+            filter_ids = [IndicationFilter(csm, f).select_id_str()
+                          for f in matching_filters]
+            # put each on new line with leading * char
+            inst_disp = "".join([f"EOL * {i}" for i in filter_ids])
+
             raise click.ClickException(
-                "Remove failed. Multiple filters meet criteria identity={0}, "
-                "owned={1}. Use --select option to pick one filter:\n  * {2}".
-                format(identity, owned_flag_str(owned_flag_opt),
-                       "\n  * ".join(inst_disp)))
+                "Remove failed. Multiple filters meet criteria "
+                f"identity={identity}, owned={owned_flag_str(owned_flag_opt)}. "
+                f"Use --select option to pick one filter:{inst_disp}")
 
     else:  # one filter returned
         filter_path = matching_filters[0].path
@@ -2025,8 +2025,8 @@ def cmd_subscription_remove_filter(context, identity, options):
     csm.remove_filter(filter_path)
 
     context.spinner_stop()
-    click.echo("Removed {0} indication filter: identity={1}, Name={2}.".
-               format(owned_flag_str(owned_flag_opt), identity, name_property))
+    click.echo(f"Removed {owned_flag_str(owned_flag_opt)} indication "
+               f"filter: identity={identity}, Name={name_property}.")
     if context.verbose:
         click.echo(f"Indication filter path: {filter_path}.")
 
@@ -2063,9 +2063,9 @@ def cmd_subscription_remove_subscription(context, destination_identity,
 
     if not remove_list:
         raise click.ClickException(
-            "Arguments destination_id={} and filter_id={} did not locate "
-            "any subscriptions to remove."
-            .format(destination_identity, filter_identity))
+            f"Arguments destination_id={destination_identity} and "
+            f"filter_id={filter_identity} did not locate "
+            "any subscriptions to remove.")
 
     if remove_list:
         remove_paths = [i.path for i in remove_list]
@@ -2081,15 +2081,14 @@ def cmd_subscription_remove_subscription(context, destination_identity,
         csm.remove_subscriptions(remove_paths)
 
         context.spinner_stop()
-        click.echo("Removed {0} subscription(s) for destination-id: {1}, "
-                   "filter-id: {2}.".
-                   format(len(remove_paths), destination_identity,
-                          filter_identity))
+        click.echo(f"Removed {len(remove_paths)} subscription(s) for "
+                   f"destination-id: {destination_identity}, "
+                   f"filter-id: {filter_identity}.")
 
         if context.verbose:
             subscription_paths_str = '\n'.join([str(x) for x in remove_paths])
-            click.echo("Removed subscription(s) paths: {0}".
-                       format(subscription_paths_str))
+            click.echo(
+                f"Removed subscription(s) paths: {subscription_paths_str}")
 
         # If option set, remove filter and destination if not used in other
         # associations:
@@ -2102,8 +2101,7 @@ def cmd_subscription_remove_subscription(context, destination_identity,
                     Role='Handler')
                 if not dest_refs:
                     csm.remove_destinations(dest_path)
-                    click.echo("Removed destination: {0}".
-                               format(dest_path))
+                    click.echo(f"Removed destination: {dest_path}")
             for filter_path in filter_paths:
                 filter_refs = conn.ReferenceNames(
                     filter_path, ResultClass=SUBSCRIPTION_CLASSNAME,
@@ -2125,10 +2123,10 @@ def cmd_subscription_remove_server(context, options):
     subscripts = csm.get_subscriptions(True)
 
     context.spinner_stop()
-    click.echo("Removing owned destinations, filters, and subscriptions "
-               "for server-id {0}. Remove counts: destinations={1}, "
-               "filters={2}, subscriptions={3}".
-               format(csm.server_id, len(dests), len(filters), len(subscripts)))
+    click.echo(f"Removing owned destinations, filters, and subscriptions "
+               f"for server-id {csm.server_id}. Remove counts: "
+               f"destinations={len(dests)}, filters={len(filters)}, "
+               f"subscriptions={len(subscripts)}")
 
     csm.remove_server()
     context.pywbem_server.subscription_manager = None
diff --git a/pywbemtools/pywbemcli/_common.py b/pywbemtools/pywbemcli/_common.py
index 8e1fa058..bb413c31 100644
--- a/pywbemtools/pywbemcli/_common.py
+++ b/pywbemtools/pywbemcli/_common.py
@@ -81,8 +81,8 @@ def resolve_propertylist(propertylist):
             if ',' in item:
                 if ' ' in item:
                     raise click.ClickException(
-                        "Spaces not allowed in comma-separated PropertyList: {}"
-                        .format(','.join(propertylist)))
+                        "Spaces not allowed in comma-separated PropertyList: "
+                        f"{','.join(propertylist)}")
                 pl.extend(item.split(','))
             else:
                 pl.append(item)
@@ -186,8 +186,8 @@ def pick_one_index_from_list(context, options, title, pick_always=None):
         click.echo(f'{index}: {str_}')
     max_option = len(options) - 1
     selection = None
-    msg = 'Input integer between 0 and {} or Ctrl-C to exit selection' \
-        .format(max_option)
+    msg = f'Input integer between 0 and {max_option} or Ctrl-C to exit ' \
+          f'selection'
 
     # Loop for valid user choice until valid choice made or selection aborted
     # by user
@@ -360,8 +360,8 @@ def pick_multiple_indexes_from_list(context, options, title):
             pass
         except KeyboardInterrupt:
             raise ValueError
-        click.echo('{} Invalid. Input integer between 0 and {}; hit enter to '
-                   'stop selection.'.format(selection, index))
+        click.echo(f"{selection} Invalid. Input integer between 0 and "
+                   f"{index}; hit enter to stop selection.")
 
 
 def is_classname(astring):
@@ -417,8 +417,8 @@ def filter_namelist(pattern, name_list, ignore_case=True):
         compiled_regex = re.compile(regex, flags)
 
     except Exception as ex:
-        raise click.ClickException('Regex compile error. Regex={}. Er: {}: {}'
-                                   .format(regex, ex.__class__.__name__, ex))
+        raise click.ClickException(f'Regex compile error. Regex={regex}. '
+                                   f'Er: {ex.__class__.__name__}: {ex}')
 
     new_list = [n for n in name_list for m in [compiled_regex.match(n)] if m]
 
@@ -608,9 +608,8 @@ def case_sorted(keys):
             ret.append(str(value))
             ret.append('"')
         else:
-            raise TypeError(
-                "Invalid type {} in keybinding value: {}={}"
-                .format(type(value), key, value))
+            raise TypeError(f"Invalid type {type(value)} in "
+                            f"keybinding value: {key}={value}")
 
     return ensure_unicode(''.join(ret))
 
@@ -635,16 +634,15 @@ def parse_wbemuri_str(wbemuri_str, namespace=None):
         if instance_name.namespace and namespace:
             if instance_name.namespace != namespace:
                 raise click.ClickException('Conflicting namespaces between '
-                                           'wbemuri {} and option {}'
-                                           .format(instance_name.namespace,
-                                                   namespace))
+                                           f'wbemuri {instance_name.namespace} '
+                                           f'and option {namespace}')
         elif instance_name.namespace is None and namespace:
             instance_name.namespace = namespace
 
         return instance_name
     except ValueError as ve:
-        raise click.ClickException('Invalid wbem uri input {}. Error {}'
-                                   .format(wbemuri_str, ve))
+        raise click.ClickException(f'Invalid wbem uri input {wbemuri_str}. '
+                                   f'Error {ve}')
 
 
 def str_2_bool(value):
@@ -763,8 +761,8 @@ def create_ciminstance(cim_class, kv_properties):
         try:
             cl_prop = cim_class.properties[name]
         except KeyError:
-            raise click.ClickException('Property name "{}" not in class "{}".'
-                                       .format(name, cim_class.classname))
+            raise click.ClickException(f'Property name "{name}" not in class '
+                                       f'"{cim_class.classname}".')
 
         try:
             prop = create_cimproperty(cl_prop.type,
@@ -773,12 +771,10 @@ def create_ciminstance(cim_class, kv_properties):
                                       value_str)
             properties.append((name, prop))
         except ValueError as ex:
-            raise click.ClickException("Type mismatch property '{}' between "
-                                       "expected type='{}', array={} and input "
-                                       "value='{}'. Exception: {}"
-                                       .format(name, cl_prop.type,
-                                               cl_prop.is_array,
-                                               value_str, ex))
+            raise click.ClickException(
+                f"Type mismatch property '{name}' between "
+                f"expected type='{cl_prop.type}', array={cl_prop.is_array} and "
+                f"input value='{value_str}'. Exception: {ex}")
 
     new_inst = CIMInstance(cim_class.classname, properties=properties)
 
@@ -791,8 +787,7 @@ def compare_obj(obj1, obj2, msg):
     match or False if different
     """
     if obj1 != obj2:
-        click.echo('Obj Compare {}: compare mismatch:\n{!r}\n{!r}'
-                   .format(msg, obj1, obj2))
+        click.echo(f"Obj Compare {msg}: compare mismatch:\n{obj1!r}\n{obj2!r}")
         return False
     return True
 
@@ -812,9 +807,9 @@ def compare_instances(inst1, inst2):
         if inst1.properties == inst2.properties:
             return True
         if len(inst1.properties) != len(inst2.properties):
-            click.echo('Different number of properties {} vs {}\n{}\n{}'
-                       .format(len(inst1.properties), len(inst2.properties),
-                               inst1.keys(), inst2.keys()))
+            click.echo(
+                f'Different number of properties {len(inst1.properties)} '
+                f'vs {len(inst2.properties)}\n{inst1.keys()}\n{inst2.keys()}')
             return False
         keys1 = set(inst1.keys())
         keys2 = set(inst2.keys())
@@ -932,13 +927,12 @@ def create_params(classname, cim_method, kv_params):
             name, value_str = parse_kv_pair(p)
             if name not in cim_method.parameters:
                 raise click.ClickException(
-                    "Method {} of class {} does not have a parameter {}".
-                    format(cim_method.name, classname, name))
+                    f"Method {cim_method.name} of class {classname} does not "
+                    f"have a parameter {name}")
 
             if name in params:
                 raise click.ClickException(
-                    "Method parameter {} specified multiple times".
-                    format(name))
+                    f"Method parameter {name} specified multiple times")
 
             cl_param = cim_method.parameters[name]
             is_array = cl_param.is_array
@@ -963,8 +957,7 @@ def create_params(classname, cim_method, kv_params):
     cim_methods = cim_class.methods
     if methodname not in cim_methods:
         raise click.ClickException(
-            "Class {} does not have a method {}"
-            .format(classname, methodname))
+            f"Class {classname} does not have a method {methodname}")
     cim_method = cim_methods[methodname]
 
     params = create_params(classname, cim_method, parameters)
@@ -1055,8 +1048,7 @@ def sort_cimobjects(cim_objects):
                 key=lambda obj: obj.path.to_wbem_uri(format="canonical"))
         except AttributeError as exc:
             new_exc = ValueError(
-                "CIMInstance object in sort list has no 'path' set: {}".
-                format(exc))
+                f"CIMInstance object in sort list has no 'path' set: {exc}")
             new_exc.__cause__ = None
             raise new_exc
 
@@ -1068,8 +1060,8 @@ def sort_cimobjects(cim_objects):
     if isinstance(tst_obj, tuple):
         if not isinstance(tst_obj[0], CIMClassName) or \
                 not isinstance(tst_obj[1], CIMClass):
-            raise TypeError("Items of type tuple ({}, {}) cannot be sorted".
-                            format(type(tst_obj[0]), type(tst_obj[1])))
+            raise TypeError(f"Items of type tuple ({type(tst_obj[0])}, "
+                            f"{type(tst_obj[1])}) cannot be sorted")
         return sorted(cim_objects,
                       key=lambda tup: tup[0].to_wbem_uri(format="canonical"))
 
@@ -1105,8 +1097,8 @@ def issue_warning(txt, new_value):
         if isinstance(new_value, list):
             new_value = ".".join([str(v) for v in new_value])
         pywbemtools_warn(
-            "Invalid Version qualifier value {}, class {}. {}. Set to "
-            "{}".format(version_str, cln, txt, new_value),
+            f"Invalid Version qualifier value {version_str}, class {cln}. "
+            f"{txt}. Set to {new_value}",
             ToleratedSchemaIssueWarning)
 
     try:
diff --git a/pywbemtools/pywbemcli/_common_cmd_functions.py b/pywbemtools/pywbemcli/_common_cmd_functions.py
index ce3bb12a..89b2486f 100644
--- a/pywbemtools/pywbemcli/_common_cmd_functions.py
+++ b/pywbemtools/pywbemcli/_common_cmd_functions.py
@@ -211,8 +211,8 @@ def display_errors(self, terminate=False):
         for ns, exc in self.result_errors.items():
             rows.append([ns, exc.status_code_name, exc.status_description])
 
-        title = "Request Response Errors for Target: ({}) {}". \
-            format(self.obj_type, self.target_object)
+        title = f"Request Response Errors for Target: ({self.obj_type}) " \
+                f"{self.target_object}"
 
         if output_format_is_table(self.output_format):
             headers = ['namespace', 'CIMError', "Description"]
@@ -225,21 +225,23 @@ def display_errors(self, terminate=False):
             click.echo(f"\n{title}")
             for row in rows:
                 click.echo(
-                    "namespace:{} CIMError:{} Description:{}".
-                    format(row[0], row[1], row[2]), err=True)
+                    f"namespace:{row[0]} CIMError:{row[1]} "
+                    f"Description:{row[2]}",
+                    err=True)
 
         elif output_format_is_textgroup(self.output_format):
             click.echo(f"\n{title}")
             for row in rows:
                 click.echo(
-                    "namespace:{} CIMError:{} Description:{}".
-                    format(row[0], row[1], row[2]), err=True)
+                    f"namespace:{row[0]} CIMError:{row[1]} "
+                    f"Description:{row[2]}",
+                    err=True)
 
         # Close with an exception so exception code is raised.
         if terminate:
             raise click.ClickException(
-                "Errors encountered on {} server request(s)".
-                format(len(self.result_errors)))
+                f"Errors encountered on {len(self.result_errors)} server "
+                "request(s)")
 
 
 def get_namespaces(context, namespaces, default_all_ns=False):
@@ -317,11 +319,11 @@ def get_default_ns(default_ns):
     except CIMError as ce:
         # Allow processing to continue if no interop namespace
         if ce.status_code == CIM_ERR_NOT_FOUND:
-            warning_msg('{}. Using default_namespace {}.'
-                        .format(ce, conn.default_namespace))
+            warning_msg(
+                f'{ce}. Using default_namespace {conn.default_namespace}.')
             return get_default_ns(default_ns)
-        raise click.ClickException('Failed to find namespaces. Exception: {} '
-                                   .format(ce))
+        raise click.ClickException(
+            f'Failed to find namespaces. Exception: {ce} ')
 
     except Error as er:
         raise pywbem_error_exception(er)
@@ -449,7 +451,7 @@ def set_qualifier_option(qname, option_value):
         set_qualifier_option('version', version_tuple)
 
     if options['schema'] is not None:
-        test_str = "{}_".format(options['schema'].lower())
+        test_str = f"{options['schema'].lower()}_"
         filters['schema'] = FILTERDEF(test_str, None, None)
 
     if options['subclass_of'] is not None:
@@ -481,12 +483,11 @@ def parse_version_str(version_str):
     except ValueError:
         raise click.ClickException('--since option value invalid. '
                                    'Must contain 3 integer elements: '
-                                   'int.int.int". {} received'.
-                                   format(version_str))
+                                   f'int.int.int". {version_str} received')
     if len(version_tuple) != 3:
         raise click.ClickException('Version value must contain 3 integer '
                                    'elements (int.int.int). '
-                                   '{} received'.format(version_str))
+                                   f'{version_str} received')
     return version_tuple
 
 
@@ -579,9 +580,10 @@ def class_has_qualifier(cls, qname, scopes):
                 classname=filters['subclass_of'].optionvalue,
                 deep_inheritance=True)
         except ValueError:
+            ft = filters['subclass_of'].optionvalue
             raise click.ClickException(
-                'Classname {} for "subclass-of" not found in returned classes.'
-                .format(filters['subclass_of'].optionvalue))
+                f'Classname {ft} for "subclass-of" not found in returned '
+                'classes.')
 
     # Build a list of leaf class names that will be used later as a filter on
     # the classes to be returned.
@@ -596,9 +598,10 @@ def class_has_qualifier(cls, qname, scopes):
                 leafclass_names = get_leafclass_names(classes)
 
         except ValueError:
+            ft = filters['leaf_classes'].optionvalue
             raise click.ClickException(
-                'Classname {} for "leaf_classes-of" not found in returned '
-                'classes.'.format(filters['leaf_classes'].optionvalue))
+                f'Classname {ft} for "leaf_classes-of" not found in returned '
+                'classes.')
 
     for cls in classes:
         show_class_list = []
diff --git a/pywbemtools/pywbemcli/_connection_repository.py b/pywbemtools/pywbemcli/_connection_repository.py
index 55c189a4..4ea321d3 100644
--- a/pywbemtools/pywbemcli/_connection_repository.py
+++ b/pywbemtools/pywbemcli/_connection_repository.py
@@ -66,10 +66,9 @@ def __init__(self, connections_file, message):
           connections_file (:term:`string`): Path name of connections file.
 
           message (:term:`string`): Text describing just the error
-            (without text like 'Cannot write connection file {file}').
+            (without text like 'Cannot write connection file "file name"').
         """
-        msg = 'Cannot write connections file "{0}": {1}'. \
-            format(connections_file, message)
+        msg = f'Cannot write connections file "{connections_file}": {message}'
         super().__init__(msg)
 
 
@@ -88,7 +87,7 @@ def __init__(self, connections_file, message):
           connections_file (:term:`string`): Path name of connections file.
 
           message (:term:`string`): Text describing just the error
-            (without text like 'Cannot load connection file {file}').
+            (without text like 'Cannot load connection file "file name"').
         """
         msg = f'Cannot load connections file "{connections_file}": {message}'
         super().__init__(msg)
@@ -272,8 +271,7 @@ def default_connection_name(self, name):
             self._default_connection_name = name
             self._write_connections_file()
         else:
-            raise KeyError('Connection definition {!r} not found'.
-                           format(name))
+            raise KeyError('Connection definition {name!r} not found')
 
     def file_exists(self):
         """
@@ -299,9 +297,8 @@ def __str__(self):
         exists = 'exists' if self.file_exists() else "does not exist"
         self._load_connections_file()
         count = len(self)
-        return ('Connection repository with {0} connection definitions and '
-                'connections file "{1}" ({2})'.
-                format(count, self._connections_file, exists))
+        return (f'Connection repository with {count} connection definitions '
+                f'and connections file "{self._connections_file}" ({exists})')
 
     def __repr__(self):
         """
@@ -318,9 +315,9 @@ def __repr__(self):
         items = [f"{k!r}: {v}"
                  for k, v in self._pywbemcli_servers.items()]
         items_str = ', '.join(items)
-        return ("{0}({{{1}}}, connections_file={2!r} ({3}), loaded={4!r})".
-                format(self.__class__.__name__, items_str,
-                       self._connections_file, exists, self._loaded))
+        return (f"{self.__class__.__name__}({{{items_str}}}, "
+                f"connections_file={self._connections_file!r} ({exists}), "
+                f"loaded={self._loaded!r})")
 
     def __contains__(self, name):
         """
@@ -457,12 +454,12 @@ def _load_connections_file(self):
             except OSError as exc:
                 raise ConnectionsFileLoadError(
                     self._connections_file,
-                    'Error migrating old connections file "{0}": {1}'.
-                    format(B08_DEFAULT_CONNECTIONS_FILE, exc))
+                    f'Error migrating old connections file '
+                    f'"{B08_DEFAULT_CONNECTIONS_FILE}": {exc}')
 
-            click.echo("Migrated old connections file {0!r} to {1!r}".
-                       format(B08_DEFAULT_CONNECTIONS_FILE,
-                              DEFAULT_CONNECTIONS_FILE))
+            click.echo(f"Migrated old connections file "
+                       f"{B08_DEFAULT_CONNECTIONS_FILE!r} to "
+                       f"{DEFAULT_CONNECTIONS_FILE!r}")
 
         # If the file does not exist, the connection repo still has the
         # initial state at this point, and it remains empty.
@@ -486,13 +483,13 @@ def _load_connections_file(self):
                 except TypeError as te:
                     raise ConnectionsFileLoadError(
                         self._connections_file,
-                        'Invalid type of YAML property {0}: {1}'.
-                        format(ConnectionRepository.connections_group_name, te))
+                        'Invalid type of YAML property '
+                        f'{ConnectionRepository.connections_group_name}: {te}')
                 except KeyError:
                     raise ConnectionsFileLoadError(
                         self._connections_file,
-                        'Missing YAML property {0}'.
-                        format(ConnectionRepository.connections_group_name))
+                        'Missing YAML property '
+                        f'{ConnectionRepository.connections_group_name}')
 
                 # Try getting the default connection name
                 try:
@@ -501,9 +498,8 @@ def _load_connections_file(self):
                 except KeyError:
                     raise ConnectionsFileLoadError(
                         self._connections_file,
-                        'Missing YAML property {0}'.
-                        format(
-                            ConnectionRepository.default_connection_grp_name))
+                        'Missing YAML property '
+                        f'{ConnectionRepository.default_connection_grp_name}')
 
                 # Build the PywbemServer object for each connection definition
                 for name, svr in connections_dict.items():
@@ -516,17 +512,17 @@ def _load_connections_file(self):
                         raise ConnectionsFileLoadError(
                             self._connections_file,
                             'Invalid attribute type in connection '
-                            'definition "{}": {}'.format(name, te))
+                            f'definition "{name}": {te}')
                     except ValueError as ve:
                         raise ConnectionsFileLoadError(
                             self._connections_file,
                             'Invalid attribute value in connection '
-                            'definition "{}": {}'.format(name, ve))
+                            f'definition "{name}": {ve}')
                     self._pywbemcli_servers[name] = server
                 self._loaded = True
                 if self._verbose:
-                    click.echo("Connections file loaded: {}".
-                               format(self._connections_file))
+                    click.echo(
+                        f"Connections file loaded: {self._connections_file}")
 
         except OSError as exc:
             raise ConnectionsFileLoadError(
diff --git a/pywbemtools/pywbemcli/_context_obj.py b/pywbemtools/pywbemcli/_context_obj.py
index 14e52049..ca5e2c4a 100644
--- a/pywbemtools/pywbemcli/_context_obj.py
+++ b/pywbemtools/pywbemcli/_context_obj.py
@@ -205,12 +205,11 @@ def pywbem_server(self):
         cmd = "{} {}".format(ctx.info_name or "",
                              ctx.invoked_subcommand or "")
         raise click.ClickException(
-            'No current server for command "{}" that requires a WBEM server. '
-            'Specify a server with the "--server", "--mock-server", or  '
+            f'No current server for command "{cmd}" that requires a WBEM '
+            'server. Specify a server with the "--server", "--mock-server", or '
             '"--name" general option, by setting the corresponding environment '
             'variables, or in interactive mode '
-            'use "connection select" to define a target server'.
-            format(cmd))
+            'use "connection select" to define a target server')
 
     @pywbem_server.setter
     def pywbem_server(self, value):
@@ -394,11 +393,9 @@ def display_click_context(ctx, msg=None, display_attrs=True):
     if not display_attrs:
         click.echo(ctx.obj)
     else:
-        click.echo('{} {}, attrs:\n    {}'.format(
-            msg, ctx,
-            '\n    '.join(
-                f'{i}: {v}'
-                for (i, v) in sorted(attrs.items()))))
+        myattrs = '\n    '.join(f'{i}: {v}' for (i, v) in
+                                sorted(attrs.items()))
+        click.echo(f'{msg} {ctx}, attrs:\n    {myattrs}')
 
 
 def display_click_context_parents(display_attrs=False):
diff --git a/pywbemtools/pywbemcli/_display_cimobjects.py b/pywbemtools/pywbemcli/_display_cimobjects.py
index 1ada7a2e..ce1126a9 100644
--- a/pywbemtools/pywbemcli/_display_cimobjects.py
+++ b/pywbemtools/pywbemcli/_display_cimobjects.py
@@ -170,8 +170,8 @@ def display_cim_objects(context, cim_objects, output_format, summary=False,
     if isinstance(cim_objects, NocaseDict) and \
             not any(list(cim_objects.values())):
         if context.verbose:
-            click.echo("No objects returned for namespace(s): {}".
-                       format(", ".join(cim_objects.keys())))
+            click.echo('No objects returned for namespace(s): '
+                       f'{", ".join(cim_objects.keys())}')
         return
 
     # Process by type based on receiving dictionaries of ns:objects or lists
@@ -419,8 +419,7 @@ def _display_one_cim_object(cim_object, output_format, namespace=None):
             # inserting NL between instance names for readability since the
             # display is always a single line per display
             if isinstance(cim_object, CIMInstanceName):
-                click.echo("")
-                click.echo(cim_object)
+                click.echo(f"\n{cim_object}")
             elif isinstance(cim_object, CIMClassName):
                 click.echo(cim_object)
             elif isinstance(cim_object, tuple):  # representation of class assoc
@@ -434,9 +433,9 @@ def _display_one_cim_object(cim_object, output_format, namespace=None):
                 else:
                     click.echo(cim_object)
             else:
-                raise click.ClickException('output_format {} invalid for {} '
-                                           .format(output_format,
-                                                   type(cim_object)))
+                raise click.ClickException(
+                    f'output_format {output_format} invalid '
+                    f'for {type(cim_object)}')
     elif output_format == 'xml':
         try:
             if isinstance(cim_object,
@@ -458,30 +457,29 @@ def _display_one_cim_object(cim_object, output_format, namespace=None):
                 else:
                     click.echo(cim_object)
             else:
-                assert False, "Output_format {} invalid for {}".format(
-                    output_format, type(cim_object))
+                assert False, f"Output_format {output_format} invalid " \
+                              f"for {type(cim_object)}"
 
         except AttributeError:
             # no tocimxmlstr functionality
-            raise click.ClickException('Output Format {} not supported. '
-                                       'Default to\n{!r}'
-                                       .format(output_format, cim_object))
+            raise click.ClickException(
+                f'Output Format {output_format} not supported. '
+                f'Default to\n{cim_object!r}')
     elif output_format == 'repr':
         try:
             click.echo(repr(cim_object))
         except AttributeError:
-            raise click.ClickException('"repr" display of {!r} failed'
-                                       .format(cim_object))
+            raise click.ClickException(
+                f'"repr" display of {cim_object!r} failed')
 
     elif output_format == 'txt':
         try:
             click.echo(cim_object)
         except AttributeError:
-            raise click.ClickException('"txt" display of {!r} failed'
-                                       .format(cim_object))
+            raise click.ClickException(
+                f'"txt" display of {cim_object!r} failed')
     else:
-        raise click.ClickException('Invalid output format {}'
-                                   .format(output_format))
+        raise click.ClickException(f'Invalid output format {output_format}')
 
 
 class QualDeclWrapper():  # pylint: disable=too-few-public-methods
@@ -579,7 +577,7 @@ def _display_cim_objects_summary(context, objects, output_format):
             else:
                 row[cim_type_pos] = f"{row[cim_type_pos]}(s)"
             row[len_pos] = str(row[len_pos])
-            click.echo('{} returned'.format(" ".join(row)))
+            click.echo(f'{" ".join(row)} returned')
 
 
 #
@@ -686,8 +684,8 @@ def _display_paths_as_table(objects, table_width, table_format, namespace=None):
                 headers = ['host', 'namespace', 'class'] + \
                     [f"key=\n{kn}" for kn in inst_keys]
 
-                title = 'InstanceNames: {}{}'.format(inst_names[0].classname,
-                                                     table_number_str)
+                title = f'InstanceNames: {inst_names[0].classname}' \
+                        f'{table_number_str}'
 
                 # Generate multiple tables, one for each key_name and
                 # return local to this scope.
@@ -836,8 +834,7 @@ def _format_instances_as_rows(insts, max_cell_width, include_classnames=False,
 
                 # Cache value mappings for integer-typed properties
                 if INT_TYPE_PATTERN.match(prop.type) and context:
-                    vm_key = '{}.{}'.format(
-                        inst.classname.lower(), name.lower())
+                    vm_key = f'{inst.classname.lower()}.{name.lower()}'
                     try:
                         valuemapping = valuemappings[vm_key]
                     except KeyError:
diff --git a/pywbemtools/pywbemcli/_pywbem_server.py b/pywbemtools/pywbemcli/_pywbem_server.py
index a25dd1f4..b4034231 100644
--- a/pywbemtools/pywbemcli/_pywbem_server.py
+++ b/pywbemtools/pywbemcli/_pywbem_server.py
@@ -41,8 +41,8 @@ def _raise_typeerror(name, value, rqd_type):
     Generate a TypeError for a property in pywbem_server setter that has an
     invalid type
     """
-    raise TypeError('Property "{}" value: {} must be type: "{}", not type: '
-                    '"{}"'.format(name, value, rqd_type, type(value)))
+    raise TypeError(f'Property "{name}" value: {value} must be type: '
+                    f'"{rqd_type}", not type: "{type(value)}"')
 
 
 def _validate_server_url(server):
@@ -69,12 +69,11 @@ def _validate_server_url(server):
         url = server
 
     elif re.match(r"^[a-zA-Z0-9]+://", server) is not None:
-        raise click.ClickException('Invalid scheme on server argument: {}.'
-                                   ' Use "http" or "https"'.format(server))
+        raise click.ClickException(
+            f'Invalid scheme on server argument: {server}. Use "http" or '
+            '"https"')
     else:
-        url = "{scheme}://{host}".format(
-            scheme=DEFAULT_URL_SCHEME,
-            host=DEFAULT_URL_SCHEME)
+        url = f"{DEFAULT_URL_SCHEME}://{DEFAULT_URL_SCHEME}"
 
     return url
 
@@ -110,9 +109,9 @@ def __init__(self, server=None, default_namespace=DEFAULT_NAMESPACE,
         """
 
         if server and mock_server:
-            raise ValueError('Simultaneous "--server" and '
-                             '"--mock-server" not allowed. Server: {}, '
-                             'mock_server {}'.format(server, mock_server))
+            raise ValueError(
+                'Simultaneous "--server" and "--mock-server" not allowed. '
+                f'Server: {server}, mock_server {mock_server}')
         self.server = server
         self.mock_server = mock_server
         self.name = name
@@ -266,8 +265,8 @@ def timeout(self, timeout):
         if not isinstance(timeout, int):
             _raise_typeerror("timeout", timeout, 'integer')
         if not 0 < timeout <= MAX_TIMEOUT:
-            raise ValueError('Timeout option "{}" out of range {} to {} sec'
-                             .format(timeout, 0, MAX_TIMEOUT))
+            raise ValueError(f'Timeout option "{timeout}" out of range 0 to '
+                             f'{MAX_TIMEOUT} sec')
         # pylint: disable=attribute-defined-outside-init
         self._timeout = timeout
 
@@ -431,16 +430,16 @@ def password_prompt(self, ctx):
         if self.user:
             ctx.spinner_stop()
             password = click.prompt(
-                "Enter password (user {user})" .format(user=self.user),
+                f"Enter password (user {self.user})",
                 hide_input=True,
                 confirmation_prompt=False, type=str, err=True)
             ctx.spinner_start()
             # pylint: disable=attribute-defined-outside-init
             self.password = password
         else:
-            raise click.ClickException("{cmd} requires user/password, but "
-                                       "no password provided."
-                                       .format(cmd=ctx.invoked_subcommand))
+            raise click.ClickException(
+                f"{ctx.invoked_subcommand} requires user/password, but "
+                "no password provided.")
 
     @property
     def subscription_manager(self):
@@ -667,7 +666,7 @@ def set_logger_config(self, log):
                                               propagate=True)
             except ValueError as ve:
                 raise click.ClickException('Logger configuration error. input: '
-                                           '{}. Exception: {}'.format(log, ve))
+                                           f'{log}. Exception: {ve}')
 
     def _create_connection(self, use_pull):
         """
@@ -717,8 +716,7 @@ def _create_connection(self, use_pull):
                 stats_enabled=True)
         except OSError as exc:
             raise click.ClickException(
-                'Cannot create connection to {}: {}'.
-                format(self.server, exc))
+                f'Cannot create connection to {self.server}: {exc}')
 
         # Create a WBEMServer object
         self._wbem_server = WBEMServer(conn)
diff --git a/pywbemtools/pywbemcli/_pywbemcli_operations.py b/pywbemtools/pywbemcli/_pywbemcli_operations.py
index e91739c0..94c8ceb7 100644
--- a/pywbemtools/pywbemcli/_pywbemcli_operations.py
+++ b/pywbemtools/pywbemcli/_pywbemcli_operations.py
@@ -421,9 +421,9 @@ def build_mockenv(self, server, file_path_list, connections_file,
                     or not os.path.isfile(depreg_pickle_file) \
                     or not os.path.isfile(md5_file):
                 if verbose:
-                    click.echo("Mock environment for connection definition "
-                               "'{}' will be built because it was not cached.".
-                               format(connection_name))
+                    click.echo(f"Mock environment for connection definition "
+                               f"'{connection_name}' will be built because it "
+                               "was not cached.")
                 need_rebuild = True
 
             try:
@@ -462,10 +462,10 @@ def build_mockenv(self, server, file_path_list, connections_file,
                     cached_md5_value = fp.read()
                 if new_md5_value != cached_md5_value:
                     if verbose:
-                        click.echo("Mock environment for connection "
-                                   "definition '{}' is cached but will be "
-                                   "rebuilt because the mock files have "
-                                   "changed.".format(connection_name))
+                        click.echo(f"Mock environment for connection "
+                                   f"definition '{connection_name}' is cached "
+                                   "but will be rebuilt because the mock "
+                                   "files have changed.")
                     need_rebuild = True
 
             cache_it = True
@@ -474,9 +474,9 @@ def build_mockenv(self, server, file_path_list, connections_file,
             # User-specified connections file used.
 
             if verbose:
-                click.echo("Mock environment for connection definition '{}' "
-                           "will be built because user-specified connections "
-                           "files are not cached.".format(connection_name))
+                click.echo("Mock environment for connection definition "
+                           f"'{connection_name}' will be built because "
+                           "user-specified connections files are not cached.")
             need_rebuild = True
             cache_it = False
 
@@ -484,9 +484,9 @@ def build_mockenv(self, server, file_path_list, connections_file,
             # No connections file context.
 
             if verbose:
-                click.echo("Mock environment for connection definition '{}' "
-                           "will be built because no connections file is "
-                           "known.".format(connection_name))
+                click.echo("Mock environment for connection definition "
+                           f"'{connection_name}' will be built because "
+                           "connections file is unknown.")
             need_rebuild = True
             cache_it = False
 
@@ -496,8 +496,8 @@ def build_mockenv(self, server, file_path_list, connections_file,
             except mockscripts.NotCacheable as exc:
                 if verbose:
                     click.echo("Mock environment for connection definition "
-                               "'{}' will be built because it is not "
-                               "cacheable: {}.".format(connection_name, exc))
+                               f"'{connection_name}' will be built because "
+                               f"it is not cacheable: {exc}.")
             else:
                 if connections_file and cache_it:
                     self._dump_mockenv(mockenv_pickle_file)
@@ -507,8 +507,8 @@ def build_mockenv(self, server, file_path_list, connections_file,
                         fp.write(new_md5_value)
                     if verbose:
                         click.echo("Mock environment for connection "
-                                   "definition '{}' has been written to "
-                                   "cache.".format(connection_name))
+                                   f"definition '{connection_name}' has been "
+                                   "written to cache.")
         else:
             # When no rebuild is needed, there must have been a connections
             # file set.
@@ -517,13 +517,13 @@ def build_mockenv(self, server, file_path_list, connections_file,
                 self._load_mockenv(mockenv_pickle_file, file_path_list)
                 if verbose:
                     click.echo("Mock environment for connection definition "
-                               "'{}' has been loaded from cache.".
-                               format(connection_name))
+                               f"'{connection_name}' has been loaded from "
+                               "cache.")
             except mockscripts.NotCacheable as exc:
                 if verbose:
                     click.echo("Mock environment for connection definition "
-                               "'{}' will be rebuilt because it is not "
-                               "cacheable: {}.".format(connection_name, exc))
+                               f"'{connection_name}' will be rebuilt because "
+                               f"it is not cacheable: {exc}.")
                 self._build_mockenv(server, file_path_list, verbose)
 
     def _build_mockenv(self, server, file_path_list, verbose):
@@ -565,11 +565,11 @@ def _build_mockenv(self, server, file_path_list, verbose):
                     else:
                         # display file name.  Error text displayed already.
                         if isinstance(er, pywbem.MOFParseError):
-                            msg = "MOF compile failed: File: '{}'" \
-                                "(see above)".format(file_path)
+                            msg = f"MOF compile failed: File: '{file_path}'" \
+                                "(see above)"
                         else:  # not parse error, display exception
-                            msg = "MOF compile failed: File: {} " \
-                                "Error: {}".format(file_path, er)
+                            msg = f"MOF compile failed: File: '{file_path}' " \
+                                f"Error: {er}"
                     new_exc = mockscripts.MockMOFCompileError(msg)
                     new_exc.__cause__ = None
                     raise new_exc
@@ -703,7 +703,7 @@ class PYWBEMCLIFakedConnection(BuildMockenvMixin,
                                pywbem_mock.FakedWBEMConnection):
     """
     PyWBEMCLIFakedConnection subclass adds the methods added by
-    PYWBEMCLIConnectionMixin
+    PYWBEMCLIConnectionMixin and BuildMockenvMixin
     """
     def __init__(self, *args, **kwargs):
         """
diff --git a/pywbemtools/pywbemcli/mockscripts/__init__.py b/pywbemtools/pywbemcli/mockscripts/__init__.py
index a4b8ec28..b1363d9c 100644
--- a/pywbemtools/pywbemcli/mockscripts/__init__.py
+++ b/pywbemtools/pywbemcli/mockscripts/__init__.py
@@ -156,8 +156,8 @@ def import_script(file_path):
         # We report the reason was the old setup approach. If it was en error,
         # this will surface during rebuild.
         raise NotCacheable(
-            "Mock script {} implements old setup approach with global "
-            "variables".format(file_path))
+            f"Mock script {file_path} implements old setup approach with "
+            "global variables")
 
     # This is just checked for additional safety - normally the execution
     # of mock script has failed due to missing global variables.
@@ -173,14 +173,12 @@ def script_error(file_path, exc):
     exception message, ready to be displayed.
     """
     if isinstance(exc, pywbem.Error):
-        new_exc = MockScriptError(
-            "Mock script {} failed: {}".
-            format(file_path, exc))
+        new_exc = MockScriptError(f"Mock script {file_path} failed: {exc}")
     else:
         tb = traceback.format_exception(*sys.exc_info())
+        fail_list = "\n".join(tb)
         new_exc = MockScriptError(
-            "Mock script {} failed:\n{}".
-            format(file_path, "\n".join(tb)))
+            f"Mock script {file_path} failed:\n{fail_list}")
     new_exc.__cause__ = None
     return new_exc
 
diff --git a/pywbemtools/pywbemcli/pywbemcli.py b/pywbemtools/pywbemcli/pywbemcli.py
index d52e1edb..62a697ed 100644
--- a/pywbemtools/pywbemcli/pywbemcli.py
+++ b/pywbemtools/pywbemcli/pywbemcli.py
@@ -84,6 +84,8 @@
 # command before the current command in some cases.
 PREV_LOG_OPTION = None
 
+EOL = '\n'  # Replace "\n" f-strings. "\" not fails in {} with python lt 3.12
+
 # OUTPUT_FORMATS must be
 OUTPUT_FORMATS_OPTION = list(OUTPUT_FORMATS)
 OUTPUT_FORMATS_OPTION.append("")
@@ -115,8 +117,8 @@ def disp_ctx_params(ctx, param, incomplete, verbose=False):
     Display parameters used in the call to a completion function
     """
     if verbose:
-        debug_log("ctx attrs:{0}\nparam:  {1}\n incomplete:  {2}".
-                  format(get_ctx_attrs(ctx), param, incomplete))
+        debug_log(f"ctx attrs:{get_ctx_attrs(ctx)}\nparam: "
+                  f"{param}\n incomplete: {incomplete}")
 
 
 def get_ctx_attrs(ctx):
@@ -125,10 +127,9 @@ def get_ctx_attrs(ctx):
     is True. This is used to debug the completion functions since the terminal
     is already in use as a result of the tab.
     """
-    attrs = vars(ctx)
-    return '{}'.format(
-        '\n  '.join(f'{i}: {v}' for (i, v) in
-                    sorted(attrs.items())))
+    sorted_ctx_vars = \
+        '\n  '.join(f'{i}: {v}' for (i, v) in sorted(vars(ctx).items()))
+    return f'{sorted_ctx_vars}'
 
 
 ###########################################################################
@@ -164,8 +165,7 @@ def connection_name_completer(ctx, param, incomplete):
         # not-existent file.
         if not connections_repo.file_exists():
             raise ConnectionsFileError(
-                "Connections file: '{}' does not exist.".
-                format(connections_file))
+                f"Connections file: '{connections_file}' does not exist.")
 
         # Returns list of click CompletionItems from list of keys in
         # the repository.
@@ -174,8 +174,8 @@ def connection_name_completer(ctx, param, incomplete):
 
     except ConnectionsFileError as cfe:
         pywbemtools_warn(
-            "Connection file: {0},  Fatal Error: {1}: {2}.".
-            format(connections_file, cfe.__class__.__name__, cfe),
+            f"Connection file: {connections_file},  "   # FIXIT: drop one space
+            f"Fatal Error: {cfe.__class__.__name__}: {cfe}.",
             TabCompletionError)
         return ""
 
@@ -205,14 +205,11 @@ def _validate_connection_name(connections_repo, connection_name):
 
     except KeyError:
         raise click.ClickException(
-            'Connection definition "{}" not found in connections '
-            'file "{}"'.
-            format(connection_name, connections_repo.connections_file))
+            f'Connection definition "{connection_name}" not found in '
+            f'connections file "{connections_repo.connections_file}"')
 
     except ConnectionsFileError as cfe:
-        click.echo('Fatal error: {0}: {1}'.
-                   format(cfe.__class__.__name__, cfe),
-                   err=True)
+        click.echo(f'Fatal error: {cfe.__class__.__name__}: {cfe}', err=True)
         raise click.Abort()
 
 
@@ -224,13 +221,12 @@ def _validate_connections_file(connections_repo, abort=False):
     """
     if not connections_repo.file_exists():
         if abort:
-            click.echo('Connections file does not exist: {}'.format(
-                connections_repo.connections_file), err=True)
+            click.echo("Connections file does not exist: "
+                       f"{connections_repo.connections_file}", err=True)
             raise click.Abort()
 
-        raise click.ClickException(
-            'Connections file does not exist: {}'.format(
-                connections_repo.connections_file))
+        raise click.ClickException("Connections file does not exist: "
+                                   f"{connections_repo.connections_file}")
 
 
 def _execute_startup_script(file_path, verbose):
@@ -245,11 +241,9 @@ def _execute_startup_script(file_path, verbose):
     ext = os.path.splitext(file_path)[1]
     if ext not in ['.py']:
         raise click.ClickException(
-            "File '{}' has invalid suffix '{}' "
-            "- must be '.py'".format(file_path, ext))
+            f"File '{file_path}' has invalid suffix '{ext}' - must be '.py'")
     if not os.path.isfile(file_path):
-        raise click.ClickException(
-            f"File '{file_path}' does not exist")
+        raise click.ClickException(f"File '{file_path}' does not exist")
 
     # Errors in executing the file cause abort
     with open(file_path, encoding='utf-8') as fp:
@@ -267,9 +261,9 @@ def _execute_startup_script(file_path, verbose):
             exc_type, exc_value, exc_traceback = sys.exc_info()
             tb = traceback.format_exception(exc_type, exc_value, exc_traceback)
             click.echo(
-                "Python  script '{}' defined by env var "
-                "PYWBEMCLI_STARTUP_ENVVAR failed:\n{}"
-                .format(file_path, "\n".join(tb)), err=True)
+                f"Python  script '{file_path}' defined by env var "
+                f"PYWBEMCLI_STARTUP_ENVVAR failed:\n{EOL.join(tb)}",
+                err=True)
             raise click.Abort()
 
 
@@ -301,8 +295,8 @@ def _resolve_mock_server(mock_server):
         ext = os.path.splitext(file_path)[1]
         if ext not in ['.py', '.mof']:
             raise click.ClickException(
-                "Mock file '{}' has invalid suffix '{}' "
-                "- must be '.py' or '.mof'".format(file_path, ext))
+                f"Mock file '{file_path}' has invalid suffix '{ext}' "
+                "- must be '.py' or '.mof'")
         if not os.path.isfile(file_path):
             raise click.ClickException(
                 f"Mock file '{file_path}' does not exist")
@@ -357,14 +351,11 @@ def _get_default_connection(connections_repo, verbose):
                     connections_repo:
                 connections_repo.default_connection_name = None
                 raise click.ClickException(
-                    'Default connection name: "{}" not found in '
-                    'connections file "{}"; default connection '
-                    'name cleared.'.
-                    format(connection_name,
-                           connections_repo.connections_file))
+                    f'Default connection name: "{connection_name}" not found '
+                    f'in connections file "{connections_repo.connections_file}"'
+                    'default connection name cleared.')
             if verbose:
-                click.echo('Current connection: "{}"'
-                           .format(connection_name))
+                click.echo(f'Current connection: "{connection_name}"')
             return connection_name
 
         # returns no if there is no file
@@ -372,8 +363,7 @@ def _get_default_connection(connections_repo, verbose):
 
     # Account for other exception from file access
     except ConnectionsFileError as cfc:
-        click.echo("{}, {}". format(cfc.__class__.__name__, cfc),
-                   err=True)
+        click.echo(f"{cfc.__class__.__name__}, {cfc}", err=True)
         raise click.Abort()
 
 
@@ -392,12 +382,12 @@ def _validate_server_only_options(pywbem_server, user, password, timeout,
             opt_names = ["--user", "--password", "--timeout",
                          "--verify", "--certfile", "--keyfile",
                          "--ca_certs"]
-            errors = [opt_names[c] for c, i in enumerate(opts) if i]
+
+            j_errs = ", ".join([opt_names[c] for c, i in enumerate(opts) if i])
             raise click.ClickException(
-                "General option(s): ({0}) not allowed when using a mock "
-                "server. This can happen when defining a mock server with "
-                "general options '--name', or ""'--mock-server'".
-                format(", ".join(errors)))
+                f"General option(s): ({j_errs}) not allowed when "
+                "using a mock server. This can happen when defining a mock "
+                "server with general options '--name', or '--mock-server'")
 
 
 def _create_server_instance(
@@ -514,8 +504,7 @@ def _create_server_instance(
                    'definition NAME. '
                    'This option is mutually exclusive with the --server and '
                    '--mock-server options, since each defines a WBEM server. '
-                   'Default: EnvVar {ev}, or none.'.
-                   format(ev=PYWBEMCLI_NAME_ENVVAR))
+                   f'Default: EnvVar {PYWBEMCLI_NAME_ENVVAR}, or none.')
 @click.option('-m', '--mock-server', multiple=True,
               type=click.Path(exists=True, dir_okay=False),
               metavar="FILE",
@@ -532,8 +521,7 @@ def _create_server_instance(
                    'This option may be specified multiple times, and is '
                    'mutually exclusive with the --server and --name options, '
                    'since each defines a WBEM server. '
-                   'Default: EnvVar {ev}, or none.'.
-                   format(ev=PYWBEMCLI_MOCK_SERVER_ENVVAR))
+                   f'Default: EnvVar {PYWBEMCLI_MOCK_SERVER_ENVVAR}, or none.')
 @click.option('-s', '--server', type=str, metavar='URL',
               # defaulted in code
               cls=MutuallyExclusiveOption,
@@ -548,31 +536,28 @@ def _create_server_instance(
                    'PORT defaults to 5989 for https and 5988 for http. '
                    'This option is mutually exclusive with the --mock-server '
                    'and --name options, since each defines a WBEM server. '
-                   'Default: EnvVar {ev}, or none.'.
-                   format(ev=PYWBEMCLI_SERVER_ENVVAR))
+                   f'Default: EnvVar {PYWBEMCLI_SERVER_ENVVAR}, or none.')
 @click.option('-u', '--user', type=str, metavar='TEXT',
 
               default=None,  # There is no default value
               envvar=PYWBEMCLI_USER_ENVVAR,
               help='User name for the WBEM server.  Use "" to set default in '
                    'interactive mode.'
-                   'Default: EnvVar {ev}, or none.'.
-                   format(ev=PYWBEMCLI_USER_ENVVAR))
+                   f'Default: EnvVar {PYWBEMCLI_USER_ENVVAR}, or none.')
 @click.option('-p', '--password', type=str, metavar='TEXT',
               default=None,  # There is not default value
               envvar=PYWBEMCLI_PASSWORD_ENVVAR,
               help='Password for the WBEM server. '
-                   'Default: EnvVar {ev}, or prompted for if --user '
-                   'specified. Use "" to set default in interactive mode.'.
-                   format(ev=PYWBEMCLI_PASSWORD_ENVVAR))
+                   f'Default: EnvVar {PYWBEMCLI_PASSWORD_ENVVAR}, or prompted '
+                   'for if --user specified. Use "" to set default in '
+                   'interactive mode.')
 @click.option('--verify/--no-verify', 'verify', default=None,
               # defaulted in code
               envvar=PYWBEMCLI_VERIFY_ENVVAR,
               help='If --verify, client verifies the X.509 server '
                    'certificate presented by the WBEM server during TLS/SSL '
                    'handshake. If --no-verify client bypasses verification. '
-                   'Default: EnvVar {ev}, or "--verify".'.
-                   format(ev=PYWBEMCLI_VERIFY_ENVVAR))
+                   f'Default: EnvVar {PYWBEMCLI_VERIFY_ENVVAR}, or "--verify".')
 @click.option('--ca-certs',
               type=str,
               metavar="CACERTS",
@@ -585,11 +570,10 @@ def _create_server_instance(
                    'directory; '
                    '"certifi" (pywbem 1.0 or later): Use the certs provided '
                    'by the certifi Python package; '
-                   'Default: EnvVar {ev}, or "certifi" (pywbem 1.0 or later), '
-                   'or the certs in the PEM files in the first existing '
-                   'directory from from a system defined list of directories '
-                   '(pywbem before 1.0).'.
-                   format(ev=PYWBEMCLI_CA_CERTS_ENVVAR))
+                   f'Default: EnvVar {PYWBEMCLI_CA_CERTS_ENVVAR}, or "certifi" '
+                   '(pywbem 1.0 or later), or the certs in the PEM files in '
+                   'the first existing directory from from a system defined '
+                   'list of directories (pywbem before 1.0).')
 @click.option('-c', '--certfile',
               # Ignore missing file. Issue caught in cim_operations
               type=click.Path(exists=False, dir_okay=False),
@@ -601,8 +585,7 @@ def _create_server_instance(
                    'authentication by presenting the certificate to the '
                    'WBEM server during TLS/SSL handshake.  Use "" to set '
                    'default in interactive mode. '
-                   'Default: EnvVar {ev}, or none.'.
-                   format(ev=PYWBEMCLI_CERTFILE_ENVVAR))
+                   f'Default: EnvVar {PYWBEMCLI_CERTFILE_ENVVAR}, or none.')
 @click.option('-k', '--keyfile',
               # Ignore missing file. Issue caught later
               type=click.Path(exists=False, dir_okay=False),
@@ -614,8 +597,7 @@ def _create_server_instance(
                    'Not required if the private key is part of the '
                    '--certfile file. Use "" to set default in interactive '
                    'mode.'
-                   'Default: EnvVar {ev}, or none.'.
-                   format(ev=PYWBEMCLI_KEYFILE_ENVVAR))
+                   f'Default: EnvVar {PYWBEMCLI_KEYFILE_ENVVAR}, or none.')
 @click.option('-t', '--timeout', type=click.IntRange(0, MAX_TIMEOUT),
               metavar='INT',
               # defaulted in code
@@ -623,11 +605,10 @@ def _create_server_instance(
               help='Client-side timeout (seconds) on data read for '
                    'operations with the WBEM server. This integer is the '
                    'timeout for a single server request. Pywbem retries '
-                   'reads {rt} times so the delay for read timeout failure '
-                   'may be multiple times the timeout value.'
-                   'Default: EnvVar {ev}, or {default}. Min/max: '.
-                   format(rt=HTTP_READ_RETRIES, ev=PYWBEMCLI_TIMEOUT_ENVVAR,
-                          default=DEFAULT_CONNECTION_TIMEOUT))
+                   f'reads {HTTP_READ_RETRIES} times so the delay for read '
+                   'timeout failure may be multiple times the timeout value.'
+                   f'Default: EnvVar {PYWBEMCLI_TIMEOUT_ENVVAR}, or '
+                   f'{DEFAULT_CONNECTION_TIMEOUT}. Min/max: ')
 @click.option('-U', '--use-pull', type=click.Choice(USE_PULL_OPTIONS),
               # defaulted in code
               envvar=PYWBEMCLI_USE_PULL_ENVVAR,
@@ -639,8 +620,7 @@ def _create_server_instance(
                    '"no" uses traditional operations; '
                    '"either" (default) uses pull operations if supported by '
                    'the server, and otherwise traditional operations. '
-                   'Default: EnvVar {ev}, or "either".'.
-                   format(ev=PYWBEMCLI_USE_PULL_ENVVAR))
+                   f'Default: EnvVar {PYWBEMCLI_USE_PULL_ENVVAR}, or "either".')
 @click.option('--pull-max-cnt', type=int, metavar='INT',
               # defaulted in code
               help='Maximum number of instances to be returned by the WBEM '
@@ -648,26 +628,23 @@ def _create_server_instance(
                    'are used. '
                    'This is a tuning parameter that does not affect the '
                    'external behavior of the commands. '
-                   'Default: EnvVar {ev}, or {default}'.
-                   format(ev=PYWBEMCLI_PULL_MAX_CNT_ENVVAR,
-                          default=DEFAULT_MAXPULLCNT))
+                   f'Default: EnvVar {PYWBEMCLI_PULL_MAX_CNT_ENVVAR}, or '
+                   f'{DEFAULT_MAXPULLCNT}')
 @click.option('-T', '--timestats/--no-timestats',
               default=None,
               envvar=PYWBEMCLI_TIMESTATS_ENVVAR,
               help='Display operation time statistics gathered by pywbemcli '
               'after each command. Otherwise statistics can be displayed with '
               '"statistics show" command. '
-              'Default: EnvVar {ev}, or no-timestats.'.
-              format(ev=PYWBEMCLI_TIMESTATS_ENVVAR))
+              f'Default: EnvVar {PYWBEMCLI_TIMESTATS_ENVVAR}, or no-timestats.')
 @click.option('-d', '--default-namespace', type=str, metavar='NAMESPACE',
               default=None,  # default value set in cli function
               envvar=PYWBEMCLI_DEFAULT_NAMESPACE_ENVVAR,
               help='Default namespace, to be used when commands do not '
                    'specify the --namespace command option. Use "" to set '
                    'default in interactive mode. '
-                   'Default: EnvVar {ev}, or {default}.'.
-                   format(ev=PYWBEMCLI_DEFAULT_NAMESPACE_ENVVAR,
-                          default=DEFAULT_NAMESPACE))
+                   f'Default: EnvVar {PYWBEMCLI_DEFAULT_NAMESPACE_ENVVAR}, '
+                   f'or {DEFAULT_NAMESPACE}.')
 @click.option('-o', '--output-format', metavar='FORMAT',
               default=None,  # There is no default value
               type=click.Choice(OUTPUT_FORMATS_OPTION),
@@ -714,13 +691,12 @@ def _create_server_instance(
               # Keep help text in sync with connections file definitions in
               # _connection_repository.py:
               help='Path name of the connections file to be used. '
-                   'Default: EnvVar {ev}, or "{cf}" in the user\'s home '
+                   f'Default: EnvVar {PYWBEMCLI_CONNECTIONS_FILE_ENVVAR}, '
+                   f'or "{CONNECTIONS_FILENAME}" in the user\'s home '
                    'directory (as determined using Python\'s '
                    'os.path.expanduser("~"). See there for details, '
                    'particularly for Windows). Use "" to set default '
-                   'in interactive mode. '.
-                   format(cf=CONNECTIONS_FILENAME,
-                          ev=PYWBEMCLI_CONNECTIONS_FILE_ENVVAR))
+                   'in interactive mode.')
 @click.option('--pdb', is_flag=True,
               # defaulted in code
               envvar=PYWBEMCLI_PDB_ENVVAR,
@@ -728,11 +704,9 @@ def _create_server_instance(
                    'executing the command within pywbemcli. Ignored in '
                    'interactive mode, but can be specified on each '
                    'interactive command. '
-                   'Default: EnvVar {ev}, or false.'.
-                   format(ev=PYWBEMCLI_PDB_ENVVAR))
+                   f'Default: EnvVar {PYWBEMCLI_PDB_ENVVAR}, or false.')
 @click.version_option(
-    message='%(prog)s, version %(version)s\npywbem, version {}'.format(
-        pywbem_version),
+    message=f'%(prog)s, version %(version)s\npywbem, version {pywbem_version}',
     help='Show the version of this command and the pywbem package.')
 @add_options(help_option)
 @click.pass_context
@@ -791,8 +765,8 @@ def cli(ctx, server, connection_name, default_namespace, user, password,
 
     if keyfile and not certfile:
         raise click.ClickException(
-            'The --keyfile option "{}" is allowed only if the --certfile '
-            'option is also used'.format(keyfile))
+            f'The --keyfile option "{keyfile}" is allowed only if the '
+            '--certfile option is also used')
 
     # If this env variable is set, execute the file defined by variable.
     # This is private and to be used to preload test scripts for pywbemcli
@@ -810,8 +784,8 @@ def cli(ctx, server, connection_name, default_namespace, user, password,
     if pull_max_cnt is not None:
         if pull_max_cnt < 1:
             raise click.ClickException(
-                'The --pull_max_cnt option value must be gt 1: "{}" received.'.
-                format(pull_max_cnt))
+                'The --pull_max_cnt option value must be gt 1: '
+                f'"{pull_max_cnt}" received.')
     resolved_pull_max_cnt = pull_max_cnt or DEFAULT_MAXPULLCNT
 
     resolved_timeout = timeout or DEFAULT_CONNECTION_TIMEOUT
@@ -1064,12 +1038,12 @@ def cli(ctx, server, connection_name, default_namespace, user, password,
         display_click_context(ctx, msg="DIAGNOSTICS-NEWCTX: Initial context:",
                               display_attrs=True)
 
+    # FIXIT Remove this since py 2.7
     _python_nm = sys.version_info[0:2]
     if _python_nm in ((2, 7),):
         pywbemtools_warn(
-            "Pywbemcli support for Python {}.{} is deprecated and will be "
-            "removed in a future version".
-            format(_python_nm[0], _python_nm[1]),
+            f"Pywbemcli support for Python {_python_nm[0]}.{_python_nm[1]} is "
+            "deprecated and will be removed in a future version",
             DeprecationWarning)
 
     # If no invoked_subcommand, there is no command to execute this flag
@@ -1136,9 +1110,8 @@ def repl(ctx):
 
     if not ctx.obj.connections_repo.file_exists():
         pywbemtools_warn(
-            "Connections file: '{}' does not exist. Server and connection "
-            "commands will not work.".
-            format(ctx.obj.connections_repo.connections_file),
+            f"Connections file: '{ctx.obj.connections_repo.connections_file}' "
+            "does not exist. Server and connection commands will not work.",
             InvalidConnectionFile, stacklevel=0)
 
     prompt_kwargs = {
diff --git a/pywbemtools/pywbemlistener/_cmd_listener.py b/pywbemtools/pywbemlistener/_cmd_listener.py
index 33a7e6ab..c59f2907 100644
--- a/pywbemtools/pywbemlistener/_cmd_listener.py
+++ b/pywbemtools/pywbemlistener/_cmd_listener.py
@@ -83,13 +83,13 @@
                  required=False, default=DEFAULT_LISTENER_PORT,
                  help='The port number the listener will open to receive '
                  'indications. This can be any available port. '
-                 'Default: {}'.format(DEFAULT_LISTENER_PORT)),
+                 f'Default: {DEFAULT_LISTENER_PORT}'),
     click.option('-s', '--scheme',
                  type=click.Choice(['http', 'https']),
                  metavar='SCHEME',
                  required=False, default=DEFAULT_LISTENER_SCHEME,
                  help='The scheme used by the listener (http, https). '
-                 'Default: {}'.format(DEFAULT_LISTENER_SCHEME)),
+                 f'Default: {DEFAULT_LISTENER_SCHEME}'),
     click.option('-b', '--bind-addr',
                  type=str,
                  metavar='HOST',
@@ -111,8 +111,8 @@
                  'SSL/TLS handshake. Required when using https. '
                  'The file may in addition contain the private key of the '
                  'certificate. '
-                 'Default: EnvVar {ev}, or no certificate file.'.
-                 format(ev=_config.PYWBEMLISTENER_CERTFILE_ENVVAR)),
+                 f'Default: EnvVar {_config.PYWBEMLISTENER_CERTFILE_ENVVAR}, '
+                 'or no certificate file.'),
     click.option('-k', '--keyfile',
                  type=click.Path(exists=False, dir_okay=False),
                  metavar='FILE',
@@ -122,8 +122,8 @@
                  'of the server certificate. '
                  'Required when using https and when the certificate file '
                  'does not contain the private key. '
-                 'Default: EnvVar {ev}, or no key file.'.
-                 format(ev=_config.PYWBEMLISTENER_KEYFILE_ENVVAR)),
+                 f'Default: EnvVar {_config.PYWBEMLISTENER_KEYFILE_ENVVAR}, '
+                 'or no key file.'),
     click.option('--indi-call', type=str, metavar='MODULE.FUNCTION',
                  required=False, default=None,
                  help='Call a Python function for each received indication. '
@@ -143,7 +143,7 @@
                  'indications. '
                  'Invoke with --help-format for details on the format '
                  'specification. '
-                 'Default: "{dif}".'.format(dif=DEFAULT_INDI_FORMAT)),
+                 f'Default: "{DEFAULT_INDI_FORMAT}".'),
     click.option('--help-format', is_flag=True,
                  required=False, default=False, is_eager=True,
                  help='Show help message for the format specification used '
@@ -582,8 +582,8 @@ def success_signal_handler(sig, frame):
     global RUN_STARTUP_STATUS, RUN_STARTUP_COND
 
     if _config.VERBOSE_PROCESSES_ENABLED:
-        print_out("Start process: Handling success signal ({}) from run "
-                  "process".format(sig))
+        print_out(f"Start process: Handling success signal ({sig}) from run "
+                  "process")
 
     RUN_STARTUP_STATUS = 'success'
     with RUN_STARTUP_COND:
@@ -600,8 +600,8 @@ def failure_signal_handler(sig, frame):
     global RUN_STARTUP_STATUS, RUN_STARTUP_COND
 
     if _config.VERBOSE_PROCESSES_ENABLED:
-        print_out("Start process: Handling failure signal ({}) from run "
-                  "process".format(sig))
+        print_out(f"Start process: Handling failure signal ({sig}) from run "
+                  f"process")
 
     RUN_STARTUP_STATUS = 'failure'
     with RUN_STARTUP_COND:
@@ -621,8 +621,8 @@ def wait_startup_completion(child_pid):
     global RUN_STARTUP_STATUS, RUN_STARTUP_COND
 
     if _config.VERBOSE_PROCESSES_ENABLED:
-        print_out("Start process: Waiting for run process {} to complete "
-                  "startup".format(child_pid))
+        print_out(f"Start process: Waiting for run process {child_pid} to "
+                  "complete startup")
 
     RUN_STARTUP_STATUS = 'failure'
     with RUN_STARTUP_COND:
@@ -637,8 +637,8 @@ def wait_startup_completion(child_pid):
 
     if status == 'success':
         if _config.VERBOSE_PROCESSES_ENABLED:
-            print_out("Start process: Startup of run process {} succeeded".
-                      format(child_pid))
+            print_out(f"Start process: Startup of run process {child_pid} "
+                      "succeeded")
         return 0
 
     if status == 'timeout':
@@ -653,8 +653,7 @@ def wait_startup_completion(child_pid):
     sleep(0.5)  # Give it some time to finish by itself before we clean it up
 
     if _config.VERBOSE_PROCESSES_ENABLED:
-        print_out("Start process: Startup of run process {} failed".
-                  format(child_pid))
+        print_out(f"Start process: Startup of run process {child_pid} failed")
     child_exists = False
     try:
         child_ps = psutil.Process(child_pid)
@@ -667,19 +666,19 @@ def wait_startup_completion(child_pid):
 
     if child_exists:
         if _config.VERBOSE_PROCESSES_ENABLED:
-            print_out("Start process: Cleaning up run process {} and status {}".
-                      format(child_pid, child_status))
+            print_out("Start process: Cleaning up run process "
+                      f"{child_pid} and status {child_status}")
         try:
             child_ps.terminate()
             child_ps.wait()
         except OSError as exc:
             raise click.ClickException(
-                "Cannot clean up 'run' child process with PID {}: {}: {}".
-                format(child_pid, type(exc), exc))
+                f"Cannot clean up 'run' child process with PID {child_pid}: "
+                f"{type(exc)}: {exc}")
     else:
         if _config.VERBOSE_PROCESSES_ENABLED:
-            print_out("Start process: Run process {} does not exist anymore".
-                      format(child_pid))
+            print_out(f"Start process: Run process {child_pid} "
+                      f"does not exist anymore")
     return 1
 
 
@@ -701,9 +700,9 @@ def run_exit_handler(start_pid, log_fp):
 
     if start_p:
         if _config.VERBOSE_PROCESSES_ENABLED:
-            print_out("Run process exit handler: Sending failure signal ({}) "
-                      "to start process {}".
-                      format(SIGNAL_RUN_STARTUP_FAILURE, start_pid))
+            print_out("Run process exit handler: Sending failure signal "
+                      f"({SIGNAL_RUN_STARTUP_FAILURE}) to "
+                      f"start process {start_pid}")
         try:
             os.kill(start_pid, SIGNAL_RUN_STARTUP_FAILURE)  # Sends the signal
         except OSError:
@@ -714,8 +713,8 @@ def run_exit_handler(start_pid, log_fp):
             # window between checking for it at the begin of this function,
             # and here.
             if _config.VERBOSE_PROCESSES_ENABLED:
-                print_out("Run process exit handler: Start process {} does "
-                          "not exist anymore".format(start_pid))
+                print_out("Run process exit handler: Start process "
+                          f"{start_pid} does not exist anymore")
 
     if log_fp:
         print_out(f"Closing 'run' output log file at {datetime.now()}")
@@ -1002,8 +1001,7 @@ def cmd_listener_run(context, name, options):
 
         # This message goes to the original stdout of the run process (wherever
         # that is directed to)
-        print_out("Run process {}: Output is logged to: {}".
-                  format(pid, logfile))
+        print_out(f"Run process {pid}: Output is logged to: {logfile}")
 
         # pylint: disable=consider-using-with
         log_fp = open(logfile, 'a', encoding='utf-8')
@@ -1106,8 +1104,8 @@ def file_func(indication, indication_host):
                                             indi_format)
         except Exception as exc:  # pylint: disable=broad-except
             display_str = ("Error: Cannot format indication using format "
-                           "\"{}\": {}: {}".
-                           format(indi_format, exc.__class__.__name__, exc))
+                           f"\"{indi_format}\": {exc.__class__.__name__}: "
+                           f"{exc}")
         with open(indi_file, 'a', encoding='utf-8') as fp:
             fp.write(display_str)
             fp.write('\n')
@@ -1116,8 +1114,8 @@ def file_func(indication, indication_host):
         mod_func = indi_call.rsplit('.', 1)
         if len(mod_func) < 2:
             raise click.ClickException(
-                "The --indi-call option does not specify MODULE.FUNCTION: {}".
-                format(indi_call))
+                "The --indi-call option does not specify MODULE.FUNCTION: "
+                f"{indi_call}")
         mod_name = mod_func[0]
         func_name = mod_func[1]
 
@@ -1125,44 +1123,41 @@ def file_func(indication, indication_host):
         if sys.path[0] != curdir:
             if context.verbose >= _config.VERBOSE_SETTINGS:
                 click.echo("Inserting current directory into front of Python "
-                           "module search path: {}".format(curdir))
+                           f"module search path: {curdir}")
             sys.path.insert(0, curdir)
 
         try:
             module = importlib.import_module(mod_name)
         except ImportError as exc:
             raise click.ClickException(
-                "Cannot import module {}: {}".
-                format(mod_name, exc))
+                f"Cannot import module {mod_name}: {exc}")
         except SyntaxError as exc:
             raise click.ClickException(
-                "Cannot import module {}: SyntaxError: {}".
-                format(mod_name, exc))
+                f"Cannot import module {mod_name}: SyntaxError: {exc}")
         try:
             func = getattr(module, func_name)
         except AttributeError:
             raise click.ClickException(
-                "Function {}() not found in module {}".
-                format(func_name, mod_name))
+                f"Function {func_name}() not found in module {mod_name}")
         listener.add_callback(func)
         if context.verbose >= _config.VERBOSE_SETTINGS:
-            click.echo("Added indication handler for calling function {}() "
-                       "in module {}".format(func_name, mod_name))
+            click.echo("Added indication handler for calling function "
+                       f"{func_name}() in module {mod_name}")
 
     if indi_file:
         listener.add_callback(file_func)
         if context.verbose >= _config.VERBOSE_SETTINGS:
-            click.echo("Added indication handler for appending to file {} "
-                       "with format \"{}\"".format(indi_file, indi_format))
+            click.echo('Added indication handler for appending to file '
+                       f'{indi_file} with format "{indi_format}"')
 
     click.echo(f"Running listener {name} at {url}")
 
     # Signal successful startup completion to the parent 'start' process.
     if start_pid:
         if _config.VERBOSE_PROCESSES_ENABLED:
-            print_out("Run process: Sending success signal ({}) to "
-                      "start process {}".
-                      format(SIGNAL_RUN_STARTUP_SUCCESS, start_pid))
+            print_out("Run process: Sending success signal "
+                      f"({SIGNAL_RUN_STARTUP_SUCCESS}) to start process "
+                      f"{start_pid}")
         os.kill(start_pid, SIGNAL_RUN_STARTUP_SUCCESS)  # Sends the signal
 
     try:
@@ -1170,8 +1165,7 @@ def file_func(indication, indication_host):
             sleep(60)
     except (KeyboardInterrupt, SystemExit) as exc:
         if _config.VERBOSE_PROCESSES_ENABLED:
-            print_out("Run process: Caught exception {}: {}".
-                      format(type(exc), exc))
+            print_out(f"Run process: Caught exception {type(exc)}: {exc}")
         # Note: SystemExit occurs only due to being raised in the signal handler
         # that was registered.
 
@@ -1205,7 +1199,9 @@ def cmd_listener_start(context, name, options):
         'pywbemlistener',
     ]
     if context.verbose:
-        run_args.append('-{}'.format('v' * context.verbose))
+        # python v < 3.10 char repeat in f-string invalid
+        v_arg = 'v' * context.verbose
+        run_args.append(f'-{v_arg}')
     if context.logdir:
         run_args.extend(['--logdir', context.logdir])
     run_args.extend([
@@ -1241,8 +1237,7 @@ def cmd_listener_start(context, name, options):
     popen_kwargs['start_new_session'] = True
 
     if _config.VERBOSE_PROCESSES_ENABLED:
-        print_out("Start process {}: Starting run process as: {}".
-                  format(pid, run_args))
+        print_out(f"Start process {pid}: Starting run process as: {run_args}")
 
     # pylint: disable=consider-using-with
     p = subprocess.Popen(run_args, **popen_kwargs)
@@ -1346,8 +1341,7 @@ def cmd_listener_test(context, name, options):
 
     context.spinner_stop()
 
-    click.echo("Sending the following test indication:\n{}".
-               format(indication.tomof()))
+    click.echo(f"Sending the following test indication:\n{indication.tomof()}")
 
     for i in range(1, count + 1):
 
@@ -1371,5 +1365,4 @@ def cmd_listener_test(context, name, options):
         except Error as exc:
             raise click.ClickException(str(exc))
 
-        click.echo("Sent test indication #{} to listener {} at {}".
-                   format(i, name, url))
+        click.echo(f"Sent test indication #{i} to listener {name} at {url}")
diff --git a/pywbemtools/pywbemlistener/_context_obj.py b/pywbemtools/pywbemlistener/_context_obj.py
index a0785d7e..5eee3376 100644
--- a/pywbemtools/pywbemlistener/_context_obj.py
+++ b/pywbemtools/pywbemlistener/_context_obj.py
@@ -65,10 +65,11 @@ def __init__(self, output_format, logdir, verbose, pdb, warn):
         self._spinner_obj = click_spinner.Spinner()
 
     def __repr__(self):
-        return 'ContextObj(at {:08x}, output_format={s.output_format}, ' \
+        return f'ContextObj(at {id(self):08x}, ' \
+               'output_format={s.output_format}, ' \
                'logdir={s.logdir}, verbose={s.verbose}, pdb={s.pdb}, ' \
                'warn={s.warn}, spinner_enabled={s.spinner_enabled}' \
-               .format(id(self), s=self)
+               .format(s=self)
 
     @property
     def output_format(self):
diff --git a/pywbemtools/pywbemlistener/pywbemlistener.py b/pywbemtools/pywbemlistener/pywbemlistener.py
index 9e7319fb..ceee3bfa 100644
--- a/pywbemtools/pywbemlistener/pywbemlistener.py
+++ b/pywbemtools/pywbemlistener/pywbemlistener.py
@@ -77,27 +77,26 @@
               help="Enable logging of the 'pywbemlistener run' command output "
                    "to a file in a log directory. The file will be named "
                    "'pywbemlistener_NAME.log' where NAME is the listener "
-                   "name. Default: EnvVar {ev}, or no logging.".
-                   format(ev=_config.PYWBEMLISTENER_LOGDIR_ENVVAR))
+                   "name. Default: EnvVar "
+                   f"{_config.PYWBEMLISTENER_LOGDIR_ENVVAR}, or no logging.")
 @click.option('-v', '--verbose', count=True,
               help='Verbosity level. Can be specified multiple times: '
-                   '-v: {}; -vv: {}.'.
-              format(_config.VERBOSE_1_HELP, _config.VERBOSE_2_HELP))
+                   f'-v: {_config.VERBOSE_1_HELP}; '
+                   f'-vv: {_config.VERBOSE_2_HELP}.')
 @click.option('--pdb', is_flag=True,
               default=False,
               envvar=_config.PYWBEMLISTENER_PDB_ENVVAR,
               help='Pause execution in the built-in pdb debugger just before '
                    'executing the command within pywbemlistener. '
-                   'Default: EnvVar {ev}, or no debugger.'.
-                   format(ev=_config.PYWBEMLISTENER_PDB_ENVVAR))
+                   f'Default: EnvVar {_config.PYWBEMLISTENER_PDB_ENVVAR}, or '
+                   'no debugger.')
 @click.option('--warn', is_flag=True,
               default=False,
               help='Enable display of all Python warnings. '
                    'Default: Leave warning control to the PYTHONWARNINGS '
                    'EnvVar, which by default displays no warnings.')
 @click.version_option(
-    message='%(prog)s, version %(version)s\npywbem, version {}'.format(
-        pywbem_version),
+    message=f'%(prog)s, version %(version)s\npywbem, version {pywbem_version}',
     help='Show the version of this command and the pywbem package.')
 @add_options(help_option)
 @click.pass_context
@@ -140,9 +139,8 @@ def cli(ctx, output_format, logdir, verbose, pdb, warn):
     ctx.obj = ContextObj(output_format, logdir, verbose, pdb, warn)
 
     _python_nm = sys.version_info[0:2]
-    if _python_nm in ((2, 7),):
-        pywbemtools_warn(
-            "Pywbemlistener support for Python {}.{} is deprecated and will be "
-            "removed in a future version".
-            format(_python_nm[0], _python_nm[1]),
-            DeprecationWarning)
+    if _python_nm in ((2, 7),):  # TODO:  py 2.7 warning should be removed
+        pywbemtools_warn("Pywbemlistener support for Python "
+                         f"{_python_nm[0]}.{_python_nm[1]} is deprecated "
+                         "and will be removed in a future version",
+                         DeprecationWarning)


Test patch:
diff --git a/tests/end2endtest/test_errors.py b/tests/end2endtest/test_errors.py
index 771bb02c..717929ec 100644
--- a/tests/end2endtest/test_errors.py
+++ b/tests/end2endtest/test_errors.py
@@ -33,14 +33,14 @@ def test_resourcewarning_interactive(server_url):  # noqa: F811
 
     def details(what, expected=None):
         "Return a string with details about the unexpected command result"
-        msg = """
-Unexpected {} (expected: {}):
-rc={}
+        msg = f"""
+Unexpected {what} (expected: {expected}):
+{rc=}
 stdout:
-{}
+{stdout}
 stderr:
-{}
-""".format(what, expected, rc, stdout, stderr)
+{stderr}
+"""
         return msg
 
     # Note: We want to see ResourceWarning but not other warnings, particularly
diff --git a/tests/end2endtest/test_indications.py b/tests/end2endtest/test_indications.py
index cb6b440a..2a038c46 100644
--- a/tests/end2endtest/test_indications.py
+++ b/tests/end2endtest/test_indications.py
@@ -60,17 +60,17 @@ def exec_pywbemlistener_cmd(request_params, expected_rc=0, ignore_stderr=False,
         print(f"Listener startup result rc={rc}, stderr={stderr}")
 
     if expected_rc == 0:
-        assert rc == 0, "pywbemlistener failed: params={}, rc={}, stderr={}" \
-                        .format(request_params, rc, stderr)
+        assert rc == 0, f"pywbemlistener failed: params={request_params}, " \
+            f"{rc=}, {stderr=}"
         if not ignore_stderr:
             assert stderr == '', \
                 f"pywbemlistener stderr={stderr}, rc={rc}"
         return stdout
 
     # expected rc not 0
-    assert rc == expected_rc, "pywbemlistener failed: params={} failed " \
-                              "rc={}, stderr={} " \
-                              .format(request_params, rc, stderr)
+    assert rc == expected_rc, f"pywbemlistener failed: " \
+                              f"params={request_params} failed {rc=}, " \
+                              f"{stderr=} "
     return stderr
 
 
@@ -88,10 +88,11 @@ def execute_indication_test(
     The verbose flag adds a number of console outputs as the test proceeds.
     """
     if verbose:
-        print("Test for ind_dest_scheme={}, ind_dest_addr={}, "
-              "listener_scheme={}, listener_bind_addr{}, listener_port={}".
-              format(ind_dest_scheme, ind_dest_addr, listener_scheme,
-                     listener_bind_addr, listener_port))
+        print(f"Test for {ind_dest_scheme=}, "
+              f"{ind_dest_addr=}, "
+              f"{listener_scheme=}, "
+              f"{listener_bind_addr=}, "
+              f"{listener_port=}")
     filter_id = 'ofilter1'
     dest_id = 'odest1'
     test_result = None
@@ -100,12 +101,11 @@ def execute_indication_test(
     query = 'SELECT * from Test_IndicationProviderClass'
 
     if verbose:
-        print("Create subscription. svr_url={} "
-              "ind_dest_scheme={}, ind_dest_addr={}, listener_port={}, "
-              "destid={}, filterid={}, query={}, source_namespaces={}".
-              format(svr_url, ind_dest_scheme, ind_dest_addr,
-                     listener_port, dest_id, filter_id, query,
-                     source_namespaces))
+        print(f"Create subscription. svr_url={svr_url} "
+              f"ind_dest_scheme={ind_dest_scheme}, "
+              f"ind_dest_addr={ind_dest_addr}, listener_port={listener_port}, "
+              f"destid={dest_id}, filterid={filter_id}, "
+              f"query={query}, source_namespaces={source_namespaces}")
 
     create_indication_subscription(
         svr_url, ind_dest_scheme, ind_dest_addr,
@@ -125,9 +125,8 @@ def execute_indication_test(
         pass
 
     if verbose:
-        print("Create listener name={} port={} scheme={} indi-file={}".
-              format(listener_name, listener_port, listener_scheme,
-                     indication_count_file))
+        print(f"Create listener name={listener_name} port={listener_port} "
+              f"scheme={listener_scheme} indi-file={indication_count_file}")
 
     exec_pywbemlistener_cmd(['start', listener_name,
                              '--port', str(listener_port),
@@ -139,15 +138,16 @@ def execute_indication_test(
     exec_pywbemlistener_cmd(['list'], verbose=verbose)
 
     if verbose:
-        print("Debug Send invoke method for {} instances".
-              format(indication_send_count))
+        print(f"Debug Send invoke method for {indication_send_count} instances")
     result = exec_pywbemcli_cmd(
         ['-s', svr_url, '--no-verify', '--log', 'all', 'class',
          'invokemethod',
-         'Test_IndicationProviderClass', 'SendTestIndicationsCount',
-         '--namespace', source_namespaces,
-         '--parameter', "indicationSendCount={}".
-         format(indication_send_count)])
+         'Test_IndicationProviderClass',
+         'SendTestIndicationsCount',
+         '--namespace',
+         source_namespaces,
+         '--parameter',
+         f'indicationSendCount={indication_send_count}'])
 
     if verbose:
         print(f"Debug: invoke method result {result}")
@@ -198,36 +198,33 @@ def wait_for_indications(indication_send_count, indication_count_file,
         with open(indication_count_file, encoding='UTF-8') as fp:
             rcvd_lines = len(fp.readlines())
             if verbose:
-                print("rcvd {} indications, loop {}".format(rcvd_lines,
-                                                            loop_counter))
+                print(f"rcvd {rcvd_lines} indications, loop {loop_counter}")
 
         # Restart loop counter when any indications received
         if rcvd_indication_count < rcvd_lines:
             rcvd_indication_count = rcvd_lines
             if verbose:
-                print("Rcvd {} indications  loop_counter {}".
-                      format(rcvd_indication_count, loop_counter))
+                print(f"Rcvd {rcvd_indication_count} indications  "
+                      f"loop_counter {loop_counter}")
             loop_counter = 0
 
         if rcvd_lines == indication_send_count:
             if verbose:
-                print("Received expected number of indications {0}".
-                      format(rcvd_lines))
+                print(f"Received expected number of indications {rcvd_lines}")
             break
         # If requested number of indications received, break loop
         if rcvd_lines > indication_send_count:
-            test_result = "Received too many indications rcvd={0}, " \
-                          "expected={1}". \
-                          format(rcvd_lines, indication_send_count)
+            test_result = f"Received too many indications rcvd={rcvd_lines}, " \
+                          f"expected={indication_send_count}"
             break
 
     else:
-        test_result = "Waited too long for indications. Rcvd {} \
-                      indications, expected {}. ".format(
-                      rcvd_indication_count, indication_send_count)
+        test_result = f"Waited too long for indications. " \
+                      f"Rcvd {rcvd_indication_count} " \
+                      f"indications, expected {indication_send_count}."
         if verbose:
-            print("Loop counter {} max_loop_count {}".format(loop_counter,
-                                                             max_loop_count))
+            print(
+                f"Loop counter {loop_counter} max_loop_count {max_loop_count}")
     return test_result or None
 
 
diff --git a/tests/end2endtest/utils.py b/tests/end2endtest/utils.py
index 574b987a..54161725 100644
--- a/tests/end2endtest/utils.py
+++ b/tests/end2endtest/utils.py
@@ -104,21 +104,20 @@ def exec_pywbemcli_cmd(request_params, expected_rc=0, ignore_stderr=False):
     There is a case in the code where a non-zero stderr is returned when
     rc == 0. the ingore_stderr parameter allows bypassing this.
     """
-    # print("debug: exec_pywbemcli_cmd {}".format(" ".join(request_params)))
+    # print(f"debug: exec_pywbemcli_cmd {" ".join(request_params)}")
     rc, stdout, stderr = execute_command('pywbemcli', request_params)
-    # print("debug: rc={}, stderr={}".format(rc, stderr))
+    # print(f"debug: rc={rc}, stderr={stderr}")
 
     if expected_rc == 0:
-        assert rc == 0, "pywbemcli failed: params={}, rc={}, stderr={}" \
-                        .format(request_params, rc, stderr)
+        assert rc == 0, f"pywbemcli failed: params={request_params}, {rc=}, " \
+            f"{stderr=}"
         if not ignore_stderr:
-            assert stderr == '', f"pywbemcli stderr={stderr}, rc={rc}"
+            assert stderr == '', f"pywbemcli {stderr=}, rc={rc=}"
         return stdout
 
     # expected rc not 0
-    assert rc == expected_rc, "pywbemcli failed: params={} failed rc={}, " \
-                              "stderr={} " \
-                              .format(request_params, rc, stderr)
+    assert rc == expected_rc, f"pywbemcli failed: params={request_params} " \
+                              f"failed {rc=}, {stderr=} "
     return stderr
 
 
@@ -156,8 +155,8 @@ def validate_indication_profile(server_url, expected_profile):
         profiles.append(m.groups())
 
     # validate versions of indication profile
-    assert expected_profile in profiles, "Expected profile {} not found in " \
-        "{}".format(expected_profile, profiles)
+    assert expected_profile in profiles, \
+        f"Expected profile {expected_profile} not found in {profiles}"
 
 
 def validate_required_classes(server_url, required_classes_dict):
@@ -186,8 +185,7 @@ def create_indication_subscription(server_url, listener_scheme, listener_host,
     Source namespaces which is a parameter for the filter is optional
     """
     # Create a destination
-    listener_url = "{}://{}:{}".format(listener_scheme, listener_host,
-                                       listener_port)
+    listener_url = f"{listener_scheme}://{listener_host}:{listener_port}"
 
     stdout = exec_pywbemcli_cmd(
         ['-s', server_url, '--no-verify', 'subscription', 'add-destination',
@@ -195,7 +193,7 @@ def create_indication_subscription(server_url, listener_scheme, listener_host,
 
     good_response = stdout.strip('\n')
     assert good_response == 'Added owned destination: ' \
-        'Name=pywbemdestination:defaultpywbemcliSubMgr:{}'.format(dest_id)
+        f'Name=pywbemdestination:defaultpywbemcliSubMgr:{dest_id}'
 
     # Create a filter
     cmd = ['-s', server_url, '--no-verify', 'subscription', 'add-filter',
@@ -207,7 +205,7 @@ def create_indication_subscription(server_url, listener_scheme, listener_host,
 
     good_response = stdout.strip('\n')
     assert good_response == 'Added owned filter: Name=pywbemfilter:' \
-        'defaultpywbemcliSubMgr:{}'.format(filter_id)
+        f'defaultpywbemcliSubMgr:{filter_id}'
 
     # Test filter creation that returns CIMError since we cannot test
     # this with mock. Server should return exception because of bad filter
@@ -242,8 +240,8 @@ def remove_subscription(server_url, dest_id, filter_id):
          dest_id, filter_id])
     good_response = stdout.strip('\n')
     assert good_response == \
-        'Removed 1 subscription(s) for destination-id: {}, filter-id: ' \
-        '{}.'.format(dest_id, filter_id)
+        f'Removed 1 subscription(s) for destination-id: {dest_id}, ' \
+        f'filter-id: {filter_id}.'
 
     # Remove the filter
     stdout = exec_pywbemcli_cmd(
@@ -251,8 +249,8 @@ def remove_subscription(server_url, dest_id, filter_id):
          filter_id])
     good_response = stdout.strip('\n')
     assert good_response == \
-        'Removed owned indication filter: identity={0}, ' \
-        'Name=pywbemfilter:defaultpywbemcliSubMgr:{0}.'.format(filter_id)
+        f'Removed owned indication filter: identity={filter_id}, ' \
+        f'Name=pywbemfilter:defaultpywbemcliSubMgr:{filter_id}.'
 
     # Remove the destination
     stdout = exec_pywbemcli_cmd(
@@ -261,5 +259,5 @@ def remove_subscription(server_url, dest_id, filter_id):
 
     good_response = stdout.strip('\n')
     assert good_response == \
-        'Removed owned indication destination: identity={0}, ' \
-        'Name=pywbemdestination:defaultpywbemcliSubMgr:{0}.'.format(dest_id)
+        f'Removed owned indication destination: identity={dest_id}, ' \
+        f'Name=pywbemdestination:defaultpywbemcliSubMgr:{dest_id}.'
diff --git a/tests/manual/test_pegasus.py b/tests/manual/test_pegasus.py
index 58ace1e6..e8aee6e4 100755
--- a/tests/manual/test_pegasus.py
+++ b/tests/manual/test_pegasus.py
@@ -68,8 +68,7 @@ def assert_not_found(self, regex, test_str):
             match = re.search(regex, test_str)
             if match:
                 raise AssertionError(
-                    'Found in error search regex {}, str {}'.
-                    format(regex, test_str))
+                    f'Found in error search regex {regex}, str {test_str}')
 
     def assert_found(self, regex, test_str):
         """ Test of find regex on multiline string.
@@ -82,15 +81,13 @@ def assert_found(self, regex, test_str):
             match = re.search(regex, test_str)
             if match is None:
                 raise AssertionError(
-                    'Failed search regex {}, str {}'.
-                    format(regex, test_str))
+                    f'Failed search regex {regex}, str {test_str}')
 
     @staticmethod
     def assert_success(exitcode, err):
         """Assert success"""
         assert exitcode == 0 and err == '', \
-            "Expected success; got exit code {} and stderr:\n{}". \
-            format(exitcode, err)
+            f"Expected success; got exit code {exitcode} and stderr:\n{err}"
 
 
 class TestClassGroup(Base):
diff --git a/tests/sighandler.py b/tests/sighandler.py
index 596b6e82..facf36c7 100755
--- a/tests/sighandler.py
+++ b/tests/sighandler.py
@@ -18,6 +18,8 @@
 
 SLEEP_TIME = 300
 
+EOL = '\n'  # Replace "\n" f-strings. "\" not fails in {} with python lt 3.12
+
 
 def sigstr(signal_number):
     try:
@@ -32,8 +34,7 @@ class SignalIndication(Exception):
 
 def signal_handler(signal_number, frame):
     # pylint: disable=unused-argument
-    print("handler: Received signal {} ({})".
-          format(signal_number, sigstr(signal_number)))
+    print(f"handler: Received signal {signal_number} ({sigstr(signal_number)}")
     raise SignalIndication(
         f"signal {signal_number} ({sigstr(signal_number)})")
 
@@ -41,12 +42,12 @@ def signal_handler(signal_number, frame):
 def register_handler(signal_name, condition=True):
     if condition:
         signal_number = getattr(signal, signal_name)
-        print("main: Registering handler for signal {} ({}, {})".
-              format(signal_number, signal_name, sigstr(signal_number)))
+        print(f"main: Registering handler for signal {signal_number} "
+              f"({signal_name}, {sigstr(signal_number)})")
         signal.signal(signal_number, signal_handler)
 
 
-print("main: Python: {}".format(sys.version.replace('\n', '')))
+print(f"main: Python: {sys.version.replace(EOL, '')}")
 print(f"main: Platform: {sys.platform} / {platform.platform()}")
 print(f"main: Process: {os.getpid()}")
 register_handler('SIGINT')
diff --git a/tests/unit/pytest_extensions.py b/tests/unit/pytest_extensions.py
index 10d0201e..1e68cfc3 100644
--- a/tests/unit/pytest_extensions.py
+++ b/tests/unit/pytest_extensions.py
@@ -15,6 +15,7 @@
 
 __all__ = ['simplified_test_function']
 
+EOL = '\n'  # Replace "\n" f-strings. "\" not fails in {} with python lt 3.12
 
 # Pytest determines the signature of the test function by unpacking any
 # wrapped functions (this is the default of the signature() function it
@@ -175,13 +176,12 @@ def wrapper_func(desc, kwargs, exp_exc_types, exp_warn_types, condition):
                     if exp_warn_types is None and rec_warnings:
                         lines = []
                         for w in rec_warnings:
-                            tup = (w.filename, w.lineno, w.category.__name__,
-                                   str(w.message))
-                            line = "{t[0]}:{t[1]}: {t[2]}: {t[3]}".format(t=tup)
+                            # pylint: disable=line-too-long
+                            line = f"{w.filename}:{w.lineno}: {w.category.__name__}: {str(w.message)}"  # noqa=E501
                             if line not in lines:
                                 lines.append(line)
-                        msg = "Unexpected warnings:\n{}".format(
-                            '\n'.join(lines))
+                            # pylint: enable=line-too-long
+                        msg = f"Unexpected warnings:\n{EOL.join(lines)}"
                         raise AssertionError(msg)
         return ret
 
diff --git a/tests/unit/pywbemcli/all_types_method_mock_v1new.py b/tests/unit/pywbemcli/all_types_method_mock_v1new.py
index 588308c3..ea4bf6eb 100644
--- a/tests/unit/pywbemcli/all_types_method_mock_v1new.py
+++ b/tests/unit/pywbemcli/all_types_method_mock_v1new.py
@@ -48,8 +48,8 @@ def InvokeMethod(self, methodname, localobject, params):
         if not self.class_exists(namespace, classname):
             raise pywbem.CIMError(
                 pywbem.CIM_ERR_NOT_FOUND,
-                "class {} does not exist in CIM repository, "
-                "namespace {}".format(classname, namespace))
+                f"class {classname} does not exist in CIM repository, "
+                f"namespace {namespace}")
 
         # Return the input parameters as output parameters
         out_params = params
diff --git a/tests/unit/pywbemcli/all_types_method_mock_v1old.py b/tests/unit/pywbemcli/all_types_method_mock_v1old.py
index 9946ea96..13660419 100644
--- a/tests/unit/pywbemcli/all_types_method_mock_v1old.py
+++ b/tests/unit/pywbemcli/all_types_method_mock_v1old.py
@@ -53,8 +53,8 @@ def InvokeMethod(self, methodname, localobject, params):
         if not self.class_exists(namespace, classname):
             raise pywbem.CIMError(
                 pywbem.CIM_ERR_NOT_FOUND,
-                "class {} does not exist in CIM repository, "
-                "namespace {}".format(classname, namespace))
+                f"class {classname} does not exist in CIM repository, "
+                f"namespace {namespace}")
 
         # Return the input parameters as output parameters
         out_params = params
diff --git a/tests/unit/pywbemcli/cli_test_extensions.py b/tests/unit/pywbemcli/cli_test_extensions.py
index b1c7e99a..e7011270 100644
--- a/tests/unit/pywbemcli/cli_test_extensions.py
+++ b/tests/unit/pywbemcli/cli_test_extensions.py
@@ -226,8 +226,8 @@ def command_test(self, desc, command_grp, inputs, exp_response, mock_files,
         elif isinstance(inputs, (list, tuple)):
             local_args = inputs
         else:
-            assert False, 'Invalid inputs param to test {!r}. Allowed types ' \
-                'are dict, string, list, tuple.'.format(inputs)
+            assert False, f'Invalid inputs param to test {inputs!r}. ' \
+                'Allowed types are dict, string, list, tuple.'
 
         if stdin and condition == 'pdb':
             assert False, "Condition 'pdb' cannot be used on testcases that " \
@@ -262,8 +262,7 @@ def command_test(self, desc, command_grp, inputs, exp_response, mock_files,
                                  os.path.join(TEST_DIR, mock_files)])
             else:
                 assert False, \
-                    'CLI_TEST_EXTENSIONS mock_file {} invalid' \
-                    .format(mock_files)
+                    f'CLI_TEST_EXTENSIONS mock_file {mock_files} invalid'
 
         if not stdin:
             if command_grp:
@@ -307,17 +306,16 @@ def command_test(self, desc, command_grp, inputs, exp_response, mock_files,
                 if test_definition == 'startswith':
                     assert isinstance(test_value, str)
                     assert rtn_value.startswith(test_value), \
-                        "Unexpected start of line on {} in test:\n" \
-                        "{}\n" \
+                        f"Unexpected start of line on {rtn_type} in test:\n" \
+                        f"{desc}\n" \
                         "Expected start of line:\n" \
                         "------------\n" \
-                        "{}\n" \
+                        f"{test_value}\n" \
                         "------------\n" \
                         "Actual output line(s):\n" \
                         "------------\n" \
-                        "{}\n" \
-                        "------------\n". \
-                        format(rtn_type, desc, test_value, rtn_value)
+                        f"{rtn_value}\n" \
+                        "------------\n"
                 # test that lines match between test_value and rtn_value
                 # base on regex match
                 elif test_definition == 'patterns':
@@ -357,71 +355,67 @@ def command_test(self, desc, command_grp, inputs, exp_response, mock_files,
                         assert isinstance(regex, str)
                         match_result = re.search(regex, rtn_value, re.MULTILINE)
                         assert match_result, \
-                            "Missing pattern on {} in test:\n" \
-                            "{}\n" \
+                            f"Missing pattern on {rtn_type} in test:\n" \
+                            f"{desc}\n" \
                             "Expected pattern in any line:\n" \
                             "------------\n" \
-                            "{}\n" \
+                            f"{regex}\n" \
                             "------------\n" \
                             "Actual output line(s):\n" \
                             "------------\n" \
-                            "{}\n" \
-                            "------------\n". \
-                            format(rtn_type, desc, regex, rtn_value)
+                            f"{rtn_value}\n" \
+                            "------------\n"
                 elif test_definition == 'in':
                     if isinstance(test_value, str):
                         test_value = [test_value]
                     for test_str in test_value:
                         assert test_str in rtn_value, \
-                            "Missing in-string on {} in test:\n" \
-                            "{}\n" \
+                            f"Missing in-string on {rtn_type} in test:\n" \
+                            f"{desc}\n" \
                             "Expected in-string in any line:\n" \
                             "------------\n" \
-                            "{}\n" \
+                            f"{test_str}\n" \
                             "------------\n" \
                             "Actual output line(s):\n" \
                             "------------\n" \
-                            "{}\n" \
-                            "------------\n". \
-                            format(rtn_type, desc, test_str, rtn_value)
+                            f"{rtn_value}\n" \
+                            "------------\n"
                 elif test_definition == 'innows':
                     if isinstance(test_value, str):
                         test_value = [test_value]
                     for test_str in test_value:
                         assert remove_ws(test_str, join=True) in \
                             remove_ws(rtn_value, join=True), \
-                            "Missing ws-agnostic in-string on {} in test:\n" \
-                            "{}\n" \
+                            f"Missing ws-agnostic in-string on {rtn_type} in " \
+                            f"test:\n{desc}\n" \
                             "Expected ws-agnostic in-string in any line:\n" \
                             "------------\n" \
-                            "{}\n" \
+                            f"{test_str}\n" \
                             "------------\n" \
                             "Actual output line(s):\n" \
                             "------------\n" \
-                            "{}\n" \
-                            "------------\n". \
-                            format(rtn_type, desc, test_str, rtn_value)
+                            f"{rtn_value}\n" \
+                            "------------\n"
                 elif test_definition == 'not-innows':
                     if isinstance(test_value, str):
                         test_value = [test_value]
                     for test_str in test_value:
                         assert remove_ws(test_str, join=True) not in \
                             remove_ws(rtn_value, join=True), \
-                            "Unexpected ws-agnostic in-string on {} in test:\n"\
-                            "{}\n" \
+                            f"Unexpected ws-agnostic in-string on {rtn_type} " \
+                            f"in test:\n{desc}\n" \
                             "Unexpected ws-agnostic in-string in any line:\n" \
                             "------------\n" \
-                            "{}\n" \
+                            f"{test_str}\n" \
                             "------------\n" \
                             "Actual output line(s):\n" \
                             "------------\n" \
-                            "{}\n" \
-                            "------------\n". \
-                            format(rtn_type, desc, test_str, rtn_value)
+                            f"{rtn_value}\n" \
+                            "------------\n"
                 else:
                     raise AssertionError(
-                        "Test validation {!r} is invalid in test:\n"
-                        "{}\n".format(test_definition, desc))
+                        f"Test validation {test_definition!r} is invalid in "
+                        f"test:\n{desc}\n")
 
 
 def remove_ws(inputs, join=False):
diff --git a/tests/unit/pywbemcli/conftest.py b/tests/unit/pywbemcli/conftest.py
index 328daf1b..49c717d2 100644
--- a/tests/unit/pywbemcli/conftest.py
+++ b/tests/unit/pywbemcli/conftest.py
@@ -38,7 +38,7 @@ def default_connections_file_path():
 def save_default_connections_file(request):
     """
     Fixture that saves away an existing default connections file and its backup
-    file at the begin of a test session and restores them at the end of the
+    file at the begining of a test session and restores them at the end of the
     test session.
 
     This function is called once per test session (i.e. execution of the pytest
diff --git a/tests/unit/pywbemcli/reject_deleteinstance_provider.py b/tests/unit/pywbemcli/reject_deleteinstance_provider.py
index 406b501a..a5d056f1 100644
--- a/tests/unit/pywbemcli/reject_deleteinstance_provider.py
+++ b/tests/unit/pywbemcli/reject_deleteinstance_provider.py
@@ -35,8 +35,7 @@ def DeleteInstance(self, InstanceName):
         """
         raise CIMError(
             CIM_ERR_FAILED,
-            "Deletion of {} instances is rejected".
-            format(self.provider_classnames))
+            f"Deletion of {self.provider_classnames} instances is rejected")
 
 
 def setup(conn, server, verbose):
diff --git a/tests/unit/pywbemcli/simple_mock_invokemethod_v1new.py b/tests/unit/pywbemcli/simple_mock_invokemethod_v1new.py
index a2da3e2b..e784963e 100644
--- a/tests/unit/pywbemcli/simple_mock_invokemethod_v1new.py
+++ b/tests/unit/pywbemcli/simple_mock_invokemethod_v1new.py
@@ -45,16 +45,15 @@ def InvokeMethod(self, methodname, localobject, params):
         if not self.class_exists(namespace, classname):
             raise pywbem.CIMError(
                 pywbem.CIM_ERR_NOT_FOUND,
-                "class {} does not exist in CIM repository, "
-                "namespace {}".format(classname, namespace))
+                f"class {classname} does not exist in CIM repository, "
+                f"namespace {namespace}")
 
         if isinstance(localobject, pywbem.CIMInstanceName):
             instance_store = self.cimrepository.get_instance_store(namespace)
             if not instance_store.object_exists(localobject):
                 raise pywbem.CIMError(
                     pywbem.CIM_ERR_NOT_FOUND,
-                    "Instance {0} does not exist in CIM repository",
-                    format(localobject))
+                    f"Instance {localobject} does not exist in CIM repository")
 
         # This method expects a single parameter input
         return_params = []
diff --git a/tests/unit/pywbemcli/simple_mock_invokemethod_v1old.py b/tests/unit/pywbemcli/simple_mock_invokemethod_v1old.py
index 13f00c8c..e768ab10 100644
--- a/tests/unit/pywbemcli/simple_mock_invokemethod_v1old.py
+++ b/tests/unit/pywbemcli/simple_mock_invokemethod_v1old.py
@@ -50,16 +50,15 @@ def InvokeMethod(self, methodname, localobject, params):
         if not self.class_exists(namespace, classname):
             raise pywbem.CIMError(
                 pywbem.CIM_ERR_NOT_FOUND,
-                "class {} does not exist in CIM repository, "
-                "namespace {}".format(classname, namespace))
+                f"class {classname} does not exist in CIM repository, "
+                f"namespace {namespace}")
 
         if isinstance(localobject, pywbem.CIMInstanceName):
             instance_store = self.cimrepository.get_instance_store(namespace)
             if not instance_store.object_exists(localobject):
                 raise pywbem.CIMError(
                     pywbem.CIM_ERR_NOT_FOUND,
-                    "Instance {0} does not exist in CIM repository",
-                    format(localobject))
+                    f"Instance {localobject} does not exist in CIM repository")
 
         # This method expects a single parameter input
         return_params = []
diff --git a/tests/unit/pywbemcli/standalone_mock_script.py b/tests/unit/pywbemcli/standalone_mock_script.py
index 20607018..6aef0e45 100644
--- a/tests/unit/pywbemcli/standalone_mock_script.py
+++ b/tests/unit/pywbemcli/standalone_mock_script.py
@@ -46,16 +46,15 @@ def InvokeMethod(self, methodname, localobject, params):
         if not self.class_exists(namespace, classname):
             raise pywbem.CIMError(
                 pywbem.CIM_ERR_NOT_FOUND,
-                "class {} does not exist in CIM repository, "
-                "namespace {}".format(classname, namespace))
+                f"class {classname} does not exist in CIM repository, "
+                f"namespace {namespace}")
 
         if isinstance(localobject, pywbem.CIMInstanceName):
             instance_store = self.cimrepository.get_instance_store(namespace)
             if not instance_store.object_exists(localobject):
                 raise pywbem.CIMError(
                     pywbem.CIM_ERR_NOT_FOUND,
-                    "Instance {0} does not exist in CIM repository",
-                    format(localobject))
+                    f"Instance {localobject} does not exist in CIM repository")
 
         # This method expects a single parameter input
         return_params = []
diff --git a/tests/unit/pywbemcli/test_common.py b/tests/unit/pywbemcli/test_common.py
index 4e39d6a2..6809cdf0 100644
--- a/tests/unit/pywbemcli/test_common.py
+++ b/tests/unit/pywbemcli/test_common.py
@@ -1610,8 +1610,7 @@ def test_sort_cimobjects(testcase, objects, exp_indexes):
     # order is incorrect.
     result_ids = [id(obj) for obj in result_objects]
     exp_ids = [id(objects[ix]) for ix in exp_indexes]
-    assert result_ids == exp_ids, "Ids misorder\n{}\n{}".format(result_ids,
-                                                                exp_ids)
+    assert result_ids == exp_ids, f"Ids misorder\n{result_ids}\n{exp_ids}"
 
 
 TESTCASES_SPLIT_ARRAY_VALUE = [
diff --git a/tests/unit/pywbemcli/test_connection_cmds.py b/tests/unit/pywbemcli/test_connection_cmds.py
index 1d4a9f48..7b4683b5 100644
--- a/tests/unit/pywbemcli/test_connection_cmds.py
+++ b/tests/unit/pywbemcli/test_connection_cmds.py
@@ -1392,8 +1392,7 @@ def test_file_existence(file_test):
                     f'Fail. File {connections_file} should not exist'
 
             else:
-                assert False, 'File test option name {} invalid' \
-                    .format(file_test)
+                assert False, f'File test option name {file_test} invalid'
 
         if not condition:
             pytest.skip("Condition for test case not met")
@@ -1613,8 +1612,7 @@ def test_file_existence(file_test):
                     f'Fail. File {connections_file} should not exist'
 
             else:
-                assert False, 'File test option name {} invalid' \
-                    .format(file_test)
+                assert False, f'File test option name {file_test} invalid'
 
         if not condition:
             pytest.skip("Condition for test case not met")
diff --git a/tests/unit/pywbemcli/test_connection_repository.py b/tests/unit/pywbemcli/test_connection_repository.py
index 4e3ed30a..b53587e1 100644
--- a/tests/unit/pywbemcli/test_connection_repository.py
+++ b/tests/unit/pywbemcli/test_connection_repository.py
@@ -213,8 +213,7 @@ def rename_to_bak_fails(file1, file2):
     file ends with '.bak'.
     """
     if file2.endswith('.bak'):
-        raise OSError("Mocked failure: Cannot rename {} to {}".
-                      format(file1, file2))
+        raise OSError(f"Mocked failure: Cannot rename {file1} to {file2}")
     REAL_OS_RENAME(file1, file2)
 
 
@@ -224,8 +223,7 @@ def rename_from_tmp_fails(file1, file2):
     file ends with '.tmp'.
     """
     if file1.endswith('.tmp'):
-        raise OSError("Mocked failure: Cannot rename {} to {}".
-                      format(file1, file2))
+        raise OSError(f"Mocked failure: Cannot rename {file1} to {file2}")
     REAL_OS_RENAME(file1, file2)
 
 
@@ -233,8 +231,7 @@ def rename_fails(file1, file2):
     """
     Patch function replacing os.rename() that raises OSError.
     """
-    raise OSError("Mocked failure: Cannot rename {} to {}".
-                  format(file1, file2))
+    raise OSError(f"Mocked failure: Cannot rename {file1} to {file2}")
 
 
 @contextmanager
@@ -244,8 +241,9 @@ def open_text_file_write_fails(filename, file_mode):
     OSError when the file is opened in write mode.
     """
     if 'w' in file_mode:
-        raise OSError("Mocked failure: Cannot open {} in mode {}".
-                      format(filename, file_mode))
+        raise OSError(
+            f"Mocked failure: Cannot open {filename} in mode {file_mode}")
+
     # Delegate the context manager yield to REAL_OPEN_TEXT_FILE()
     return REAL_OPEN_TEXT_FILE(filename, file_mode)
 
@@ -257,8 +255,9 @@ def open_text_file_read_fails(filename, file_mode):
     OSError when the file is opened in read mode.
     """
     if 'r' in file_mode:
-        raise OSError("Mocked failure: Cannot open {} in mode {}".
-                      format(filename, file_mode))
+        raise OSError(
+            f"Mocked failure: Cannot open {filename} in mode {file_mode}")
+
     # Delegate the context manager yield to REAL_OPEN_TEXT_FILE()
     return REAL_OPEN_TEXT_FILE(filename, file_mode)
 
diff --git a/tests/unit/pywbemcli/test_display_cimobjects.py b/tests/unit/pywbemcli/test_display_cimobjects.py
index 744f221e..1bc1eed8 100644
--- a/tests/unit/pywbemcli/test_display_cimobjects.py
+++ b/tests/unit/pywbemcli/test_display_cimobjects.py
@@ -36,6 +36,8 @@
 
 from ..pytest_extensions import simplified_test_function
 
+EOL = '\n'  # Replace "\n" f-strings. "\" not fails in {} with python lt 3.12
+
 # pylint: disable=use-dict-literal
 
 OK = True    # mark tests OK when they execute correctly
@@ -590,19 +592,16 @@ def test_format_instances_as_rows(testcase, args, kwargs, exp_rtn):
     # result is list of lists.  we want to test each item in inner list
 
     assert len(act_rtn) == len(exp_rtn), \
-        "Unexpected number of lines in test desc: {}:\n" \
-        "Expected line cnt={}:\n" \
-        "{}\n\n" \
-        "Actual line cnt={}:\n" \
-        "{}\n". \
-        format(testcase.desc, len(act_rtn), '\n'.join(act_rtn),
-               len(exp_rtn), '\n'.join(exp_rtn))
+        f"Unexpected number of lines in test desc: {testcase.desc}:\n" \
+        f"Expected line cnt={len(act_rtn)}:\n" \
+        f"{EOL.join(act_rtn)}\n\n" \
+        f"Actual line cnt={len(exp_rtn)}:\n" \
+        f"{EOL.join(exp_rtn)}\n"
 
     assert exp_rtn == act_rtn, \
-        "Unequal values for test desc: {}:\n" \
-        "Expected = {}:\n" \
-        "Actual   = {}:\n". \
-        format(testcase.desc, exp_rtn, act_rtn)
+        f"Unequal values for test desc: {testcase.desc}:\n" \
+        f"Expected = {exp_rtn}:\n" \
+        f"Actual   = {act_rtn}:\n"
 
 
 # Testcases for _display_instances_as_table()
@@ -765,9 +764,8 @@ def test_display_instances_as_table(
     stdout, _ = capsys.readouterr()
 
     assert exp_stdout == stdout, \
-        "Unexpected output in test case: {}\n" \
+        f"Unexpected output in test case: {desc}\n" \
         "Actual:\n" \
-        "{}\n" \
+        f"{stdout}\n" \
         "Expected:\n" \
-        "{}\n" \
-        "End\n".format(desc, stdout, exp_stdout)
+        f"{exp_stdout}\n"
diff --git a/tests/unit/pywbemcli/test_general_options.py b/tests/unit/pywbemcli/test_general_options.py
index 47a183fd..49c98d90 100644
--- a/tests/unit/pywbemcli/test_general_options.py
+++ b/tests/unit/pywbemcli/test_general_options.py
@@ -1203,8 +1203,8 @@ class       Command group for CIM classes.
                                 TEST_CONNECTIONS_FILE_DICT),
       'general': ['--server', 'http://initialserver', ],
       'stdin': ['-o table connection show',
-                '-v --connections-file {} -n blah connection list'.
-                format(TEST_CONNECTIONS_FILE_PATH),
+                f'-v --connections-file {TEST_CONNECTIONS_FILE_PATH} -n blah '
+                'connection list',
                 # Show that the original server is restored
                 'connection show']},
      {'stdout': ["| name | not-saved (current) |",     # Results, first cmd
diff --git a/tests/unit/pywbemcli/test_namespace_creation.py b/tests/unit/pywbemcli/test_namespace_creation.py
index 95a992ff..5cd9d354 100644
--- a/tests/unit/pywbemcli/test_namespace_creation.py
+++ b/tests/unit/pywbemcli/test_namespace_creation.py
@@ -80,8 +80,7 @@
             stdout=[
                 f"^Compiling file .*{MOCK1_MOF_FILE}",
                 f"^Target namespace '{DEFAULT_DEFAULT_NAMESPACE}'",
-                "^Creating class {}:{}$".format(
-                    DEFAULT_DEFAULT_NAMESPACE, MOCK1_CLASS),
+                f"^Creating class {DEFAULT_DEFAULT_NAMESPACE}:{MOCK1_CLASS}$",
                 f"^class {MOCK1_CLASS} {{$",
             ],
             test='regex'
@@ -101,8 +100,7 @@
             stdout=[
                 f"^Compiling file .*{MOCK1_MOF_FILE}",
                 f"^Target namespace '{MOCK1_FOO_NAMESPACE}'",
-                "^Creating class {}:{}$".format(
-                    MOCK1_FOO_NAMESPACE, MOCK1_CLASS),
+                f"^Creating class {MOCK1_FOO_NAMESPACE}:{MOCK1_CLASS}$",
                 f"^class {MOCK1_CLASS} {{$",
             ],
             test='regex'
@@ -123,12 +121,11 @@
             stdout=[
                 f"^Compiling file .*{MOCK1_MOF_FILE}",
                 f"^Target namespace '{DEFAULT_DEFAULT_NAMESPACE}'",
-                "^Creating class {}:{}$".format(
-                    DEFAULT_DEFAULT_NAMESPACE, MOCK1_CLASS),
+                f"^Creating class {DEFAULT_DEFAULT_NAMESPACE}:{MOCK1_CLASS}$",
             ],
             stderr=[
                 "CIM_ERR_INVALID_NAMESPACE.* Namespace does not exist in CIM "
-                "repository: ''{}'".format(MOCK1_FOO_NAMESPACE),
+                f"repository: ''{MOCK1_FOO_NAMESPACE}'",
             ],
             test='regex'
         ),
@@ -140,8 +137,7 @@
         None,
         dict(
             stdin=[
-                '-v -d {} class get {} --nq'.format(
-                    MOCK1_FOO_NAMESPACE, MOCK1_CLASS)
+                f'-v -d {MOCK1_FOO_NAMESPACE} class get {MOCK1_CLASS} --nq'
             ]
         ),
         dict(
@@ -149,8 +145,7 @@
             stdout=[
                 f"^Compiling file .*{MOCK1_MOF_FILE}",
                 f"^Target namespace '{MOCK1_FOO_NAMESPACE}'",
-                "^Creating class {}:{}$".format(
-                    MOCK1_FOO_NAMESPACE, MOCK1_CLASS),
+                f"^Creating class {MOCK1_FOO_NAMESPACE}:{MOCK1_CLASS}$",
                 f"^class {MOCK1_CLASS} {{$",
             ],
             test='regex'
@@ -165,8 +160,7 @@
         dict(
             general=['-d', 'bar'],
             stdin=[
-                '-v -d {} class get {} --nq'.format(
-                    MOCK1_FOO_NAMESPACE, MOCK1_CLASS)
+                f'-v -d {MOCK1_FOO_NAMESPACE} class get {MOCK1_CLASS} --nq'
             ]
         ),
         dict(
@@ -174,8 +168,7 @@
             stdout=[
                 f"^Compiling file .*{MOCK1_MOF_FILE}",
                 f"^Target namespace '{MOCK1_FOO_NAMESPACE}'",
-                "^Creating class {}:{}$".format(
-                    MOCK1_FOO_NAMESPACE, MOCK1_CLASS),
+                f"^Creating class {MOCK1_FOO_NAMESPACE}:{MOCK1_CLASS}$",
                 f"^class {MOCK1_CLASS} {{$",
             ],
             test='regex'
@@ -189,8 +182,7 @@
         None,
         dict(
             stdin=[
-                '-v class get {} --nq -n {}'.format(
-                    MOCK1_CLASS, MOCK1_FOO_NAMESPACE)
+                f'-v class get {MOCK1_CLASS} --nq -n {MOCK1_FOO_NAMESPACE}'
             ]
         ),
         dict(
@@ -198,12 +190,11 @@
             stdout=[
                 f"^Compiling file .*{MOCK1_MOF_FILE}",
                 f"^Target namespace '{DEFAULT_DEFAULT_NAMESPACE}'",
-                "^Creating class {}:{}$".format(
-                    DEFAULT_DEFAULT_NAMESPACE, MOCK1_CLASS),
+                f"^Creating class {DEFAULT_DEFAULT_NAMESPACE}:{MOCK1_CLASS}$",
             ],
             stderr=[
                 "CIM_ERR_INVALID_NAMESPACE.* Namespace does not exist in CIM "
-                "repository: ''{}'".format(MOCK1_FOO_NAMESPACE),
+                f"repository: ''{MOCK1_FOO_NAMESPACE}'",
             ],
             test='regex'
         ),
@@ -221,24 +212,21 @@
         dict(
             rc=1,
             stdout=[
-                "^Creating namespace {} .in mock support.".format(
-                    MOCK2_INTEROP_NAMESPACE),
+                f"^Creating namespace {MOCK2_INTEROP_NAMESPACE} .in mock "
+                "support.",
                 f"^Compiling file .*{MOCK2_INTEROP_MOF_FILE}",
                 f"^Target namespace '{MOCK2_INTEROP_NAMESPACE}'",
-                "^Creating class {}:{}$".format(
-                    MOCK2_INTEROP_NAMESPACE, MOCK2_INTEROP_CLASS),
+                f"^Creating class {MOCK2_INTEROP_NAMESPACE}:"
+                f"{MOCK2_INTEROP_CLASS}$",
                 f"^Compiling file .*{MOCK2_FOO_MOF_FILE}",
                 f"^Target namespace '{DEFAULT_DEFAULT_NAMESPACE}'",
-                "^Switching target namespace to '{}'".format(
-                    MOCK2_FOO_NAMESPACE),
-                "^Creating namespace {} .in MOF compiler.".format(
-                    MOCK2_FOO_NAMESPACE),
-                "^Creating class {}:{}$".format(
-                    MOCK2_FOO_NAMESPACE, MOCK2_FOO_CLASS),
+                f"^Switching target namespace to '{MOCK2_FOO_NAMESPACE}'",
+                f"^Creating namespace {MOCK2_FOO_NAMESPACE} .in MOF compiler.",
+                f"^Creating class {MOCK2_FOO_NAMESPACE}:{MOCK2_FOO_CLASS}$",
             ],
             stderr=[
-                "CIM_ERR_NOT_FOUND.: Class '{}' not found in namespace '{}'".
-                format(MOCK2_FOO_CLASS, DEFAULT_DEFAULT_NAMESPACE),
+                f"CIM_ERR_NOT_FOUND.: Class '{MOCK2_FOO_CLASS}' not found "
+                f"in namespace '{DEFAULT_DEFAULT_NAMESPACE}'",
             ],
             test='regex'
         ),
@@ -255,18 +243,16 @@
         dict(
             rc=0,
             stdout=[
-                "^Creating namespace {} .in mock support.".format(
-                    MOCK2_INTEROP_NAMESPACE),
+                f"^Creating namespace {MOCK2_INTEROP_NAMESPACE} .in "
+                "mock support.",
                 f"^Compiling file .*{MOCK2_INTEROP_MOF_FILE}",
                 f"^Target namespace '{MOCK2_INTEROP_NAMESPACE}'",
-                "^Creating class {}:{}$".format(
-                    MOCK2_INTEROP_NAMESPACE, MOCK2_INTEROP_CLASS),
+                f"^Creating class {MOCK2_INTEROP_NAMESPACE}:"
+                f"{MOCK2_INTEROP_CLASS}$",
                 f"^Compiling file .*{MOCK2_FOO_MOF_FILE}",
                 f"^Target namespace '{MOCK2_FOO_NAMESPACE}'",
-                "^Switching target namespace to '{}'".format(
-                    MOCK2_FOO_NAMESPACE),
-                "^Creating class {}:{}$".format(
-                    MOCK2_FOO_NAMESPACE, MOCK2_FOO_CLASS),
+                f"^Switching target namespace to '{MOCK2_FOO_NAMESPACE}'",
+                f"^Creating class {MOCK2_FOO_NAMESPACE}:{MOCK2_FOO_CLASS}$",
                 f"^class {MOCK2_FOO_CLASS} {{$",
             ],
             test='regex'
@@ -284,20 +270,17 @@
         dict(
             rc=0,
             stdout=[
-                "^Creating namespace {} .in mock support.".format(
-                    MOCK2_INTEROP_NAMESPACE),
+                f"^Creating namespace {MOCK2_INTEROP_NAMESPACE} .in mock "
+                "support.",
                 f"^Compiling file .*{MOCK2_INTEROP_MOF_FILE}",
                 f"^Target namespace '{MOCK2_INTEROP_NAMESPACE}'",
-                "^Creating class {}:{}$".format(
-                    MOCK2_INTEROP_NAMESPACE, MOCK2_INTEROP_CLASS),
+                f"^Creating class {MOCK2_INTEROP_NAMESPACE}:"
+                f"{MOCK2_INTEROP_CLASS}$",
                 f"^Compiling file .*{MOCK2_FOO_MOF_FILE}",
                 f"^Target namespace '{DEFAULT_DEFAULT_NAMESPACE}'",
-                "^Switching target namespace to '{}'".format(
-                    MOCK2_FOO_NAMESPACE),
-                "^Creating namespace {} .in MOF compiler.".format(
-                    MOCK2_FOO_NAMESPACE),
-                "^Creating class {}:{}$".format(
-                    MOCK2_FOO_NAMESPACE, MOCK2_FOO_CLASS),
+                f"^Switching target namespace to '{MOCK2_FOO_NAMESPACE}'",
+                f"^Creating namespace {MOCK2_FOO_NAMESPACE} .in MOF compiler.",
+                f"^Creating class {MOCK2_FOO_NAMESPACE}:{MOCK2_FOO_CLASS}$",
                 f"^class {MOCK2_FOO_CLASS} {{$",
             ],
             test='regex'
@@ -312,25 +295,22 @@
         dict(
             general=['-d', 'bar'],
             stdin=[
-                '-v -d {} class get {} --nq'.format(
-                    MOCK2_FOO_NAMESPACE, MOCK2_FOO_CLASS)
+                f'-v -d {MOCK2_FOO_NAMESPACE} class get {MOCK2_FOO_CLASS} --nq'
             ]
         ),
         dict(
             rc=0,
             stdout=[
-                "^Creating namespace {} .in mock support.".format(
-                    MOCK2_INTEROP_NAMESPACE),
+                f"^Creating namespace {MOCK2_INTEROP_NAMESPACE} .in mock "
+                "support.",
                 f"^Compiling file .*{MOCK2_INTEROP_MOF_FILE}",
                 f"^Target namespace '{MOCK2_INTEROP_NAMESPACE}'",
-                "^Creating class {}:{}$".format(
-                    MOCK2_INTEROP_NAMESPACE, MOCK2_INTEROP_CLASS),
+                f"^Creating class {MOCK2_INTEROP_NAMESPACE}:"
+                f"{MOCK2_INTEROP_CLASS}$",
                 f"^Compiling file .*{MOCK2_FOO_MOF_FILE}",
                 f"^Target namespace '{MOCK2_FOO_NAMESPACE}'",
-                "^Switching target namespace to '{}'".format(
-                    MOCK2_FOO_NAMESPACE),
-                "^Creating class {}:{}$".format(
-                    MOCK2_FOO_NAMESPACE, MOCK2_FOO_CLASS),
+                f"^Switching target namespace to '{MOCK2_FOO_NAMESPACE}'",
+                f"^Creating class {MOCK2_FOO_NAMESPACE}:{MOCK2_FOO_CLASS}$",
                 f"^class {MOCK2_FOO_CLASS} {{$",
             ],
             test='regex'
@@ -343,27 +323,23 @@
         None,
         dict(
             stdin=[
-                '-v class get {} --nq -n {}'.format(
-                    MOCK2_FOO_CLASS, MOCK2_FOO_NAMESPACE)
+                f'-v class get {MOCK2_FOO_CLASS} --nq -n {MOCK2_FOO_NAMESPACE}'
             ]
         ),
         dict(
             rc=0,
             stdout=[
-                "^Creating namespace {} .in mock support.".format(
-                    MOCK2_INTEROP_NAMESPACE),
+                f"^Creating namespace {MOCK2_INTEROP_NAMESPACE} .in mock "
+                "support.",
                 f"^Compiling file .*{MOCK2_INTEROP_MOF_FILE}",
                 f"^Target namespace '{MOCK2_INTEROP_NAMESPACE}'",
-                "^Creating class {}:{}$".format(
-                    MOCK2_INTEROP_NAMESPACE, MOCK2_INTEROP_CLASS),
+                f"^Creating class {MOCK2_INTEROP_NAMESPACE}:"
+                f"{MOCK2_INTEROP_CLASS}$",
                 f"^Compiling file .*{MOCK2_FOO_MOF_FILE}",
                 f"^Target namespace '{DEFAULT_DEFAULT_NAMESPACE}'",
-                "^Switching target namespace to '{}'".format(
-                    MOCK2_FOO_NAMESPACE),
-                "^Creating namespace {} .in MOF compiler.".format(
-                    MOCK2_FOO_NAMESPACE),
-                "^Creating class {}:{}$".format(
-                    MOCK2_FOO_NAMESPACE, MOCK2_FOO_CLASS),
+                f"^Switching target namespace to '{MOCK2_FOO_NAMESPACE}'",
+                f"^Creating namespace {MOCK2_FOO_NAMESPACE} .in MOF compiler.",
+                f"^Creating class {MOCK2_FOO_NAMESPACE}:{MOCK2_FOO_CLASS}$",
                 f"^class {MOCK2_FOO_CLASS} {{$",
             ],
             test='regex'
@@ -377,8 +353,8 @@
         None,
         dict(
             stdin=[
-                '-v -d {} class get {} --nq'.format(
-                    MOCK2_INTEROP_NAMESPACE, MOCK2_INTEROP_CLASS)
+                f"-v -d {MOCK2_INTEROP_NAMESPACE} class get "
+                f"{MOCK2_INTEROP_CLASS} --nq"
             ]
         ),
         dict(
@@ -386,16 +362,13 @@
             stdout=[
                 f"^Compiling file .*{MOCK2_INTEROP_MOF_FILE}",
                 f"^Target namespace '{MOCK2_INTEROP_NAMESPACE}'",
-                "^Creating class {}:{}$".format(
-                    MOCK2_INTEROP_NAMESPACE, MOCK2_INTEROP_CLASS),
+                f"^Creating class {MOCK2_INTEROP_NAMESPACE}:"
+                f"{MOCK2_INTEROP_CLASS}$",
                 f"^Compiling file .*{MOCK2_FOO_MOF_FILE}",
                 f"^Target namespace '{MOCK2_INTEROP_NAMESPACE}'",
-                "^Switching target namespace to '{}'".format(
-                    MOCK2_FOO_NAMESPACE),
-                "^Creating namespace {} .in MOF compiler.".format(
-                    MOCK2_FOO_NAMESPACE),
-                "^Creating class {}:{}$".format(
-                    MOCK2_FOO_NAMESPACE, MOCK2_FOO_CLASS),
+                f"^Switching target namespace to '{MOCK2_FOO_NAMESPACE}'",
+                f"^Creating namespace {MOCK2_FOO_NAMESPACE} .in MOF compiler.",
+                f"^Creating class {MOCK2_FOO_NAMESPACE}:{MOCK2_FOO_CLASS}$",
                 f"^class {MOCK2_INTEROP_CLASS} {{$",
             ],
             test='regex'
@@ -409,8 +382,8 @@
         None,
         dict(
             stdin=[
-                '-v -d {} class get {} --nq'.format(
-                    MOCK3_INTEROP_NAMESPACE, MOCK3_INTEROP_CLASS)
+                f"-v -d {MOCK3_INTEROP_NAMESPACE} class get "
+                f"{MOCK3_INTEROP_CLASS} --nq"
             ]
         ),
         dict(
@@ -418,12 +391,11 @@
             stdout=[
                 f"^Compiling file .*{MOCK3_INTEROP_MOF_FILE}",
                 f"^Target namespace '{MOCK3_INTEROP_NAMESPACE}'",
-                "^Creating class {}:{}$".format(
-                    MOCK3_INTEROP_NAMESPACE, MOCK3_INTEROP_CLASS),
+                f"^Creating class {MOCK3_INTEROP_NAMESPACE}:"
+                f"{MOCK3_INTEROP_CLASS}$",
                 f"^Compiling file .*{MOCK3_FOO_MOF_FILE}",
                 f"^Target namespace '{MOCK3_INTEROP_NAMESPACE}'",
-                "^Creating class {}:{}$".format(
-                    MOCK3_INTEROP_NAMESPACE, MOCK3_FOO_CLASS),
+                f"^Creating class {MOCK3_INTEROP_NAMESPACE}:{MOCK3_FOO_CLASS}$",
                 f"^class {MOCK3_INTEROP_CLASS} {{$",
             ],
             test='regex'
@@ -445,12 +417,11 @@
             stdout=[
                 f"^Compiling file .*{MOCK3_INTEROP_MOF_FILE}",
                 f"^Target namespace '{MOCK3_INTEROP_NAMESPACE}'",
-                "^Creating class {}:{}$".format(
-                    MOCK3_INTEROP_NAMESPACE, MOCK3_INTEROP_CLASS),
+                f"^Creating class {MOCK3_INTEROP_NAMESPACE}:"
+                f"{MOCK3_INTEROP_CLASS}$",
                 f"^Compiling file .*{MOCK3_FOO_MOF_FILE}",
                 f"^Target namespace '{MOCK3_INTEROP_NAMESPACE}'",
-                "^Creating class {}:{}$".format(
-                    MOCK3_INTEROP_NAMESPACE, MOCK3_FOO_CLASS),
+                f"^Creating class {MOCK3_INTEROP_NAMESPACE}:{MOCK3_FOO_CLASS}$",
                 f"^class {MOCK3_INTEROP_CLASS} {{$",
             ],
             test='regex'
diff --git a/tests/unit/pywbemcli/test_python_tell.py b/tests/unit/pywbemcli/test_python_tell.py
index c1e3ff5e..ae320d57 100644
--- a/tests/unit/pywbemcli/test_python_tell.py
+++ b/tests/unit/pywbemcli/test_python_tell.py
@@ -58,9 +58,8 @@ def test_tell_append_diff(file_path):
     new_size = os.stat(file_path).st_size
     exp_size = size
     assert new_size == exp_size, \
-        "original size: {}, tell() result: {}, actual new size: {}, " \
-        "expected new size: {}". \
-        format(size, pos, new_size, exp_size)
+        f"original size: {size}, tell() result: {pos}, " \
+        f"actual new size: {new_size}, expected new size: {exp_size}"
 
 
 def test_truncate_append_same(file_path):
@@ -84,5 +83,5 @@ def test_truncate_append_same(file_path):
     new_size = os.stat(file_path).st_size
     exp_size = size
     assert new_size == exp_size, \
-        "original size: {}, actual new size: {}, expected new size: {}". \
-        format(size, new_size, exp_size)
+        f"original size: {size}, actual new size: {new_size}, " \
+        f"expected new size: {exp_size}"
diff --git a/tests/unit/pywbemcli/test_pywbemcli_operations.py b/tests/unit/pywbemcli/test_pywbemcli_operations.py
index 814c4d3b..cbeae27b 100644
--- a/tests/unit/pywbemcli/test_pywbemcli_operations.py
+++ b/tests/unit/pywbemcli/test_pywbemcli_operations.py
@@ -41,9 +41,12 @@
 # pylint: disable=use-dict-literal
 
 OK = True
+RUN = True
 FAIL = False
 PDB = "pdb"
 
+EOL = '\n'  # Replace "\n" f-strings. "\" not fails in {} with python lt 3.12
+
 PYWBEM_VERSION = packaging.version.parse(pywbem.__version__)
 
 URLLIB3_VERSION = packaging.version.parse(urllib3.__version__)
@@ -1120,41 +1123,37 @@ def test_build_mockenv(testcase, test_mode, verbose, connections_file,
             stdout_lines = []
         else:
             stdout_lines = captured.stdout.strip('\n').split('\n')
+        # pylint: disable=line-too-long
         assert len(stdout_lines) == len(exp_stdout_lines), \
             "Unexpected number of lines on stdout:\n" \
-            "Testcase: {}\n" \
-            "---- Actually: {} lines:\n{}" \
-            "---- Expected: {} lines (regexp):\n{}" \
-            "---- End\n". \
-            format(testcase.desc,
-                   len(stdout_lines),
-                   ''.join([ensure_unicode(ln) + '\n'
-                            for ln in stdout_lines]),
-                   len(exp_stdout_lines),
-                   ''.join([ensure_unicode(ln) + '\n'
-                            for ln in exp_stdout_lines]))
+            f"Testcase: {testcase.desc}\n" \
+            f"---- Actually: {len(stdout_lines)} lines:\n" \
+            f"{''.join([ensure_unicode(ln) + {EOL}for ln in stdout_lines])}" \
+            f"---- Expected: {len(exp_stdout_lines)} lines (regexp):\n" \
+            f"{''.join([ensure_unicode(ln) + {EOL}for ln in exp_stdout_lines])}" \
+            "---- End\n"  # noqa E501
+        # pylint: enable=line-too-long
+
         for i, regexp in enumerate(exp_stdout_lines):
             line = stdout_lines[i]
             assert re.search(regexp, line), \
-                "Unexpected line #{} on stdout:\n" \
-                "Testcase: {}\n" \
+                f"Unexpected line #{i + 1} on stdout:\n" \
+                f"Testcase: {testcase.desc}\n" \
                 "---- Actually:\n" \
-                "{}\n" \
+                f"{line}\n" \
                 "---- Expected (regexp):\n" \
-                "{}\n" \
-                "---- End\n". \
-                format(i + 1, testcase.desc, line, regexp)
+                f"{regexp}\n" \
+                "---- End\n"
     else:
         for regexp in exp_stdout_lines:
             assert re.search(regexp, captured.stdout), \
                 "Missing line on stdout:\n" \
-                "Testcase: {}\n" \
+                f"Testcase: {testcase.desc}\n" \
                 "---- Actual stdout:\n" \
-                "{}\n" \
+                f"{captured.stdout}\n" \
                 "---- Expected line (regexp):\n" \
-                "{}\n" \
-                "---- End\n". \
-                format(testcase.desc, captured.stdout, regexp)
+                f"{regexp}\n" \
+                "---- End\n"
 
     if captured.stderr == '':
         stderr_lines = []
@@ -1162,25 +1161,19 @@ def test_build_mockenv(testcase, test_mode, verbose, connections_file,
         stderr_lines = captured.stderr.strip('\n').split('\n')
     assert len(stderr_lines) == len(exp_stderr_lines), \
         "Unexpected number of lines on stderr:\n" \
-        "Testcase: {}\n" \
-        "---- Actually: {} lines:\n{}" \
-        "---- Expected: {} lines (regexp):\n{}" \
-        "---- End\n". \
-        format(testcase.desc,
-               len(stderr_lines),
-               ''.join([ensure_unicode(ln) + '\n'
-                        for ln in stderr_lines]),
-               len(exp_stderr_lines),
-               ''.join([ensure_unicode(ln) + '\n'
-                        for ln in exp_stderr_lines]))
+        f"Testcase: {testcase.desc}\n" \
+        f"---- Actually: {len(stderr_lines)} lines:\n" \
+        f"{''.join([ensure_unicode(ln) + EOL for ln in stderr_lines])}" \
+        f"---- Expected: {len(exp_stderr_lines)} lines (regexp):\n" \
+        f"{''.join([ensure_unicode(ln) + EOL for ln in exp_stderr_lines])}" \
+        "---- End\n"
     for i, regexp in enumerate(exp_stderr_lines):
         line = stderr_lines[i]
         assert re.search(regexp, line), \
-            "Unexpected line #{} on stderr:\n" \
-            "Testcase: {}\n" \
+            f"Unexpected line #{i + 1} on stderr:\n" \
+            f"Testcase: {testcase.desc}\n" \
             "---- Actually:\n" \
-            "{}\n" \
+            f"{line}\n" \
             "---- Expected (regexp):\n" \
-            "{}\n" \
-            "---- End\n". \
-            format(i + 1, testcase.desc, line, regexp)
+            f"{regexp}\n" \
+            "---- End\n"
diff --git a/tests/unit/pywbemcli/test_subscription_cmds.py b/tests/unit/pywbemcli/test_subscription_cmds.py
index eee0b6bf..b0c6ba99 100644
--- a/tests/unit/pywbemcli/test_subscription_cmds.py
+++ b/tests/unit/pywbemcli/test_subscription_cmds.py
@@ -19,11 +19,21 @@
 pywbemcli commands must be used to add and test the various subscriptions.
 A single command can be used only  to test the add... commands. Since the
 requests sent to the mock server have a lifecycle of one interactive command
-session, stdin servers to test these commands.  Also, the mockwbemserver
-mock definition is used in a local namespace and therefore, does not get
-pickled making the time to execute each test significantly longer (ex. 5
-seconds rather than LT a second) so a number of commands were combined into
-a single test to test the create, list, and removal commands.
+session, stdin is used to generate multiple commands within a single test
+by eecuting the commands in a single command session using the pywbemcli
+repl.
+
+Users must be careful since the use of stdin and use of breakpoints are not
+compatible in the test environment.
+
+The mockwbemserver mock definition is used in a local namespace and therefore,
+does not get pickled making the time to execute each test significantly longer
+(ex. 5 seconds rather than LT a second) so a number of commands were combined
+into a single test to test the create, list, and removal commands.
+
+NOTE: This test requires a default connections file to avoid output of warnings
+from the repl code when stdin is used to generate multiple commands in the repl
+about the nonexistance of this file which messes up the stderr file.
 
 NOTE: We used long lines in the test definitions to make the tests more
 readable.
@@ -75,6 +85,7 @@ def GET_TEST_PATH_STR(filename):  # pylint: disable=invalid-name
 MOCK_CONFIRM_N_FILE = "mock_confirm_n.py"
 
 # Test connections file used in some testcases
+# TODO: Currently the following not used. See issue # 1414
 TEST_SUBSCRIPTIONS_FILE_PATH = 'tmp_subscription_options.yaml'
 TEST_SUBSCRIPTIONS_FILE_DICT = {
     'connection_definitions': {
@@ -248,7 +259,7 @@ def GET_TEST_PATH_STR(filename):  # pylint: disable=invalid-name
     # List of testcases.
     # Each testcase is a list with the following items:
     # * desc: Description of testcase.
-    # * inputs: String, or tuple/list of strings, or dict of 'env', 'args',
+    # * inputs: String, tuple/list of strings, or dict of 'env', 'args',
     #     'general', and 'stdin'. See the 'inputs' parameter of
     #     CLITestsBase.command_test() in cli_test_extensions.py for detailed
     #     documentation.
@@ -261,6 +272,12 @@ def GET_TEST_PATH_STR(filename):  # pylint: disable=invalid-name
     #     the debugger, if 'verbose' print verbose messages, if False the test
     #     is skipped.
 
+    #
+    #  Test of subscription command help responses.  These tests all use a
+    #  list to define the parameters of the command and use only a single
+    #  command.
+    #
+
     ['Verify subscription command --help response',
      ['--help'],
      {'stdout': SUBSCRIPTION_HELP_LINES,
@@ -355,6 +372,9 @@ def GET_TEST_PATH_STR(filename):  # pylint: disable=invalid-name
 
     #
     #  Create a destination and list the connection in the next command
+    # These tests use a dictionary as the input defining the 'general' key
+    # for general options, and the commands in a list defined by the 'stdin'
+    # key.
     #
     ['Verify add-destination succeeds and list.',
      {'general': ['-m', MOCK_SERVER_MODEL_PATH],
@@ -882,7 +902,7 @@ def GET_TEST_PATH_STR(filename):  # pylint: disable=invalid-name
                  '};'],
       'stderr': [],
       'test': 'innows'},
-     None, RUN],
+     None, OK],
 
     ['Verify add dest, filter, subscription and remove --permanent OK.',
      {'general': ['-m', MOCK_SERVER_MODEL_PATH],
@@ -1309,10 +1329,9 @@ def GET_TEST_PATH_STR(filename):  # pylint: disable=invalid-name
                 'subscription remove-destination duptestdest --permanent',
                 '-o simple subscription list'],
       'platform': 'win32'},  # ignore on windows
-     {'stderr': ['Remove failed. Multiple destinations meet criteria identity=duptestdest, owned=permanent',  # noqa: E501
-                 '* CIM_ListenerDestinationCIMXML.CreationClassName="CIM_ListenerDestinationCIMXML",Name="duptestdest",SystemCreationClassName="CIM_ComputerSystem",SystemName="MockSystem_WBEMServerTest',  # noqa: E501
-                 '* CIM_ListenerDestinationCIMXMLSub.CreationClassName="CIM_ListenerDestinationCIMXMLSub",Name="duptestdest",SystemCreationClassName="CIM_ComputerSystem",SystemName="blah'],  # noqa: E501
-
+     {'stderr': ["Remove failed. Multiple destinations meet criteria identity='duptestdest', owned='permanent'",  # noqa: E501
+                 '* CIM_ListenerDestinationCIMXML.CreationClassName="CIM_ListenerDestinationCIMXML",Name="duptestdest",SystemCreationClassName="CIM_ComputerSystem",SystemName="MockSystem_WBEMServerTest"',  # noqa: E501
+                 '* CIM_ListenerDestinationCIMXMLSub.CreationClassName="CIM_ListenerDestinationCIMXMLSub",Name="duptestdest",SystemCreationClassName="CIM_ComputerSystem",SystemName="blah"'],  # noqa: E501
       'rc': 0,
       'test': 'innows'},
      None, OK],
@@ -1658,13 +1677,16 @@ class command that can be tested.  This includes:
                 return
 
         # Create the connection file from the 'yaml' input
-        if 'yaml' in inputs:
-            # pylint: disable=unspecified-encoding
-            with open(TEST_SUBSCRIPTIONS_FILE_PATH, "w") as repo_file:
-                repo_file.write(inputs['yaml'])
+        # The following removed because it was never used and is not docemented
+        # if 'yaml' in inputs:
+        #    # pylint: disable=unspecified-encoding
+        #    with open(TEST_SUBSCRIPTIONS_FILE_PATH, "w") as repo_file:
+        #        repo_file.write(inputs['yaml'])
 
         # All tests in for subscriptions will use the subscriptions
         # connections file.
+        # TODO: The following to be corrected.  Currently the connections
+        # file is not used in these tests. See issue #1414
         connections_file = TEST_SUBSCRIPTIONS_FILE_PATH
         if 'general' in inputs:
             inputs['general'].extend(['--connections-file', connections_file])
diff --git a/tests/unit/pywbemcli/testmock/wbemserver_mock_class.py b/tests/unit/pywbemcli/testmock/wbemserver_mock_class.py
index 667396c2..a444dd15 100644
--- a/tests/unit/pywbemcli/testmock/wbemserver_mock_class.py
+++ b/tests/unit/pywbemcli/testmock/wbemserver_mock_class.py
@@ -335,30 +335,29 @@ def __init__(self, conn, server, interop_ns=None, server_mock_data=None,
         self.display("Built central instances and element_conforms_to_Profile")
 
     def __str__(self):
-        return 'object_manager_name={!r}, interop_ns={!r}, system_name=' \
-            '{!r}, dmtf_schema_ver={!r}, schema_dir={!r}, wbem_server={}' \
-            .format(self.server_mock_data['object_manager']['Name'],
-                    self.interop_ns,
-                    self.server_mock_data['system_name'],
-                    self.server_mock_data['dmtf_schema']['version'],
-                    self.server_mock_data['dmtf_schema']['dir'],
-                    getattr(self, 'wbem_server', None))
+        # pylint: disable=line-too-long
+        return f"object_manager_name={self.server_mock_data['object_manager']['Name']!r}, " \
+               f"interop_ns={self.interop_ns!r}, " \
+               f"system_name={self.server_mock_data['system_name']!r}, " \
+               f"dmtf_schema_ver={self.server_mock_data['dmtf_schema']['version']!r}, " \
+               f"schema_dir={self.server_mock_data['dmtf_schema']['dir']!r}, " \
+               f"wbem_server={getattr(self, 'wbem_server', None)}"  # noqa=E501
+        # pylint: enable=line-too-long
 
     def __repr__(self):
         """
         Return a representation of the class object
         with all attributes, that is suitable for debugging.
         """
-        return 'WBEMServerMock(object_manager_name={!r}, interop_ns={!r}, ' \
-            'system_name={!r}, dmtf_schema_ver={!r}, schema_dir={!r}, ' \
-            'wbem_server={!r}, registered_profiles={!r})' \
-            .format(self.server_mock_data['object_manager']['Name'],
-                    self.interop_ns,
-                    self.server_mock_data['system_name'],
-                    self.server_mock_data['dmtf_schema']['version'],
-                    self.server_mock_data['dmtf_schema']['dir'],
-                    getattr(self, 'wbem_server', None),
-                    self.server_mock_data['registered_profiles'])
+        # pylint: disable=line-too-long
+        return f"WBEMServerMock(object_manager_name={self.server_mock_data['object_manager']['Name']!r}, " \
+               f" \"interop_ns={self.interop_ns!r}, " \
+               f"system_name={self.server_mock_data['system_name']!r}, " \
+               f"dmtf_schema_ver={self.server_mock_data['dmtf_schema']['version']!r}, " \
+               f"schema_dir={self.server_mock_data['dmtf_schema']['dir']!r}, " \
+               f"wbem_server={getattr(self, 'wbem_server', None)!r}, " \
+               f"registered_profiles={self.server_mock_data['registered_profiles']!r})"  # noqa=E501
+        # pylint: enable=line-too-long
 
     def display(self, txt):
         """Display the txt and current repository. Diagnostic only"""
diff --git a/tests/unit/pywbemlistener/cli_test_extensions.py b/tests/unit/pywbemlistener/cli_test_extensions.py
index 73e80042..9944e71c 100644
--- a/tests/unit/pywbemlistener/cli_test_extensions.py
+++ b/tests/unit/pywbemlistener/cli_test_extensions.py
@@ -207,8 +207,7 @@ def start_listeners(input_listeners, verbose, situation):
     for lis_args in input_listeners:
         assert isinstance(lis_args, Sequence)
         verbose_opts = '-vv' if verbose else ''
-        cmd_args = 'pywbemlistener {} start {}'. \
-            format(verbose_opts, ' '.join(lis_args))
+        cmd_args = f"pywbemlistener {verbose_opts} start {' '.join(lis_args)}"
         if verbose:
             print(f"{situation}: Starting listener: {cmd_args}")
         check_output(cmd_args, situation, "Starting listener failed", verbose)
diff --git a/tests/unit/pywbemlistener/indicall_display.py b/tests/unit/pywbemlistener/indicall_display.py
index 0cfd2358..13e641c0 100644
--- a/tests/unit/pywbemlistener/indicall_display.py
+++ b/tests/unit/pywbemlistener/indicall_display.py
@@ -16,6 +16,6 @@ def display(indication, host):
       host (:term:`string`):
         Host name or IP address of WBEM server sending the indication.
     """
-    props = [f'{pn}={p.value!r}'
-             for pn, p in indication.properties.items()]
-    print("{}:{}:{}".format(host, indication.classname, ','.join(props)))
+    props = ','.join([f'{pn}={p.value!r}'
+                      for pn, p in indication.properties.items()])
+    print(f"{host}:{indication.classname}:{props}")
diff --git a/tests/unit/pywbemlistener/test_start_cmd.py b/tests/unit/pywbemlistener/test_start_cmd.py
index aa253ee5..1c026d13 100644
--- a/tests/unit/pywbemlistener/test_start_cmd.py
+++ b/tests/unit/pywbemlistener/test_start_cmd.py
@@ -436,7 +436,7 @@
                     r"Opening 'run' output log file at .+",
 
                     r"Added indication handler for appending to file new\.log "
-                    r"with format .{df}.".format(df=DEFAULT_INDI_FORMAT),
+                    fr"with format .{DEFAULT_INDI_FORMAT}.",
 
                     r"Running listener lis1 at http://localhost:50001",
                     r"Shut down listener lis1 running at "
@@ -463,7 +463,7 @@
                 r"'50001', '--scheme', 'http', "
                 r"'--start-pid', '[0-9]+', "
                 r"'--bind-addr', u?'localhost', "
-                r"'--indi-format', u?'{df}'\]".format(df=DEFAULT_INDI_FORMAT),
+                fr"'--indi-format', u?'{DEFAULT_INDI_FORMAT}'\]",
                 r"Start process( [0-9]+)?: Waiting for run process [0-9]+ to "
                 r"complete startup",
                 r"Start process( [0-9]+)?: Handling success signal .+ from "
diff --git a/tests/unit/utils.py b/tests/unit/utils.py
index b1df190e..fe39e085 100644
--- a/tests/unit/utils.py
+++ b/tests/unit/utils.py
@@ -33,6 +33,8 @@
 # Click version as a tuple
 CLICK_VERSION = packaging.version.parse(click.__version__).release
 
+EOL = '\n'  # Replace "\n" f-strings. "\" not fails in {} with python lt 3.12
+
 
 def execute_command(cmdname, args, env=None, stdin=None, verbose=False,
                     capture=True):
@@ -182,9 +184,8 @@ def execute_command(cmdname, args, env=None, stdin=None, verbose=False,
         except TimeoutExpired:
             proc.kill()
             rc = 255
-            print("Error: Timeout ({} sec) when waiting for command to "
-                  "complete; Killed process and setting rc={}".
-                  format(cmd_timeout, rc))
+            print(f"Error: Timeout ({cmd_timeout} sec) when waiting for "
+                  f"command to complete; Killed process and setting {rc=}")
             sys.stdout.flush()
 
         with open(out_log, 'rb') as fp:
@@ -213,10 +214,10 @@ def execute_command(cmdname, args, env=None, stdin=None, verbose=False,
                 stdout_str, stderr_str = proc.communicate(timeout=10)
             except TimeoutExpired:
                 stdout_str = stderr_str = None
-            print("Error: Timeout ({} sec) when waiting for command to "
-                  "complete; Killed process and setting rc={}; Stdout "
-                  "produced so far: {!r}; Stderr produced so far: {!r}".
-                  format(cmd_timeout, rc, stdout_str, stderr_str))
+            print(f"Error: Timeout ({cmd_timeout} sec) when waiting for "
+                  f"command to complete; Killed process and setting {rc=};"
+                  f" Stdout produced so far: {stdout_str!r}; Stderr produced "
+                  f"so far: {stderr_str!r}")
             sys.stdout.flush()
 
     # Restore environment of current process
@@ -281,18 +282,17 @@ def assert_rc(exp_rc, rc, stdout, stderr, desc):
 
     assert exp_rc == rc, \
         "Unexpected exit code in test:\n" \
-        "{}\n" \
-        "Expected rc: {}\n" \
-        "Actual rc: {}\n" \
+        f"{desc}\n" \
+        f"Expected rc: {exp_rc}\n" \
+        f"Actual rc: {rc}\n" \
         "Stdout:\n" \
         "------------\n" \
-        "{}\n" \
+        f"{stdout}\n" \
         "------------\n" \
         "Stderr:\n" \
         "------------\n" \
-        "{}\n" \
-        "------------\n". \
-        format(desc, exp_rc, rc, stdout, stderr)
+        f"{stderr}\n" \
+        "------------\n"
 
 
 def assert_patterns(exp_patterns, act_lines, source, desc):
@@ -315,33 +315,30 @@ def assert_patterns(exp_patterns, act_lines, source, desc):
       desc (string): Testcase description.
     """
     assert len(act_lines) == len(exp_patterns), \
-        "Unexpected number of lines on {} in test:\n" \
-        "{}\n" \
-        "Expected patterns (cnt={}):\n" \
+        f"Unexpected number of lines on {source} in test:\n" \
+        f"{desc}\n" \
+        f"Expected patterns (cnt={len(exp_patterns)}):\n" \
         "------------\n" \
-        "{}\n" \
+        f"{EOL.join(exp_patterns)}\n" \
         "------------\n" \
-        "Actual lines (cnt={}):\n" \
+        f"Actual lines (cnt={len(act_lines)}):\n" \
         "------------\n" \
-        "{}\n" \
-        "------------\n". \
-        format(source, desc, len(exp_patterns), '\n'.join(exp_patterns),
-               len(act_lines), '\n'.join(act_lines))
+        f"{EOL.join(act_lines)}\n" \
+        "------------\n"
 
     for i, act_line in enumerate(act_lines):
         exp_pattern = exp_patterns[i]
         assert re.search(exp_pattern, act_line), \
-            "Unexpected line #{} on {} in test:\n" \
-            "{}\n" \
+            f"Unexpected line #{i} on {source} in test:\n" \
+            f"{desc}\n" \
             "Expected pattern:\n" \
             "------------\n" \
-            "{}\n" \
+            f"{exp_pattern}\n" \
             "------------\n" \
             "Actual line:\n" \
             "------------\n" \
-            "{}\n" \
-            "------------\n". \
-            format(i, source, desc, exp_pattern, act_line)
+            f"{act_line}\n" \
+            "------------\n"
 
 
 def assert_patterns_in_lines(exp_patterns, act_lines, source, desc):
@@ -379,22 +376,20 @@ def assert_patterns_in_lines(exp_patterns, act_lines, source, desc):
                 act_line = next(act_lines_iter)
     except StopIteration:
         raise AssertionError(
-            "Pattern #{} not found in order on {} in test:\n"
-            "{}\n"
+            f"Pattern #{i} not found in order on {source} in test:\n"
+            f"{desc}\n"
             "Expected pattern:\n"
             "------------\n"
-            "{!r}\n"
+            f"{exp_pattern!r}\n"
             "------------\n"
             "Start line for search:\n"
             "------------\n"
-            "{!r}\n"
+            f"{start_line!r}\n"
             "------------\n"
             "Actual lines:\n"
             "------------\n"
-            "{}\n"
-            "------------\n".
-            format(i, source, desc, exp_pattern, start_line,
-                   '\n'.join(act_lines)))
+            f"{EOL.join(act_lines)}\n"
+            "------------\n")
 
 
 def assert_lines(exp_lines, act_lines, source, desc):
@@ -418,33 +413,30 @@ def assert_lines(exp_lines, act_lines, source, desc):
       desc (string): Testcase description.
     """
     assert len(act_lines) == len(exp_lines), \
-        "Unexpected number of lines on {} in test:\n" \
-        "{}\n" \
-        "Expected lines cnt={}:\n" \
+        f"Unexpected number of lines on {source} in test:\n" \
+        f"{desc}\n" \
+        f"Expected lines cnt={len(exp_lines)}:\n" \
         "------------\n" \
-        "{}\n" \
+        f"{EOL.join(exp_lines)}\n" \
         "------------\n" \
-        "Actual lines cnt={}:\n" \
+        f"Actual lines cnt={len(act_lines)}:\n" \
         "------------\n" \
-        "{}\n" \
-        "------------\n". \
-        format(source, desc, len(exp_lines), '\n'.join(exp_lines),
-               len(act_lines), '\n'.join(act_lines))
+        f"{EOL.join(act_lines)}\n" \
+        "------------\n"
 
     for i, act_line in enumerate(act_lines):
         exp_line = exp_lines[i]
         assert exp_line == act_line, \
-            "Unexpected line #{} on {} in test:\n" \
-            "{}\n" \
+            f"Unexpected line #{i} on {source} in test:\n" \
+            f"{desc}\n" \
             "Expected line:\n" \
             "------------\n" \
-            "{}\n" \
+            f"{exp_line}\n" \
             "------------\n" \
             "Actual line:\n" \
             "------------\n" \
-            "{}\n" \
-            "------------\n". \
-            format(i, source, desc, exp_line, act_line)
+            f"{act_line}\n" \
+            "------------\n"
 
 
 class captured_output: