From 5088b0154d8cc4570b9f9c4fca39e489ef12dee1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 27 Apr 2024 16:06:51 +1000 Subject: [PATCH] Cleanup: replace %-formatting with str.format in scripts/modules/ The "bl_i18n_utils" module has been excluded I'm not sure how best to run it with reasonable code coverage. --- scripts/modules/addon_utils.py | 49 +++--- scripts/modules/animsys_refactor.py | 25 ++- scripts/modules/bl_app_template_utils.py | 18 ++- .../autocomplete/complete_calltip.py | 8 +- .../autocomplete/complete_namespace.py | 4 +- scripts/modules/bl_keymap_utils/io.py | 2 +- .../bl_previews_utils/bl_previews_render.py | 14 +- scripts/modules/bl_rna_utils/data_path.py | 8 +- .../modules/bl_text_utils/external_editor.py | 4 +- scripts/modules/bl_ui_utils/bug_report_url.py | 14 +- scripts/modules/blend_render_info.py | 10 +- scripts/modules/bpy/ops.py | 9 +- scripts/modules/bpy/path.py | 2 +- scripts/modules/bpy/utils/__init__.py | 48 +++--- scripts/modules/bpy/utils/previews.py | 8 +- scripts/modules/bpy_extras/image_utils.py | 6 +- scripts/modules/bpy_extras/io_utils.py | 12 +- scripts/modules/bpy_extras/object_utils.py | 2 +- .../bpy_extras/wm_utils/progress_report.py | 10 +- scripts/modules/bpy_types.py | 14 +- scripts/modules/console_python.py | 4 +- scripts/modules/graphviz_export.py | 30 ++-- scripts/modules/keyingsets_utils.py | 4 +- scripts/modules/nodeitems_utils.py | 4 +- scripts/modules/rna_info.py | 84 +++++----- scripts/modules/rna_keymap_ui.py | 7 +- scripts/modules/rna_manual_reference.py | 5 +- scripts/modules/rna_prop_ui.py | 4 +- scripts/modules/rna_xml.py | 62 ++++---- scripts/modules/sys_info.py | 149 ++++++++++-------- 30 files changed, 343 insertions(+), 277 deletions(-) diff --git a/scripts/modules/addon_utils.py b/scripts/modules/addon_utils.py index 1d43dcc0b3c..90cb2d502a4 100644 --- a/scripts/modules/addon_utils.py +++ b/scripts/modules/addon_utils.py @@ -72,7 +72,7 @@ def _paths_with_extension_repos(): dirpath = repo.directory if not os.path.isdir(dirpath): continue - addon_paths.append((dirpath, "%s.%s" % (_ext_base_pkg_idname, repo.module))) + addon_paths.append((dirpath, "{:s}.{:s}".format(_ext_base_pkg_idname, repo.module))) return addon_paths @@ -187,8 +187,8 @@ def modules_refresh(*, module_cache=addons_fake_modules): if mod.__file__ != mod_path: print( "multiple addons with the same name:\n" - " %r\n" - " %r" % (mod.__file__, mod_path) + " {!r}\n" + " {!r}".format(mod.__file__, mod_path) ) error_duplicates.append((mod.bl_info["name"], mod.__file__, mod_path)) @@ -394,7 +394,7 @@ def enable(module_name, *, default_set=False, persistent=False, handle_error=Non # Include a message otherwise the "cause:" for failing to load the module is left blank. # Include the `__path__` when available so there is a reference to the location that failed to load. raise ImportError( - "module loaded with no associated file, __path__=%r, aborting!" % ( + "module loaded with no associated file, __path__={!r}, aborting!".format( getattr(mod, "__path__", None) ), name=module_name @@ -407,7 +407,7 @@ def enable(module_name, *, default_set=False, persistent=False, handle_error=Non # Account for `ImportError` & `ModuleNotFoundError`. if isinstance(ex, ImportError): if ex.name == module_name: - ex.msg = "Add-on not loaded: \"%s\", cause: %s" % (module_name, str(ex)) + ex.msg = "Add-on not loaded: \"{:s}\", cause: {:s}".format(module_name, str(ex)) # Issue with an add-on from an extension repository, report a useful message. elif is_extension and module_name.startswith(ex.name + "."): @@ -418,17 +418,19 @@ def enable(module_name, *, default_set=False, persistent=False, handle_error=Non ) if repo is None: ex.msg = ( - "Add-on not loaded: \"%s\", cause: extension repository \"%s\" doesn't exist" % - (module_name, repo_id) + "Add-on not loaded: \"{:s}\", cause: extension repository \"{:s}\" doesn't exist".format( + module_name, repo_id, + ) ) elif not repo.enabled: ex.msg = ( - "Add-on not loaded: \"%s\", cause: extension repository \"%s\" is disabled" % - (module_name, repo_id) + "Add-on not loaded: \"{:s}\", cause: extension repository \"{:s}\" is disabled".format( + module_name, repo_id, + ) ) else: # The repository exists and is enabled, it should have imported. - ex.msg = "Add-on not loaded: \"%s\", cause: %s" % (module_name, str(ex)) + ex.msg = "Add-on not loaded: \"{:s}\", cause: {:s}".format(module_name, str(ex)) handle_error(ex) @@ -448,8 +450,9 @@ def enable(module_name, *, default_set=False, persistent=False, handle_error=Non # Once `bl_info` is fully deprecated this should be changed to always print a warning. if _bpy.app.debug_python: print( - "Add-on \"%s\" has a \"bl_info\" which will be ignored in favor of \"%s\"" % - (module_name, _ext_manifest_filename_toml) + "Add-on \"{:s}\" has a \"bl_info\" which will be ignored in favor of \"{:s}\"".format( + module_name, _ext_manifest_filename_toml, + ) ) # Always remove as this is not expected to exist and will be lazily initialized. del mod.bl_info @@ -520,9 +523,10 @@ def disable(module_name, *, default_set=False, handle_error=None): handle_error(ex) else: print( - "addon_utils.disable: %s not %s" % ( + "addon_utils.disable: {:s} not {:s}".format( module_name, - "loaded" if mod is None else "enabled") + "loaded" if mod is None else "enabled", + ) ) # could be in more than once, unlikely but better do this just in case. @@ -593,7 +597,10 @@ def disable_all(): def _blender_manual_url_prefix(): - return "https://docs.blender.org/manual/%s/%d.%d" % (_bpy.utils.manual_language_code(), *_bpy.app.version[:2]) + return "https://docs.blender.org/manual/{:s}/{:d}.{:d}".format( + _bpy.utils.manual_language_code(), + *_bpy.app.version[:2], + ) def _bl_info_basis(): @@ -868,7 +875,7 @@ def _initialize_extension_repos_post_addons_prepare( repo_runtime = addon_runtime_info.get(module_id, {}) for submodule_id, addon in repo_userdef.items(): - module_name_next = "%s.%s.%s" % (_ext_base_pkg_idname, module_id, submodule_id) + module_name_next = "{:s}.{:s}.{:s}".format(_ext_base_pkg_idname, module_id, submodule_id) # Only default & persistent add-ons are kept for re-activation. default_set = True persistent = True @@ -880,8 +887,8 @@ def _initialize_extension_repos_post_addons_prepare( for submodule_id, mod in repo_runtime.items(): if not getattr(mod, "__addon_enabled__", False): continue - module_name_prev = "%s.%s.%s" % (_ext_base_pkg_idname, module_id_prev, submodule_id) - module_name_next = "%s.%s.%s" % (_ext_base_pkg_idname, module_id_next, submodule_id) + module_name_prev = "{:s}.{:s}.{:s}".format(_ext_base_pkg_idname, module_id_prev, submodule_id) + module_name_next = "{:s}.{:s}.{:s}".format(_ext_base_pkg_idname, module_id_next, submodule_id) disable(module_name_prev, default_set=False) addon = repo_userdef.get(submodule_id) default_set = addon is not None @@ -897,7 +904,7 @@ def _initialize_extension_repos_post_addons_prepare( continue # Either there is no run-time data or the module wasn't enabled. # Rename the add-on without enabling it so the next time it's enabled it's preferences are kept. - module_name_next = "%s.%s.%s" % (_ext_base_pkg_idname, module_id_next, submodule_id) + module_name_next = "{:s}.{:s}.{:s}".format(_ext_base_pkg_idname, module_id_next, submodule_id) addon.module = module_name_next if submodules_del: @@ -914,7 +921,7 @@ def _initialize_extension_repos_post_addons_prepare( default_set = False for submodule_id, mod in repo_runtime.items(): - module_name_prev = "%s.%s.%s" % (_ext_base_pkg_idname, module_id, submodule_id) + module_name_prev = "{:s}.{:s}.{:s}".format(_ext_base_pkg_idname, module_id, submodule_id) disable(module_name_prev, default_set=default_set) del repo del repo_module_map @@ -923,7 +930,7 @@ def _initialize_extension_repos_post_addons_prepare( for module_id_prev in submodules_del_disabled: repo_userdef = addon_userdef_info.get(module_id_prev, {}) for submodule_id in repo_userdef.keys(): - module_name_prev = "%s.%s.%s" % (_ext_base_pkg_idname, module_id_prev, submodule_id) + module_name_prev = "{:s}.{:s}.{:s}".format(_ext_base_pkg_idname, module_id_prev, submodule_id) disable(module_name_prev, default_set=True) return addons_to_enable diff --git a/scripts/modules/animsys_refactor.py b/scripts/modules/animsys_refactor.py index 34723ab1716..e7ef63640a1 100644 --- a/scripts/modules/animsys_refactor.py +++ b/scripts/modules/animsys_refactor.py @@ -37,16 +37,16 @@ class DataPathBuilder: self.data_path = attrs def __getattr__(self, attr): - str_value = ".%s" % attr + str_value = ".{:s}".format(attr) return DataPathBuilder(self.data_path + (str_value, )) def __getitem__(self, key): if type(key) is int: - str_value = '[%d]' % key + str_value = '[{:d}]'.format(key) elif type(key) is str: - str_value = '["%s"]' % bpy.utils.escape_identifier(key) + str_value = '["{:s}"]'.format(bpy.utils.escape_identifier(key)) else: - raise Exception("unsupported accessor %r of type %r (internal error)" % (key, type(key))) + raise Exception("unsupported accessor {!r} of type {!r} (internal error)".format(key, type(key))) return DataPathBuilder(self.data_path + (str_value, )) def resolve(self, real_base, rna_update_from_map, fcurve, log): @@ -171,7 +171,10 @@ def update_data_paths(rna_update, log=sys.stdout): if not IS_TESTING: fcurve.data_path = data_path_new fcurve.driver.is_valid = True # reset to allow this to work again - print("driver-fcurve (%s): %s -> %s" % (id_data.name, data_path, data_path_new), file=log) + print( + "driver-fcurve ({:s}): {:s} -> {:s}".format(id_data.name, data_path, data_path_new), + file=log, + ) for var in fcurve.driver.variables: if var.type == 'SINGLE_PROP': @@ -185,8 +188,14 @@ def update_data_paths(rna_update, log=sys.stdout): if data_path_new != data_path: if not IS_TESTING: tar.data_path = data_path_new - print("driver (%s): %s -> %s" % (id_data_other.name, data_path, data_path_new), - file=log) + print( + "driver ({:s}): {:s} -> {:s}".format( + id_data_other.name, + data_path, + data_path_new, + ), + file=log, + ) for action in anim_data_actions(anim_data): for fcu in action.fcurves: @@ -196,7 +205,7 @@ def update_data_paths(rna_update, log=sys.stdout): if data_path_new != data_path: if not IS_TESTING: fcu.data_path = data_path_new - print("fcurve (%s): %s -> %s" % (id_data.name, data_path, data_path_new), file=log) + print("fcurve ({:s}): {:s} -> {:s}".format(id_data.name, data_path, data_path_new), file=log) if __name__ == "__main__": diff --git a/scripts/modules/bl_app_template_utils.py b/scripts/modules/bl_app_template_utils.py index a770c391602..f4bbf66f057 100644 --- a/scripts/modules/bl_app_template_utils.py +++ b/scripts/modules/bl_app_template_utils.py @@ -65,8 +65,7 @@ def _enable(template_id, *, handle_error=None, ignore_not_found=False): try: mod.register() except BaseException as ex: - print("Exception in module register(): %r" % - getattr(mod, "__file__", template_id)) + print("Exception in module register(): {!r}".format(getattr(mod, "__file__", template_id))) handle_error(ex) del _modules[template_id] return None @@ -107,12 +106,15 @@ def _disable(template_id, *, handle_error=None): try: mod.unregister() except BaseException as ex: - print("Exception in module unregister(): %r" % - getattr(mod, "__file__", template_id)) + print("Exception in module unregister(): {!r}".format(getattr(mod, "__file__", template_id))) handle_error(ex) else: - print("\tapp_template_utils.disable: %s not %s." % - (template_id, "disabled" if mod is False else "loaded")) + print( + "\tapp_template_utils.disable: {:s} not {:s}.".format( + template_id, + "disabled" if mod is False else "loaded", + ) + ) if _bpy.app.debug_python: print("\tapp_template_utils.disable", template_id) @@ -139,7 +141,7 @@ def import_from_id(template_id, *, ignore_not_found=False): if ignore_not_found: return None else: - raise Exception("%r template not found!" % template_id) + raise Exception("{!r} template not found!".format(template_id)) else: if ignore_not_found: if not os.path.exists(os.path.join(path, "__init__.py")): @@ -170,6 +172,6 @@ def reset(*, reload_scripts=False): """ template_id = _bpy.context.preferences.app_template if _bpy.app.debug_python: - print("bl_app_template_utils.reset('%s')" % template_id) + print("bl_app_template_utils.reset('{:s}')".format(template_id)) activate(template_id=template_id, reload_scripts=reload_scripts) diff --git a/scripts/modules/bl_console_utils/autocomplete/complete_calltip.py b/scripts/modules/bl_console_utils/autocomplete/complete_calltip.py index 380a1775d50..93e7b9a7b9f 100644 --- a/scripts/modules/bl_console_utils/autocomplete/complete_calltip.py +++ b/scripts/modules/bl_console_utils/autocomplete/complete_calltip.py @@ -9,8 +9,8 @@ import re # regular expression constants -DEF_DOC = r'%s\s*(\(.*?\))' -DEF_SOURCE = r'def\s+%s\s*(\(.*?\)):' +DEF_DOC = r'{:s}\s*(\(.*?\))' +DEF_SOURCE = r'def\s+{:s}\s*(\(.*?\)):' RE_EMPTY_LINE = re.compile(r'^\s*\n') RE_FLAG = re.MULTILINE | re.DOTALL RE_NEWLINE = re.compile('\n+') @@ -103,7 +103,7 @@ def get_argspec(func, *, strip_self=True, doc=None, source=None): # From doc-string. if doc is None: doc = get_doc(func) - match = re.search(DEF_DOC % func_name, doc, RE_FLAG) + match = re.search(DEF_DOC.format(func_name), doc, RE_FLAG) # from source code if not match: if source is None: @@ -112,7 +112,7 @@ def get_argspec(func, *, strip_self=True, doc=None, source=None): except (TypeError, IOError): source = '' if source: - match = re.search(DEF_SOURCE % func_name, source, RE_FLAG) + match = re.search(DEF_SOURCE.format(func_name), source, RE_FLAG) if match: argspec = reduce_spaces(match.group(1)) else: diff --git a/scripts/modules/bl_console_utils/autocomplete/complete_namespace.py b/scripts/modules/bl_console_utils/autocomplete/complete_namespace.py index cde40f5e9b1..faecb5ca0a2 100644 --- a/scripts/modules/bl_console_utils/autocomplete/complete_namespace.py +++ b/scripts/modules/bl_console_utils/autocomplete/complete_namespace.py @@ -92,10 +92,10 @@ def complete_indices(word, namespace, *, obj=None, base=None): if obj_is_dict: # dictionary type - matches = ['%s[%r]' % (base, key) for key in sorted(obj.keys())] + matches = ['{:s}[{!r}]'.format(base, key) for key in sorted(obj.keys())] else: # list type - matches = ['%s[%d]' % (base, idx) for idx in range(obj_len)] + matches = ['{:s}[{:d}]'.format(base, idx) for idx in range(obj_len)] if word != base: matches = [match for match in matches if match.startswith(word)] return matches diff --git a/scripts/modules/bl_keymap_utils/io.py b/scripts/modules/bl_keymap_utils/io.py index f6bce2c010d..5abd1fc7995 100644 --- a/scripts/modules/bl_keymap_utils/io.py +++ b/scripts/modules/bl_keymap_utils/io.py @@ -34,7 +34,7 @@ def repr_f32(f): f_test = round(f, i) f_test_round = round_float_32(f_test) if f_test_round == f_round: - return "%.*f" % (i, f_test) + return "{:.{:d}f}".format(f_test, i) return f_str diff --git a/scripts/modules/bl_previews_utils/bl_previews_render.py b/scripts/modules/bl_previews_utils/bl_previews_render.py index a915bb8bf99..99bbabbe498 100644 --- a/scripts/modules/bl_previews_utils/bl_previews_render.py +++ b/scripts/modules/bl_previews_utils/bl_previews_render.py @@ -421,7 +421,7 @@ def do_previews(do_objects, do_collections, do_scenes, do_data_intern): bpy.context.window.scene = bpy.data.scenes[prev_scenename, None] if do_save: - print("Saving %s..." % bpy.data.filepath) + print("Saving {:s}...".format(bpy.data.filepath)) try: bpy.ops.wm.save_mainfile() except BaseException as ex: @@ -429,7 +429,11 @@ def do_previews(do_objects, do_collections, do_scenes, do_data_intern): # references an nonexistent texture. Better not break in this case, just spit error to console. print("ERROR:", ex) else: - print("*NOT* Saving %s, because some error(s) happened while deleting temp render data..." % bpy.data.filepath) + print( + "*NOT* Saving {:s}, because some error(s) happened while deleting temp render data...".format( + bpy.data.filepath, + ) + ) def do_clear_previews(do_objects, do_collections, do_scenes, do_data_intern): @@ -448,7 +452,7 @@ def do_clear_previews(do_objects, do_collections, do_scenes, do_data_intern): for scene in ids_nolib_with_preview(bpy.data.scenes): scene.preview.image_size = (0, 0) - print("Saving %s..." % bpy.data.filepath) + print("Saving {:s}...".format(bpy.data.filepath)) bpy.ops.wm.save_mainfile() @@ -526,7 +530,7 @@ def main(): if __name__ == "__main__": - print("\n\n *** Running %s *** \n" % __file__) - print(" *** Blend file %s *** \n" % bpy.data.filepath) + print("\n\n *** Running {:s} *** \n".format(__file__)) + print(" *** Blend file {:s} *** \n".format(bpy.data.filepath)) main() bpy.ops.wm.quit_blender() diff --git a/scripts/modules/bl_rna_utils/data_path.py b/scripts/modules/bl_rna_utils/data_path.py index d73c111bdc6..ea135032e09 100644 --- a/scripts/modules/bl_rna_utils/data_path.py +++ b/scripts/modules/bl_rna_utils/data_path.py @@ -22,18 +22,18 @@ class _TokenizeDataPath: self.data_path = attrs def __getattr__(self, attr): - return _TokenizeDataPath(self.data_path + ((".%s" % attr),)) + return _TokenizeDataPath(self.data_path + ((".{:s}".format(attr)),)) def __getitem__(self, key): - return _TokenizeDataPath(self.data_path + (("[%r]" % (key,)),)) + return _TokenizeDataPath(self.data_path + (("[{!r}]".format(key)),)) def __call__(self, *args, **kw): value_str = ", ".join([ val for val in ( ", ".join(repr(value) for value in args), - ", ".join(["%s=%r" % (key, value) for key, value in kw.items()]), + ", ".join(["{:s}={!r}".format(key, value) for key, value in kw.items()]), ) if val]) - return _TokenizeDataPath(self.data_path + ('(%s)' % value_str, )) + return _TokenizeDataPath(self.data_path + ('({:s})'.format(value_str), )) def __iter__(self): return iter(self.data_path) diff --git a/scripts/modules/bl_text_utils/external_editor.py b/scripts/modules/bl_text_utils/external_editor.py index 4c0157a812e..5f0f40ea22d 100644 --- a/scripts/modules/bl_text_utils/external_editor.py +++ b/scripts/modules/bl_text_utils/external_editor.py @@ -43,12 +43,12 @@ def open_external_editor(filepath, line, column, /): try: args.extend([Template(arg).substitute(**template_vars) for arg in shlex.split(text_editor_args)]) except BaseException as ex: - return rpt_("Exception parsing template: %r") % ex + return rpt_("Exception parsing template: {!r}").format(ex) try: # With `check=True` if `process.returncode != 0` an exception will be raised. subprocess.run(args, check=True) except BaseException as ex: - return rpt_("Exception running external editor: %r") % ex + return rpt_("Exception running external editor: {!r}").format(ex) return "" diff --git a/scripts/modules/bl_ui_utils/bug_report_url.py b/scripts/modules/bl_ui_utils/bug_report_url.py index fbfab780fd4..3efd03be2f0 100644 --- a/scripts/modules/bl_ui_utils/bug_report_url.py +++ b/scripts/modules/bl_ui_utils/bug_report_url.py @@ -15,7 +15,7 @@ def url_prefill_from_blender(*, addon_info=None): fh.write("**System Information**\n") fh.write( - "Operating system: %s %d Bits" % ( + "Operating system: {:s} {:d} Bits".format( platform.platform(), struct.calcsize("P") * 8, ) @@ -25,13 +25,13 @@ def url_prefill_from_blender(*, addon_info=None): from _bpy import _ghost_backend ghost_backend = _ghost_backend() if ghost_backend not in {'NONE', 'DEFAULT'}: - fh.write(", %s UI" % ghost_backend) + fh.write(", {:s} UI".format(ghost_backend)) del _ghost_backend, ghost_backend fh.write("\n") fh.write( - "Graphics card: %s %s %s\n" % ( + "Graphics card: {:s} {:s} {:s}\n".format( gpu.platform.renderer_get(), gpu.platform.vendor_get(), gpu.platform.version_get(), @@ -42,7 +42,7 @@ def url_prefill_from_blender(*, addon_info=None): "**Blender Version**\n" ) fh.write( - "Broken: version: %s, branch: %s, commit date: %s %s, hash: `%s`\n" % ( + "Broken: version: {:s}, branch: {:s}, commit date: {:s} {:s}, hash: `{:s}`\n".format( bpy.app.version_string, bpy.app.build_branch.decode('utf-8', 'replace'), bpy.app.build_commit_date.decode('utf-8', 'replace'), @@ -73,6 +73,8 @@ def url_prefill_from_blender(*, addon_info=None): form_number = 2 if addon_info else 1 return ( - "https://developer.blender.org/maniphest/task/edit/form/%i?description=" % form_number + - urllib.parse.quote(fh.getvalue()) + "https://developer.blender.org/maniphest/task/edit/form/{:d}?description={:s}".format( + form_number, + urllib.parse.quote(fh.getvalue()), + ) ) diff --git a/scripts/modules/blend_render_info.py b/scripts/modules/blend_render_info.py index 818a60995fd..506caf4cfde 100755 --- a/scripts/modules/blend_render_info.py +++ b/scripts/modules/blend_render_info.py @@ -72,7 +72,7 @@ def _read_blend_rend_chunk_from_file(blendfile, filepath): head = blendfile.read(7) if head != b'BLENDER': - sys.stderr.write("Not a blend file: %s\n" % filepath) + sys.stderr.write("Not a blend file: {:s}\n".format(filepath)) return [] is_64_bit = (blendfile.read(1) == b'-') @@ -91,13 +91,13 @@ def _read_blend_rend_chunk_from_file(blendfile, filepath): while (bhead_id := blendfile.read(4)) != b'ENDB': if len(bhead_id) != 4: - sys.stderr.write("Unable to read until ENDB block (corrupt file): %s\n" % filepath) + sys.stderr.write("Unable to read until ENDB block (corrupt file): {:s}\n".format(filepath)) break sizeof_data_left = struct.unpack('>i' if is_big_endian else '" % - (self._module, self._func, id(self))) + return ( + "".format( + self._module, self._func, id(self), + ) + ) # ----------------------------------------------------------------------------- diff --git a/scripts/modules/bpy/path.py b/scripts/modules/bpy/path.py index 00988305f81..5dc252b00e1 100644 --- a/scripts/modules/bpy/path.py +++ b/scripts/modules/bpy/path.py @@ -390,7 +390,7 @@ def module_names(path, *, recursive=False, package=""): if recursive: for mod_name, mod_path in module_names(directory, recursive=True): modules.append(( - "%s.%s" % (pacakge_prefix + filename, mod_name), + "{:s}.{:s}".format(pacakge_prefix + filename, mod_name), mod_path, )) diff --git a/scripts/modules/bpy/utils/__init__.py b/scripts/modules/bpy/utils/__init__.py index 183147b05c5..4a445b53ca4 100644 --- a/scripts/modules/bpy/utils/__init__.py +++ b/scripts/modules/bpy/utils/__init__.py @@ -123,8 +123,7 @@ def _test_import(module_name, loaded_modules): if module_name in loaded_modules: return None if "." in module_name: - print("Ignoring '%s', can't import files containing " - "multiple periods" % module_name) + print("Ignoring '{:s}', can't import files containing multiple periods".format(module_name)) return None if use_time: @@ -139,7 +138,7 @@ def _test_import(module_name, loaded_modules): return None if use_time: - print("time %s %.4f" % (module_name, time.time() - t)) + print("time {:s} {:.4f}".format(module_name, time.time() - t)) loaded_modules.add(mod.__name__) # should match mod.__name__ too return mod @@ -235,9 +234,10 @@ def load_scripts(*, reload_scripts=False, refresh_scripts=False, extensions=True import traceback traceback.print_exc() else: - print("\nWarning! %r has no register function, " - "this is now a requirement for registerable scripts" % - mod.__file__) + print( + "\nWarning! {!r} has no register function, " + "this is now a requirement for registerable scripts".format(mod.__file__) + ) def unregister_module_call(mod): unregister = getattr(mod, "unregister", None) @@ -324,20 +324,17 @@ def load_scripts(*, reload_scripts=False, refresh_scripts=False, extensions=True _bpy.context.window_manager.tag_script_reload() import gc - print("gc.collect() -> %d" % gc.collect()) + print("gc.collect() -> {:d}".format(gc.collect())) if use_time: - print("Python Script Load Time %.4f" % (time.time() - t_main)) + print("Python Script Load Time {:.4f}".format(time.time() - t_main)) if use_class_register_check: for cls in _bpy.types.bpy_struct.__subclasses__(): if getattr(cls, "is_registered", False): for subcls in cls.__subclasses__(): if not subcls.is_registered: - print( - "Warning, unregistered class: %s(%s)" % - (subcls.__name__, cls.__name__) - ) + print("Warning, unregistered class: {:s}({:s})".format(subcls.__name__, cls.__name__)) def load_scripts_extensions(*, reload_scripts=False): @@ -500,7 +497,7 @@ def preset_paths(subdir): for path in script_paths(subdir="presets", check_all=True): directory = _os.path.join(path, subdir) if not directory.startswith(path): - raise Exception("invalid subdir given %r" % subdir) + raise Exception("invalid subdir given {!r}".format(subdir)) elif _os.path.isdir(directory): dirs.append(directory) @@ -595,13 +592,14 @@ def smpte_from_frame(frame, *, fps=None, fps_base=None): frame = abs(frame) return ( - "%s%02d:%02d:%02d:%02d" % ( + "{:s}{:02d}:{:02d}:{:02d}:{:02d}".format( sign, int(frame / (3600 * fps)), # HH int((frame / (60 * fps)) % 60), # MM int((frame / fps) % 60), # SS int(frame % fps), # FF - )) + ) + ) def time_from_frame(frame, *, fps=None, fps_base=None): @@ -728,7 +726,7 @@ def keyconfig_set(filepath, *, report=None): # Get name, exception for default keymap to keep backwards compatibility. if kc_new is None: if report is not None: - report({'ERROR'}, "Failed to load keymap %r" % filepath) + report({'ERROR'}, "Failed to load keymap {!r}".format(filepath)) return False else: keyconfigs.active = kc_new @@ -764,7 +762,7 @@ def user_resource(resource_type, *, path="", create=False): traceback.print_exc() target_path = "" elif not _os.path.isdir(target_path): - print("Path %r found but isn't a directory!" % target_path) + print("Path {!r} found but isn't a directory!".format(target_path)) target_path = "" return target_path @@ -856,7 +854,7 @@ def register_tool(tool_cls, *, after=None, separator=False, group=False): cls = ToolSelectPanelHelper._tool_class_from_space_type(space_type) if cls is None: - raise Exception("Space type %r has no toolbar" % space_type) + raise Exception("Space type {!r} has no toolbar".format(space_type)) tools = cls._tools[context_mode] # First sanity check @@ -866,9 +864,9 @@ def register_tool(tool_cls, *, after=None, separator=False, group=False): if item is not None } if not issubclass(tool_cls, WorkSpaceTool): - raise Exception("Expected WorkSpaceTool subclass, not %r" % type(tool_cls)) + raise Exception("Expected WorkSpaceTool subclass, not {!r}".format(type(tool_cls))) if tool_cls.bl_idname in tools_id: - raise Exception("Tool %r already exists!" % tool_cls.bl_idname) + raise Exception("Tool {!r} already exists!".format(tool_cls.bl_idname)) del tools_id, WorkSpaceTool # Convert the class into a ToolDef. @@ -968,7 +966,7 @@ def unregister_tool(tool_cls): from bl_ui.space_toolsystem_common import ToolSelectPanelHelper cls = ToolSelectPanelHelper._tool_class_from_space_type(space_type) if cls is None: - raise Exception("Space type %r has no toolbar" % space_type) + raise Exception("Space type {!r} has no toolbar".format(space_type)) tools = cls._tools[context_mode] tool_def = tool_cls._bl_tool @@ -1020,7 +1018,7 @@ def unregister_tool(tool_cls): break if not changed: - raise Exception("Unable to remove %r" % tool_cls) + raise Exception("Unable to remove {!r}".format(tool_cls)) del tool_cls._bl_tool keymap_data = tool_def.keymap @@ -1033,7 +1031,7 @@ def unregister_tool(tool_cls): continue km = kc.keymaps.get(keymap_data[0]) if km is None: - print("Warning keymap %r not found in %r!" % (keymap_data[0], kc.name)) + print("Warning keymap {!r} not found in {!r}!".format(keymap_data[0], kc.name)) else: kc.keymaps.remove(km) @@ -1069,7 +1067,7 @@ def manual_map(): try: prefix, url_manual_mapping = cb() except: - print("Error calling %r" % cb) + print("Error calling {!r}".format(cb)) import traceback traceback.print_exc() continue @@ -1145,7 +1143,7 @@ def make_rna_paths(struct_name, prop_name, enum_name): if prop_name: src = src_rna = ".".join((struct_name, prop_name)) if enum_name: - src = src_enum = "%s:'%s'" % (src_rna, enum_name) + src = src_enum = "{:s}:'{:s}'".format(src_rna, enum_name) else: src = src_rna = struct_name return src, src_rna, src_enum diff --git a/scripts/modules/bpy/utils/previews.py b/scripts/modules/bpy/utils/previews.py index 1567223e6e8..7bc918483f1 100644 --- a/scripts/modules/bpy/utils/previews.py +++ b/scripts/modules/bpy/utils/previews.py @@ -61,7 +61,7 @@ class ImagePreviewCollection(dict): return raise ResourceWarning( - "%r: left open, remove with 'bpy.utils.previews.remove()'" % self + "{!r}: left open, remove with 'bpy.utils.previews.remove()'".format(self) ) self.close() @@ -70,7 +70,7 @@ class ImagePreviewCollection(dict): def new(self, name): if name in self: - raise KeyError("key %r already exists" % name) + raise KeyError("key {!r} already exists".format(name)) p = self[name] = _utils_previews.new( self._gen_key(name)) return p @@ -78,7 +78,7 @@ class ImagePreviewCollection(dict): def load(self, name, path, path_type, force_reload=False): if name in self: - raise KeyError("key %r already exists" % name) + raise KeyError("key {!r} already exists".format(name)) p = self[name] = _utils_previews.load( self._gen_key(name), path, path_type, force_reload) return p @@ -100,7 +100,7 @@ class ImagePreviewCollection(dict): super().__delitem__(key) def __repr__(self): - return "<%s id=%s[%d], %r>" % ( + return "<{:s} id={:s}[{:d}], {!r}>".format( self.__class__.__name__, self._uuid, len(self), super() ) diff --git a/scripts/modules/bpy_extras/image_utils.py b/scripts/modules/bpy_extras/image_utils.py index 450cacd04f0..2b331b01112 100644 --- a/scripts/modules/bpy_extras/image_utils.py +++ b/scripts/modules/bpy_extras/image_utils.py @@ -94,9 +94,9 @@ def load_image( if verbose: if image: - print(" image loaded '%s'" % path) + print(" image loaded '{:s}'".format(path)) else: - print(" image load failed '%s'" % path) + print(" image load failed '{:s}'".format(path)) # image path has been checked so the path could not be read for some # reason, so be sure to return a placeholder @@ -138,7 +138,7 @@ def load_image( imagepath = bpy.path.native_pathsep(imagepath) if verbose: - print("load_image('%s', '%s', ...)" % (imagepath, dirname)) + print("load_image('{:s}', '{:s}', ...)".format(imagepath, dirname)) if os.path.exists(imagepath): return _image_load(imagepath) diff --git a/scripts/modules/bpy_extras/io_utils.py b/scripts/modules/bpy_extras/io_utils.py index 7c84f0b9fdd..3bb4b5a8b1c 100644 --- a/scripts/modules/bpy_extras/io_utils.py +++ b/scripts/modules/bpy_extras/io_utils.py @@ -505,7 +505,7 @@ def path_reference( filepath_abs = filepath_cpy mode = 'RELATIVE' else: - raise Exception("invalid mode given %r" % mode) + raise Exception("invalid mode given {!r}".format(mode)) if mode == 'ABSOLUTE': return filepath_abs @@ -537,7 +537,7 @@ def path_reference_copy(copy_set, report=print): for file_src, file_dst in copy_set: if not os.path.exists(file_src): - report("missing %r, not copying" % file_src) + report("missing {!r}, not copying".format(file_src)) elif os.path.exists(file_dst) and os.path.samefile(file_src, file_dst): pass else: @@ -588,7 +588,7 @@ def unique_name(key, name, name_dict, name_max=-1, clean_func=None, sep="."): if name_max == -1: while name_new in name_dict_values: - name_new = "%s%s%03d" % ( + name_new = "{:s}{:s}{:03d}".format( name_new_orig, sep, count, @@ -597,10 +597,10 @@ def unique_name(key, name, name_dict, name_max=-1, clean_func=None, sep="."): else: name_new = name_new[:name_max] while name_new in name_dict_values: - count_str = "%03d" % count - name_new = "%.*s%s%s" % ( - name_max - (len(count_str) + 1), + count_str = "{:03d}".format(count) + name_new = "{:.{:d}s}{:s}{:s}".format( name_new_orig, + name_max - (len(count_str) + 1), sep, count_str, ) diff --git a/scripts/modules/bpy_extras/object_utils.py b/scripts/modules/bpy_extras/object_utils.py index fd121a31f76..1567fbb5b2e 100644 --- a/scripts/modules/bpy_extras/object_utils.py +++ b/scripts/modules/bpy_extras/object_utils.py @@ -282,7 +282,7 @@ def object_report_if_active_shape_key_is_locked(obj, operator): if key and key.lock_shape: if operator: - operator.report({'ERROR'}, "The active shape key of %s is locked" % obj.name) + operator.report({'ERROR'}, "The active shape key of {:s} is locked".format(obj.name)) return True diff --git a/scripts/modules/bpy_extras/wm_utils/progress_report.py b/scripts/modules/bpy_extras/wm_utils/progress_report.py index 2ea63a37b4c..61c4ffd94e4 100644 --- a/scripts/modules/bpy_extras/wm_utils/progress_report.py +++ b/scripts/modules/bpy_extras/wm_utils/progress_report.py @@ -76,10 +76,14 @@ class ProgressReport: self.wm.progress_update(steps) if msg: prefix = " " * (len(self.steps) - 1) - print(prefix + "(%8.4f sec | %8.4f sec) %s\nProgress: %6.2f%%\r" % - (tm, loc_tm, msg, steps_percent), end='') + print( + prefix + "({:8.4f} sec | {:8.4f} sec) {:s}\nProgress: {:6.2f}%\r".format( + tm, loc_tm, msg, steps_percent, + ), + end="", + ) else: - print("Progress: %6.2f%%\r" % (steps_percent,), end='') + print("Progress: {:6.2f}%\r".format(steps_percent,), end="") def enter_substeps(self, nbr, msg=""): if msg: diff --git a/scripts/modules/bpy_types.py b/scripts/modules/bpy_types.py index 1b4808d731d..0716a6ec491 100644 --- a/scripts/modules/bpy_types.py +++ b/scripts/modules/bpy_types.py @@ -27,7 +27,7 @@ class Context(StructRNA): :type coerce: boolean """ # This is a convenience wrapper around `StructRNA.path_resolve` which doesn't support accessing context members. - # Without this wrapper many users were writing `exec("context.%s" % data_path)` which is a security + # Without this wrapper many users were writing `exec("context.{:s}".format(data_path))` which is a security # concern if the `data_path` comes from an unknown source. # This function performs the initial lookup, after that the regular `path_resolve` function is used. @@ -53,7 +53,7 @@ class Context(StructRNA): # to simplify exception handling for the caller. value = getattr(self, attr, _sentinel) if value is _sentinel: - raise ValueError("Path could not be resolved: %r" % attr) + raise ValueError("Path could not be resolved: {!r}".format(attr)) if value is None: return value @@ -62,22 +62,22 @@ class Context(StructRNA): if isinstance(value, list) and path_rest.startswith("["): index_str, div, index_tail = path_rest[1:].partition("]") if not div: - raise ValueError("Path index is not terminated: %s%s" % (attr, path_rest)) + raise ValueError("Path index is not terminated: {:s}{:s}".format(attr, path_rest)) try: index = int(index_str) except ValueError: - raise ValueError("Path index is invalid: %s[%s]" % (attr, index_str)) + raise ValueError("Path index is invalid: {:s}[{:s}]".format(attr, index_str)) if 0 <= index < len(value): path_rest = index_tail value = value[index] else: - raise IndexError("Path index out of range: %s[%s]" % (attr, index_str)) + raise IndexError("Path index out of range: {:s}[{:s}]".format(attr, index_str)) # Resolve the rest of the path if necessary. if path_rest: path_resolve_fn = getattr(value, "path_resolve", None) if path_resolve_fn is None: - raise ValueError("Path %s resolves to a non RNA value" % attr) + raise ValueError("Path {:s} resolves to a non RNA value".format(attr)) return path_resolve_fn(path_rest, coerce) return value @@ -468,7 +468,7 @@ class _GenericBone: return id_data.edit_bones if isinstance(self, Bone): return id_data.bones - raise RuntimeError("Invalid type %r" % self) + raise RuntimeError("Invalid type {!r}".format(self)) class PoseBone(StructRNA, _GenericBone, metaclass=StructMetaPropGroup): diff --git a/scripts/modules/console_python.py b/scripts/modules/console_python.py index 474684129b6..9fd21984509 100644 --- a/scripts/modules/console_python.py +++ b/scripts/modules/console_python.py @@ -167,7 +167,7 @@ def execute(context, is_interactive): except SystemExit as ex: # Occurs when `exit(..)` is called, this raises an exception instead of exiting. # The trace-back isn't helpful in this case, just print the exception. - stderr.write("%r\n" % ex) + stderr.write("{!r}\n".format(ex)) # Without this, entering new commands may include the previous command, see: #109435. console.resetbuffer() except: @@ -337,7 +337,7 @@ def banner(context): version_string = sys.version.strip().replace('\n', ' ') message = ( - "PYTHON INTERACTIVE CONSOLE %s" % version_string, + "PYTHON INTERACTIVE CONSOLE {:s}".format(version_string), "", "Builtin Modules: " "bpy, bpy.data, bpy.ops, bpy.props, bpy.types, bpy.context, bpy.utils, bgl, gpu, blf, mathutils", diff --git a/scripts/modules/graphviz_export.py b/scripts/modules/graphviz_export.py index 8cc9be8ee4f..e6b3168ac11 100644 --- a/scripts/modules/graphviz_export.py +++ b/scripts/modules/graphviz_export.py @@ -40,7 +40,7 @@ def graph_armature(obj, filepath, FAKE_PARENT=True, CONSTRAINTS=True, DRIVERS=Tr fileobject = open(filepath, "w") fw = fileobject.write fw(header) - fw('label = "%s::%s" ;' % (bpy.data.filepath.split("/")[-1].split("\\")[-1], obj.name)) + fw('label = "{:s}::{:s}" ;'.format(bpy.data.filepath.split("/")[-1].split("\\")[-1], obj.name)) arm = obj.data @@ -58,18 +58,18 @@ def graph_armature(obj, filepath, FAKE_PARENT=True, CONSTRAINTS=True, DRIVERS=Tr continue if type(value) == float: - value = "%.3f" % value + value = "{:.3f}".format(value) elif type(value) == str: value = compat_str(value) - label.append("%s = %s" % (key, value)) + label.append("{:s} = {:s}".format(key, value)) opts = [ "shape=box", "regular=1", "style=filled", "fixedsize=false", - 'label="%s"' % compat_str('\n'.join(label)), + 'label="{:s}"'.format(compat_str('\n'.join(label))), ] if bone.name.startswith('ORG'): @@ -77,13 +77,13 @@ def graph_armature(obj, filepath, FAKE_PARENT=True, CONSTRAINTS=True, DRIVERS=Tr else: opts.append("fillcolor=white") - fw('"%s" [%s];\n' % (bone.name, ','.join(opts))) + fw('"{:s}" [{:s}];\n'.format(bone.name, ','.join(opts))) fw('\n\n# Hierarchy:\n') # Root node. if FAKE_PARENT: - fw('"Object::%s" [];\n' % obj.name) + fw('"Object::{:s}" [];\n'.format(obj.name)) for bone in bones: bone = arm.bones[bone] @@ -93,7 +93,7 @@ def graph_armature(obj, filepath, FAKE_PARENT=True, CONSTRAINTS=True, DRIVERS=Tr parent_name = parent.name connected = bone.use_connect elif FAKE_PARENT: - parent_name = "Object::%s" % obj.name + parent_name = "Object::{:s}".format(obj.name) connected = False else: continue @@ -102,7 +102,7 @@ def graph_armature(obj, filepath, FAKE_PARENT=True, CONSTRAINTS=True, DRIVERS=Tr if not connected: opts.append("style=dotted") - fw('"%s" -> "%s" [%s] ;\n' % (bone.name, parent_name, ','.join(opts))) + fw('"{:s}" -> "{:s}" [{:s}] ;\n'.format(bone.name, parent_name, ','.join(opts))) del bone # constraints @@ -125,9 +125,9 @@ def graph_armature(obj, filepath, FAKE_PARENT=True, CONSTRAINTS=True, DRIVERS=Tr 'labelfontsize=4', ] if XTRA_INFO: - label = "%s\n%s" % (constraint.type, constraint.name) - opts.append('label="%s"' % compat_str(label)) - fw('"%s" -> "%s" [%s] ;\n' % (pbone.name, subtarget, ','.join(opts))) + label = "{:s}\n{:s}".format(constraint.type, constraint.name) + opts.append('label="{:s}"'.format(compat_str(label))) + fw('"{:s}" -> "{:s}" [{:s}] ;\n'.format(pbone.name, subtarget, ','.join(opts))) # Drivers if DRIVERS: @@ -170,9 +170,9 @@ def graph_armature(obj, filepath, FAKE_PARENT=True, CONSTRAINTS=True, DRIVERS=Tr display_source = rna_path.replace("pose.bones", "") display_target = rna_path_target.replace("pose.bones", "") if XTRA_INFO: - label = "%s\\n%s" % (display_source, display_target) - opts.append('label="%s"' % compat_str(label)) - fw('"%s" -> "%s" [%s] ;\n' % (pbone_target.name, pbone.name, ','.join(opts))) + label = "{:s}\\n{:s}".format(display_source, display_target) + opts.append('label="{:s}"'.format(compat_str(label))) + fw('"{:s}" -> "{:s}" [{:s}] ;\n'.format(pbone_target.name, pbone.name, ','.join(opts))) fw(footer) fileobject.close() @@ -190,4 +190,4 @@ if __name__ == "__main__": import os tmppath = "/tmp/test.dot" graph_armature(bpy.context.object, tmppath, CONSTRAINTS=True, DRIVERS=True) - os.system("dot -Tpng %s > %s; eog %s &" % (tmppath, tmppath + '.png', tmppath + '.png')) + os.system("dot -Tpng {:s} > {:s}; eog {:s} &".format(tmppath, tmppath + '.png', tmppath + '.png')) diff --git a/scripts/modules/keyingsets_utils.py b/scripts/modules/keyingsets_utils.py index e13d61fb133..e7f7970603b 100644 --- a/scripts/modules/keyingsets_utils.py +++ b/scripts/modules/keyingsets_utils.py @@ -221,7 +221,7 @@ def RKS_GEN_custom_props(_ksi, _context, ks, data): if cprop_name == "_RNA_UI": continue - prop_path = '["%s"]' % bpy.utils.escape_identifier(cprop_name) + prop_path = '["{:s}"]'.format(bpy.utils.escape_identifier(cprop_name)) try: rna_property = data.path_resolve(prop_path, False) @@ -235,7 +235,7 @@ def RKS_GEN_custom_props(_ksi, _context, ks, data): if rna_property.rna_type not in prop_type_compat: continue - path = "%s%s" % (base_path, prop_path) + path = "{:s}{:s}".format(base_path, prop_path) if grouping: ks.paths.add(id_block, path, group_method='NAMED', group_name=grouping) else: diff --git a/scripts/modules/nodeitems_utils.py b/scripts/modules/nodeitems_utils.py index a315adf417a..f0b0b36b272 100644 --- a/scripts/modules/nodeitems_utils.py +++ b/scripts/modules/nodeitems_utils.py @@ -87,7 +87,7 @@ _node_categories = {} def register_node_categories(identifier, cat_list): if identifier in _node_categories: - raise KeyError("Node categories list '%s' already registered" % identifier) + raise KeyError("Node categories list '{:s}' already registered".format(identifier)) return # works as draw function for menus @@ -116,7 +116,7 @@ def register_node_categories(identifier, cat_list): for cat in cat_list: if cat.poll(context): - layout.menu("NODE_MT_category_%s" % cat.identifier) + layout.menu("NODE_MT_category_" + cat.identifier) # Stores: (categories list, menu draw function, sub-menu types). _node_categories[identifier] = (cat_list, draw_add_menu, menu_types) diff --git a/scripts/modules/rna_info.py b/scripts/modules/rna_info.py index 9858594acf9..cb76e3d0c22 100644 --- a/scripts/modules/rna_info.py +++ b/scripts/modules/rna_info.py @@ -54,13 +54,13 @@ def range_str(val): elif val > 10000000: return "inf" elif type(val) == float: - return '%g' % val + return "{:g}".format(val) else: return str(val) def float_as_string(f): - val_str = "%g" % f + val_str = "{:g}".format(f) # Ensure a `.0` suffix for whole numbers, excluding scientific notation such as `1e-05` or `1e+5`. if '.' not in val_str and 'e' not in val_str: val_str += '.0' @@ -220,7 +220,7 @@ class InfoStructRNA: txt = "" txt += self.identifier if self.base: - txt += "(%s)" % self.base.identifier + txt += "({:s})".format(self.base.identifier) txt += ": " + self.description + "\n" for prop in self.properties: @@ -316,7 +316,7 @@ class InfoPropertyRNA: if dim != 0: self.default = tuple(zip(*((iter(self.default),) * dim))) self.default_str = tuple( - "(%s)" % ", ".join(s for s in b) for b in zip(*((iter(self.default_str),) * dim)) + "({:s})".format(", ".join(s for s in b)) for b in zip(*((iter(self.default_str),) * dim)) ) self.default_str = self.default_str[0] elif self.type == "enum" and self.is_enum_flag: @@ -329,18 +329,18 @@ class InfoPropertyRNA: self.default = None self.default_str = "None" elif self.type == "string": - self.default_str = "\"%s\"" % self.default + self.default_str = "\"{:s}\"".format(self.default) elif self.type == "enum": if self.is_enum_flag: # self.default_str = repr(self.default) # repr or set() - self.default_str = "{%s}" % repr(list(sorted(self.default)))[1:-1] + self.default_str = "{{{:s}}}".format(repr(list(sorted(self.default)))[1:-1]) else: - self.default_str = "'%s'" % self.default + self.default_str = "'{:s}'".format(self.default) elif self.array_length: if self.array_dimensions[1] == 0: # single dimension array, we already took care of multi-dimensions ones. # special case for floats if self.type == "float" and len(self.default) > 0: - self.default_str = "(%s)" % ", ".join(float_as_string(f) for f in self.default) + self.default_str = "({:s})".format(", ".join(float_as_string(f) for f in self.default)) else: self.default_str = str(self.default) else: @@ -354,15 +354,15 @@ class InfoPropertyRNA: def get_arg_default(self, force=True): default = self.default_str if default and (force or self.is_required is False): - return "%s=%s" % (self.identifier, default) + return "{:s}={:s}".format(self.identifier, default) return self.identifier def get_type_description( self, *, as_ret=False, as_arg=False, - class_fmt="%s", - mathutils_fmt="%s", + class_fmt="{:s}", + mathutils_fmt="{:s}", collection_id="Collection", enum_descr_override=None, ): @@ -376,65 +376,68 @@ class InfoPropertyRNA: type_str += self.type if self.array_length: if self.array_dimensions[1] != 0: - dimension_str = " of %s items" % ( + dimension_str = " of {:s} items".format( " * ".join(str(d) for d in self.array_dimensions if d != 0) ) type_str += " multi-dimensional array" + dimension_str else: - dimension_str = " of %d items" % (self.array_length) + dimension_str = " of {:d} items".format(self.array_length) type_str += " array" + dimension_str # Describe mathutils types; logic mirrors pyrna_math_object_from_array if self.type == "float": if self.subtype == "MATRIX": if self.array_length in {9, 16}: - type_str = (mathutils_fmt % "Matrix") + dimension_str + type_str = (mathutils_fmt.format("Matrix")) + dimension_str elif self.subtype in {"COLOR", "COLOR_GAMMA"}: if self.array_length == 3: - type_str = (mathutils_fmt % "Color") + dimension_str + type_str = (mathutils_fmt.format("Color")) + dimension_str elif self.subtype in {"EULER", "QUATERNION"}: if self.array_length == 3: - type_str = (mathutils_fmt % "Euler") + " rotation" + dimension_str + type_str = (mathutils_fmt.format("Euler")) + " rotation" + dimension_str elif self.array_length == 4: - type_str = (mathutils_fmt % "Quaternion") + " rotation" + dimension_str + type_str = (mathutils_fmt.format("Quaternion")) + " rotation" + dimension_str elif self.subtype in { 'COORDINATES', 'TRANSLATION', 'DIRECTION', 'VELOCITY', 'ACCELERATION', 'XYZ', 'XYZ_LENGTH', }: if 2 <= self.array_length <= 4: - type_str = (mathutils_fmt % "Vector") + dimension_str + type_str = (mathutils_fmt.format("Vector")) + dimension_str if self.type in {"float", "int"}: - type_str += " in [%s, %s]" % (range_str(self.min), range_str(self.max)) + type_str += " in [{:s}, {:s}]".format(range_str(self.min), range_str(self.max)) elif self.type == "enum": enum_descr = enum_descr_override if not enum_descr: if self.is_enum_flag: - enum_descr = "{%s}" % ", ".join(("'%s'" % s[0]) for s in self.enum_items) + enum_descr = "{{{:s}}}".format(", ".join(("'{:s}'".format(s[0])) for s in self.enum_items)) else: - enum_descr = "[%s]" % ", ".join(("'%s'" % s[0]) for s in self.enum_items) + enum_descr = "[{:s}]".format(", ".join(("'{:s}'".format(s[0])) for s in self.enum_items)) if self.is_enum_flag: - type_str += " set in %s" % enum_descr + type_str += " set in {:s}".format(enum_descr) else: - type_str += " in %s" % enum_descr + type_str += " in {:s}".format(enum_descr) del enum_descr if not (as_arg or as_ret): # write default property, ignore function args for this if self.type != "pointer": if self.default_str: - type_str += ", default %s" % self.default_str + type_str += ", default {:s}".format(self.default_str) else: if self.type == "collection": if self.collection_type: - collection_str = (class_fmt % self.collection_type.identifier) + (" %s of " % collection_id) + collection_str = ( + class_fmt.format(self.collection_type.identifier) + + " {:s} of ".format(collection_id) + ) else: - collection_str = "%s of " % collection_id + collection_str = "{:s} of ".format(collection_id) else: collection_str = "" - type_str += collection_str + (class_fmt % self.fixed_type.identifier) + type_str += collection_str + (class_fmt.format(self.fixed_type.identifier)) # setup qualifiers for this value. type_info = [] @@ -453,7 +456,7 @@ class InfoPropertyRNA: type_info.append("never None") if type_info: - type_str += (", (%s)" % ", ".join(type_info)) + type_str += ", ({:s})".format(", ".join(type_info)) return type_str @@ -622,7 +625,7 @@ def BuildRNAInfo(): """ nested = rna_struct.nested if nested: - return "%s.%s" % (full_rna_struct_path(nested), rna_struct.identifier) + return "{:s}.{:s}".format(full_rna_struct_path(nested), rna_struct.identifier) else: return rna_struct.identifier @@ -739,7 +742,7 @@ def BuildRNAInfo(): i += 1 if not ok: - print("Dependency \"%s\" could not be found for \"%s\"" % (identifier, rna_base)) + print("Dependency \"{:s}\" could not be found for \"{:s}\"".format(identifier, rna_base)) break @@ -761,7 +764,7 @@ def BuildRNAInfo(): # Does this property point to me? if rna_prop_ptr and rna_prop_ptr.identifier in rna_references_dict: rna_references_dict[rna_prop_ptr.identifier].append( - "%s.%s" % (rna_struct_path, rna_prop_identifier)) + "{:s}.{:s}".format(rna_struct_path, rna_prop_identifier)) for rna_func in get_direct_functions(rna_struct): for rna_prop_identifier, rna_prop in rna_func.parameters.items(): @@ -774,7 +777,7 @@ def BuildRNAInfo(): # Does this property point to me? if rna_prop_ptr and rna_prop_ptr.identifier in rna_references_dict: rna_references_dict[rna_prop_ptr.identifier].append( - "%s.%s" % (rna_struct_path, rna_func.identifier)) + "{:s}.{:s}".format(rna_struct_path, rna_func.identifier)) # Store nested children nested = rna_struct.nested @@ -832,8 +835,9 @@ def BuildRNAInfo(): default = prop.default if type(default) in {float, int}: if default < prop.min or default > prop.max: - print("\t %s.%s, %s not in [%s - %s]" % - (rna_info.identifier, prop.identifier, default, prop.min, prop.max)) + print("\t {:s}.{:s}, {:s} not in [{:s} - {:s}]".format( + rna_info.identifier, prop.identifier, default, prop.min, prop.max, + )) # now for operators op_mods = dir(bpy.ops) @@ -885,12 +889,16 @@ def main(): # continue prop_type = prop.type if prop.array_length > 0: - prop_type += "[%d]" % prop.array_length + prop_type += "[{:d}]".format(prop.array_length) data.append( - "%s.%s -> %s: %s%s %s" % - (struct_id_str, prop.identifier, prop.identifier, prop_type, - ", (read-only)" if prop.is_readonly else "", prop.description)) + "{:s}.{:s} -> {:s}: {:s}{:s} {:s}".format( + struct_id_str, + prop.identifier, + prop.identifier, + prop_type, + ", (read-only)" if prop.is_readonly else "", prop.description, + )) data.sort() if bpy.app.background: diff --git a/scripts/modules/rna_keymap_ui.py b/scripts/modules/rna_keymap_ui.py index a48bcab39e8..9e50cf056e7 100644 --- a/scripts/modules/rna_keymap_ui.py +++ b/scripts/modules/rna_keymap_ui.py @@ -77,7 +77,10 @@ def draw_km(display_keymaps, kc, km, children, layout, level): subcol = _indented_layout(col, level + 1) subrow = subcol.row(align=True) subrow.prop(km, "show_expanded_items", text="", emboss=False) - subrow.label(text=iface_("%s (Global)") % iface_(km.name, i18n_contexts.id_windowmanager), translate=False) + subrow.label( + text=iface_("{:s} (Global)").format(iface_(km.name, i18n_contexts.id_windowmanager)), + translate=False, + ) else: km.show_expanded_items = True @@ -238,7 +241,7 @@ def draw_filtered(display_keymaps, filter_type, filter_text, layout): "MMB": 'MIDDLEMOUSE', }) _EVENT_TYPE_MAP_EXTRA.update({ - "%d" % i: "NUMPAD_%d" % i for i in range(10) + "{:d}".format(i): "NUMPAD_{:d}".format(i) for i in range(10) }) # done with once off init diff --git a/scripts/modules/rna_manual_reference.py b/scripts/modules/rna_manual_reference.py index 2aedf4ea431..80cf9e12edd 100644 --- a/scripts/modules/rna_manual_reference.py +++ b/scripts/modules/rna_manual_reference.py @@ -2,12 +2,13 @@ # # SPDX-License-Identifier: GPL-2.0-or-later -# Do not edit this file. This file is auto generated from rna_manual_reference_updater.py +# Do not edit this file. This file is auto generated from: +# ./tools/utils_doc/rna_manual_reference_updater.py # autopep8: off import bpy -url_manual_prefix = "https://docs.blender.org/manual/%s/%d.%d/" % ( +url_manual_prefix = "https://docs.blender.org/manual/{:s}/{:d}.{:d}/".format( bpy.utils.manual_language_code(), *bpy.app.version[:2], ) diff --git a/scripts/modules/rna_prop_ui.py b/scripts/modules/rna_prop_ui.py index 5811158bf39..3a6ea6b174a 100644 --- a/scripts/modules/rna_prop_ui.py +++ b/scripts/modules/rna_prop_ui.py @@ -16,7 +16,7 @@ MAX_DISPLAY_ROWS = 8 def rna_idprop_quote_path(prop): - return "[\"%s\"]" % bpy.utils.escape_identifier(prop) + return "[\"{:s}\"]".format(bpy.utils.escape_identifier(prop)) def rna_idprop_ui_prop_update(item, prop): @@ -262,7 +262,7 @@ class PropertyPanel: rna_item, context_member = rna_idprop_context_value(context, self._context_path, self._property_type) tot = len(rna_item.keys()) if tot: - self.layout().label(text="%d:" % tot) + self.layout().label(text="{:d}:".format(tot)) """ def draw(self, context): diff --git a/scripts/modules/rna_xml.py b/scripts/modules/rna_xml.py index 76c11f36be9..306fa8de94b 100644 --- a/scripts/modules/rna_xml.py +++ b/scripts/modules/rna_xml.py @@ -39,9 +39,9 @@ def build_property_typemap(skip_classes, skip_typemap): try: properties.remove(prop_id) except: - print("skip_typemap unknown prop_id '%s.%s'" % (cls_name, prop_id)) + print("skip_typemap unknown prop_id '{:s}.{:s}'".format(cls_name, prop_id)) else: - print("skip_typemap unknown class '%s'" % cls_name) + print("skip_typemap unknown class '{:s}'".format(cls_name)) return property_typemap @@ -85,13 +85,13 @@ def rna2xml( def number_to_str(val, val_type): if val_type == int: - return "%d" % val + return "{:d}".format(val) elif val_type == float: - return "%.6g" % val + return "{:.6g}".format(val) elif val_type == bool: return "TRUE" if val else "FALSE" else: - raise NotImplementedError("this type is not a number %s" % val_type) + raise NotImplementedError("this type is not a number {:s}".format(val_type)) def rna2xml_node(ident, value, parent): ident_next = ident + ident_val @@ -117,16 +117,16 @@ def rna2xml( subvalue_type = type(subvalue) if subvalue_type in {int, bool, float}: - node_attrs.append("%s=\"%s\"" % (prop, number_to_str(subvalue, subvalue_type))) + node_attrs.append("{:s}=\"{:s}\"".format(prop, number_to_str(subvalue, subvalue_type))) elif subvalue_type is str: - node_attrs.append("%s=%s" % (prop, quoteattr(subvalue))) + node_attrs.append("{:s}={:s}".format(prop, quoteattr(subvalue))) elif subvalue_type is set: - node_attrs.append("%s=%s" % (prop, quoteattr("{" + ",".join(list(subvalue)) + "}"))) + node_attrs.append("{:s}={:s}".format(prop, quoteattr("{" + ",".join(list(subvalue)) + "}"))) elif subvalue is None: - node_attrs.append("%s=\"NONE\"" % prop) + node_attrs.append("{:s}=\"NONE\"".format(prop)) elif issubclass(subvalue_type, referenced_classes): # special case, ID's are always referenced. - node_attrs.append("%s=%s" % (prop, quoteattr(subvalue_type.__name__ + "::" + subvalue.name))) + node_attrs.append("{:s}={:s}".format(prop, quoteattr(subvalue_type.__name__ + "::" + subvalue.name))) else: try: subvalue_ls = list(subvalue) @@ -148,7 +148,7 @@ def rna2xml( prop_rna.array_length in {3, 4}): # ----- # color - array_value = "#" + "".join(("%.2x" % int(v * 255) for v in subvalue_rna)) + array_value = "#" + "".join(("{:02x}".format(int(v * 255)) for v in subvalue_rna)) else: # default @@ -161,43 +161,43 @@ def rna2xml( array_value = " ".join(str_recursive(v) for v in subvalue_rna) - node_attrs.append("%s=\"%s\"" % (prop, array_value)) + node_attrs.append("{:s}=\"{:s}\"".format(prop, array_value)) else: nodes_lists.append((prop, subvalue_ls, subvalue_type)) # declare + attributes if pretty_format: if node_attrs: - fw("%s<%s\n" % (ident, value_type_name)) + fw("{:s}<{:s}\n".format(ident, value_type_name)) for node_attr in node_attrs: - fw("%s%s\n" % (ident_next, node_attr)) - fw("%s>\n" % (ident_next,)) + fw("{:s}{:s}\n".format(ident_next, node_attr)) + fw("{:s}>\n".format(ident_next,)) else: - fw("%s<%s>\n" % (ident, value_type_name)) + fw("{:s}<{:s}>\n".format(ident, value_type_name)) else: - fw("%s<%s %s>\n" % (ident, value_type_name, " ".join(node_attrs))) + fw("{:s}<{:s} {:s}>\n".format(ident, value_type_name, " ".join(node_attrs))) # unique members for prop, subvalue, subvalue_type in nodes_items: - fw("%s<%s>\n" % (ident_next, prop)) # XXX, this is awkward, how best to solve? + fw("{:s}<{:s}>\n".format(ident_next, prop)) # XXX, this is awkward, how best to solve? rna2xml_node(ident_next + ident_val, subvalue, value) - fw("%s\n" % (ident_next, prop)) # XXX, need to check on this. + fw("{:s}\n".format(ident_next, prop)) # XXX, need to check on this. # list members for prop, subvalue, subvalue_type in nodes_lists: - fw("%s<%s>\n" % (ident_next, prop)) + fw("{:s}<{:s}>\n".format(ident_next, prop)) for subvalue_item in subvalue: if subvalue_item is not None: rna2xml_node(ident_next + ident_val, subvalue_item, value) - fw("%s\n" % (ident_next, prop)) + fw("{:s}\n".format(ident_next, prop)) - fw("%s\n" % (ident, value_type_name)) + fw("{:s}\n".format(ident, value_type_name)) # ------------------------------------------------------------------------- # needs re-working to be generic if root_node: - fw("%s<%s>\n" % (root_ident, root_node)) + fw("{:s}<{:s}>\n".format(root_ident, root_node)) # bpy.data if method == 'DATA': @@ -217,16 +217,16 @@ def rna2xml( ls = None if type(ls) == list: - fw("%s<%s>\n" % (ident, attr)) + fw("{:s}<{:s}>\n".format(ident, attr)) for blend_id in ls: rna2xml_node(ident + ident_val, blend_id, None) - fw("%s\n" % (ident_val, attr)) + fw("{:s}\n".format(ident_val, attr)) # any attribute elif method == 'ATTR': rna2xml_node(root_ident, root_rna, None) if root_node: - fw("%s\n" % (root_ident, root_node)) + fw("{:s}\n".format(root_ident, root_node)) def xml2rna( @@ -245,7 +245,7 @@ def xml2rna( subvalue = getattr(value, attr, Ellipsis) if subvalue is Ellipsis: - print("%s.%s not found" % (type(value).__name__, attr)) + print("{:s}.{:s} not found".format(type(value).__name__, attr)) else: value_xml = xml_node.attributes[attr].value @@ -282,7 +282,7 @@ def xml2rna( del value_xml_split # tp_name = 'ARRAY' - # print(" %s.%s (%s) --- %s" % (type(value).__name__, attr, tp_name, subvalue_type)) + # print(" {:s}.{:s} ({:s}) --- {:s}".format(type(value).__name__, attr, tp_name, subvalue_type)) try: setattr(value, attr, value_xml_coerce) except ValueError: @@ -318,7 +318,7 @@ def xml2rna( subsubvalue = subvalue[i] if child_xml_real is None or subsubvalue is None: - print("None found %s - %d collection:", (child_xml.nodeName, i)) + print("None found {:s} - {:d} collection:".format(child_xml.nodeName, i)) else: rna2xml_node(child_xml_real, subsubvalue) @@ -348,7 +348,7 @@ def _get_context_val(context, path): try: value = context.path_resolve(path) except BaseException as ex: - print("Error: %r, path %r not found" % (ex, path)) + print("Error: {!r}, path {!r} not found".format(ex, path)) value = Ellipsis return value @@ -369,7 +369,7 @@ def xml_file_run(context, filepath, rna_map): value = _get_context_val(context, rna_path) if value is not Ellipsis and value is not None: - # print(" loading XML: %r -> %r" % (filepath, rna_path)) + # print(" loading XML: {!r} -> {!r}".format(filepath, rna_path)) xml2rna(xml_node, root_rna=value) diff --git a/scripts/modules/sys_info.py b/scripts/modules/sys_info.py index 9307f68e6c6..0d5888d31e3 100644 --- a/scripts/modules/sys_info.py +++ b/scripts/modules/sys_info.py @@ -26,55 +26,56 @@ def write_sysinfo(filepath): with open(filepath, 'w', encoding="utf-8") as output: try: - header = "= Blender %s System Information =\n" % bpy.app.version_string - lilies = "%s\n\n" % ((len(header) - 1) * "=") + header = "= Blender {:s} System Information =\n".format(bpy.app.version_string) + lilies = "{:s}\n\n".format((len(header) - 1) * "=") output.write(lilies[:-1]) output.write(header) output.write(lilies) def title(text): - return "\n%s:\n%s" % (text, lilies) + return "\n{:s}:\n{:s}".format(text, lilies) # build info output.write(title("Blender")) output.write( - "version: %s, branch: %s, commit date: %s %s, hash: %s, type: %s\n" % - (bpy.app.version_string, - prepr(bpy.app.build_branch), - prepr(bpy.app.build_commit_date), - prepr(bpy.app.build_commit_time), - prepr(bpy.app.build_hash), - prepr(bpy.app.build_type), - )) + "version: {:s}, branch: {:s}, commit date: {:s} {:s}, hash: {:s}, type: {:s}\n".format( + bpy.app.version_string, + prepr(bpy.app.build_branch), + prepr(bpy.app.build_commit_date), + prepr(bpy.app.build_commit_time), + prepr(bpy.app.build_hash), + prepr(bpy.app.build_type), + ) + ) - output.write("build date: %s, %s\n" % (prepr(bpy.app.build_date), prepr(bpy.app.build_time))) - output.write("platform: %s\n" % prepr(platform.platform())) - output.write("binary path: %s\n" % prepr(bpy.app.binary_path)) - output.write("build cflags: %s\n" % prepr(bpy.app.build_cflags)) - output.write("build cxxflags: %s\n" % prepr(bpy.app.build_cxxflags)) - output.write("build linkflags: %s\n" % prepr(bpy.app.build_linkflags)) - output.write("build system: %s\n" % prepr(bpy.app.build_system)) + output.write("build date: {:s}, {:s}\n".format(prepr(bpy.app.build_date), prepr(bpy.app.build_time))) + output.write("platform: {:s}\n".format(prepr(platform.platform()))) + output.write("binary path: {:s}\n".format(prepr(bpy.app.binary_path))) + output.write("build cflags: {:s}\n".format(prepr(bpy.app.build_cflags))) + output.write("build cxxflags: {:s}\n".format(prepr(bpy.app.build_cxxflags))) + output.write("build linkflags: {:s}\n".format(prepr(bpy.app.build_linkflags))) + output.write("build system: {:s}\n".format(prepr(bpy.app.build_system))) # Windowing Environment (include when dynamically selectable). from _bpy import _ghost_backend ghost_backend = _ghost_backend() if ghost_backend not in {'NONE', 'DEFAULT'}: - output.write("windowing environment: %s\n" % prepr(ghost_backend)) + output.write("windowing environment: {:s}\n".format(prepr(ghost_backend))) del _ghost_backend, ghost_backend # Python info. output.write(title("Python")) - output.write("version: %s\n" % (sys.version.replace("\n", " "))) - output.write("file system encoding: %s:%s\n" % ( + output.write("version: {:s}\n".format(sys.version.replace("\n", " "))) + output.write("file system encoding: {:s}:{:s}\n".format( sys.getfilesystemencoding(), sys.getfilesystemencodeerrors(), )) output.write("paths:\n") for p in sys.path: - output.write("\t%r\n" % p) + output.write("\t{!r}\n".format(p)) output.write(title("Python (External Binary)")) - output.write("binary path: %s\n" % prepr(sys.executable)) + output.write("binary path: {:s}\n".format(prepr(sys.executable))) try: py_ver = prepr(subprocess.check_output([ sys.executable, @@ -82,36 +83,40 @@ def write_sysinfo(filepath): ]).strip()) except BaseException as ex: py_ver = str(ex) - output.write("version: %s\n" % py_ver) + output.write("version: {:s}\n".format(py_ver)) del py_ver output.write(title("Directories")) output.write("scripts:\n") for p in bpy.utils.script_paths(): - output.write("\t%r\n" % p) - output.write("user scripts: %r\n" % (bpy.utils.script_path_user())) + output.write("\t{!r}\n".format(p)) + output.write("user scripts: {!r}\n".format(bpy.utils.script_path_user())) output.write("pref scripts:\n") for p in bpy.utils.script_paths_pref(): - output.write("\t%r\n" % p) - output.write("datafiles: %r\n" % (bpy.utils.user_resource('DATAFILES'))) - output.write("config: %r\n" % (bpy.utils.user_resource('CONFIG'))) - output.write("scripts: %r\n" % (bpy.utils.user_resource('SCRIPTS'))) - output.write("extensions: %r\n" % (bpy.utils.user_resource('EXTENSIONS'))) - output.write("tempdir: %r\n" % (bpy.app.tempdir)) + output.write("\t{!r}\n".format(p)) + output.write("datafiles: {!r}\n".format(bpy.utils.user_resource('DATAFILES'))) + output.write("config: {!r}\n".format(bpy.utils.user_resource('CONFIG'))) + output.write("scripts: {!r}\n".format(bpy.utils.user_resource('SCRIPTS'))) + output.write("extensions: {!r}\n".format(bpy.utils.user_resource('EXTENSIONS'))) + output.write("tempdir: {!r}\n".format(bpy.app.tempdir)) output.write(title("FFmpeg")) ffmpeg = bpy.app.ffmpeg if ffmpeg.supported: for lib in ("avcodec", "avdevice", "avformat", "avutil", "swscale"): output.write( - "%s:%s%r\n" % (lib, " " * (10 - len(lib)), - getattr(ffmpeg, lib + "_version_string"))) + "{:s}:{:s}{!r}\n".format( + lib, + " " * (10 - len(lib)), + getattr(ffmpeg, lib + "_version_string"), + ) + ) else: output.write("Blender was built without FFmpeg support\n") if bpy.app.build_options.sdl: output.write(title("SDL")) - output.write("Version: %s\n" % bpy.app.sdl.version_string) + output.write("Version: {:s}\n".format(bpy.app.sdl.version_string)) output.write("Loading method: ") if bpy.app.build_options.sdl_dynload: output.write("dynamically loaded by Blender (WITH_SDL_DYNLOAD=ON)\n") @@ -128,14 +133,14 @@ def write_sysinfo(filepath): output.write("Blender was built with OpenColorIO, " "but it currently uses fallback color management.\n") else: - output.write("%s\n" % (ocio.version_string)) + output.write("{:s}\n".format(ocio.version_string)) else: output.write("Blender was built without OpenColorIO support\n") oiio = bpy.app.oiio output.write("OpenImageIO: ") if ocio.supported: - output.write("%s\n" % (oiio.version_string)) + output.write("{:s}\n".format(oiio.version_string)) else: output.write("Blender was built without OpenImageIO support\n") @@ -143,7 +148,7 @@ def write_sysinfo(filepath): if bpy.app.build_options.cycles: if bpy.app.build_options.cycles_osl: from _cycles import osl_version_string - output.write("%s\n" % (osl_version_string)) + output.write("{:s}\n".format(osl_version_string)) else: output.write("Blender was built without OpenShadingLanguage support in Cycles\n") else: @@ -152,28 +157,28 @@ def write_sysinfo(filepath): opensubdiv = bpy.app.opensubdiv output.write("OpenSubdiv: ") if opensubdiv.supported: - output.write("%s\n" % opensubdiv.version_string) + output.write("{:s}\n".format(opensubdiv.version_string)) else: output.write("Blender was built without OpenSubdiv support\n") openvdb = bpy.app.openvdb output.write("OpenVDB: ") if openvdb.supported: - output.write("%s\n" % openvdb.version_string) + output.write("{:s}\n".format(openvdb.version_string)) else: output.write("Blender was built without OpenVDB support\n") alembic = bpy.app.alembic output.write("Alembic: ") if alembic.supported: - output.write("%s\n" % alembic.version_string) + output.write("{:s}\n".format(alembic.version_string)) else: output.write("Blender was built without Alembic support\n") usd = bpy.app.usd output.write("USD: ") if usd.supported: - output.write("%s\n" % usd.version_string) + output.write("{:s}\n".format(usd.version_string)) else: output.write("Blender was built without USD support\n") @@ -184,31 +189,51 @@ def write_sysinfo(filepath): output.write("\nGPU: missing, background mode\n") else: output.write(title("GPU")) - output.write("renderer:\t%r\n" % gpu.platform.renderer_get()) - output.write("vendor:\t\t%r\n" % gpu.platform.vendor_get()) - output.write("version:\t%r\n" % gpu.platform.version_get()) - output.write("device type:\t%r\n" % gpu.platform.device_type_get()) - output.write("backend type:\t%r\n" % gpu.platform.backend_type_get()) + output.write("renderer:\t{!r}\n".format(gpu.platform.renderer_get())) + output.write("vendor:\t\t{!r}\n".format(gpu.platform.vendor_get())) + output.write("version:\t{!r}\n".format(gpu.platform.version_get())) + output.write("device type:\t{!r}\n".format(gpu.platform.device_type_get())) + output.write("backend type:\t{!r}\n".format(gpu.platform.backend_type_get())) output.write("extensions:\n") glext = sorted(gpu.capabilities.extensions_get()) for l in glext: - output.write("\t%s\n" % l) + output.write("\t{:s}\n".format(l)) output.write(title("Implementation Dependent GPU Limits")) - output.write("Maximum Batch Vertices:\t%d\n" % gpu.capabilities.max_batch_vertices_get()) - output.write("Maximum Batch Indices:\t%d\n" % gpu.capabilities.max_batch_indices_get()) + output.write("Maximum Batch Vertices:\t{:d}\n".format( + gpu.capabilities.max_batch_vertices_get(), + )) + output.write("Maximum Batch Indices:\t{:d}\n".format( + gpu.capabilities.max_batch_indices_get(), + )) output.write("\nGLSL:\n") - output.write("Maximum Varying Floats:\t%d\n" % gpu.capabilities.max_varying_floats_get()) - output.write("Maximum Vertex Attributes:\t%d\n" % gpu.capabilities.max_vertex_attribs_get()) - output.write("Maximum Vertex Uniform Components:\t%d\n" % gpu.capabilities.max_uniforms_vert_get()) - output.write("Maximum Fragment Uniform Components:\t%d\n" % gpu.capabilities.max_uniforms_frag_get()) - output.write("Maximum Vertex Image Units:\t%d\n" % gpu.capabilities.max_textures_vert_get()) - output.write("Maximum Fragment Image Units:\t%d\n" % gpu.capabilities.max_textures_frag_get()) - output.write("Maximum Pipeline Image Units:\t%d\n" % gpu.capabilities.max_textures_get()) - output.write("Maximum Image Units:\t%d\n" % gpu.capabilities.max_images_get()) + output.write("Maximum Varying Floats:\t{:d}\n".format( + gpu.capabilities.max_varying_floats_get(), + )) + output.write("Maximum Vertex Attributes:\t{:d}\n".format( + gpu.capabilities.max_vertex_attribs_get(), + )) + output.write("Maximum Vertex Uniform Components:\t{:d}\n".format( + gpu.capabilities.max_uniforms_vert_get(), + )) + output.write("Maximum Fragment Uniform Components:\t{:d}\n".format( + gpu.capabilities.max_uniforms_frag_get(), + )) + output.write("Maximum Vertex Image Units:\t{:d}\n".format( + gpu.capabilities.max_textures_vert_get(), + )) + output.write("Maximum Fragment Image Units:\t{:d}\n".format( + gpu.capabilities.max_textures_frag_get(), + )) + output.write("Maximum Pipeline Image Units:\t{:d}\n".format( + gpu.capabilities.max_textures_get(), + )) + output.write("Maximum Image Units:\t{:d}\n".format( + gpu.capabilities.max_images_get(), + )) if bpy.app.build_options.cycles: import cycles @@ -221,14 +246,14 @@ def write_sysinfo(filepath): for addon in bpy.context.preferences.addons.keys(): addon_mod = addon_utils.addons_fake_modules.get(addon, None) if addon_mod is None: - output.write("%s (MISSING)\n" % (addon)) + output.write("{:s} (MISSING)\n".format(addon)) else: output.write( - "%s (version: %s, path: %r)\n" % ( + "{:s} (version: {:s}, path: {!r})\n".format( addon, - addon_mod.bl_info.get("version", "UNKNOWN"), + str(addon_mod.bl_info.get("version", "UNKNOWN")), addon_mod.__file__, ) ) except BaseException as ex: - output.write("ERROR: %s\n" % ex) + output.write("ERROR: {:s}\n".format(str(ex)))