Cleanup: replace {!s} with {:s} when used with strings

When passing strings to str.format(..) use `{:s}` format specifier
which only takes strings and wont run `.__str__()` on non-strings.

While `{!s}` is an equivalent to `%s`, for the most part `%s` was
used for strings, so using `{:s}` is clearer and more specific.
This commit is contained in:
Campbell Barton 2024-04-27 16:02:37 +10:00
parent 0e3b594edb
commit 0c4d3754f1
21 changed files with 130 additions and 130 deletions

@ -56,7 +56,7 @@ class ANIM_OT_keying_set_export(Operator):
scene = context.scene
ks = scene.keying_sets.active
f.write("# Keying Set: {!s}\n".format(ks.bl_idname))
f.write("# Keying Set: {:s}\n".format(ks.bl_idname))
f.write("import bpy\n\n")
f.write("scene = bpy.context.scene\n\n")
@ -96,44 +96,44 @@ class ANIM_OT_keying_set_export(Operator):
# (e.g. node-tree in Material).
if ksp.id.bl_rna.identifier.startswith("ShaderNodeTree"):
# Find material or light using this node tree...
id_bpy_path = "bpy.data.nodes[\"{!s}\"]"
id_bpy_path = "bpy.data.nodes[\"{:s}\"]"
found = False
for mat in bpy.data.materials:
if mat.node_tree == ksp.id:
id_bpy_path = "bpy.data.materials[\"{!s}\"].node_tree".format(escape_identifier(mat.name))
id_bpy_path = "bpy.data.materials[\"{:s}\"].node_tree".format(escape_identifier(mat.name))
found = True
break
if not found:
for light in bpy.data.lights:
if light.node_tree == ksp.id:
id_bpy_path = "bpy.data.lights[\"{!s}\"].node_tree".format(escape_identifier(light.name))
id_bpy_path = "bpy.data.lights[\"{:s}\"].node_tree".format(escape_identifier(light.name))
found = True
break
if not found:
self.report(
{'WARN'},
rpt_("Could not find material or light using Shader Node Tree - {!s}").format(str(ksp.id))
rpt_("Could not find material or light using Shader Node Tree - {:s}").format(str(ksp.id))
)
elif ksp.id.bl_rna.identifier.startswith("CompositorNodeTree"):
# Find compositor node-tree using this node tree.
for scene in bpy.data.scenes:
if scene.node_tree == ksp.id:
id_bpy_path = "bpy.data.scenes[\"{!s}\"].node_tree".format(escape_identifier(scene.name))
id_bpy_path = "bpy.data.scenes[\"{:s}\"].node_tree".format(escape_identifier(scene.name))
break
else:
self.report(
{'WARN'},
rpt_("Could not find scene using Compositor Node Tree - {!s}").format(str(ksp.id))
rpt_("Could not find scene using Compositor Node Tree - {:s}").format(str(ksp.id))
)
elif ksp.id.bl_rna.name == "Key":
# "keys" conflicts with a Python keyword, hence the simple solution won't work
id_bpy_path = "bpy.data.shape_keys[\"{!s}\"]".format(escape_identifier(ksp.id.name))
id_bpy_path = "bpy.data.shape_keys[\"{:s}\"]".format(escape_identifier(ksp.id.name))
else:
idtype_list = ksp.id.bl_rna.name.lower() + "s"
id_bpy_path = "bpy.data.{!s}[\"{!s}\"]".format(idtype_list, escape_identifier(ksp.id.name))
id_bpy_path = "bpy.data.{:s}[\"{:s}\"]".format(idtype_list, escape_identifier(ksp.id.name))
# shorthand ID for the ID-block (as used in the script)
short_id = "id_{:d}".format(len(id_to_paths_cache))
@ -143,7 +143,7 @@ class ANIM_OT_keying_set_export(Operator):
f.write("# ID's that are commonly used\n")
for id_pair in id_to_paths_cache.values():
f.write("{!s} = {!s}\n".format(id_pair[0], id_pair[1]))
f.write("{:s} = {:s}\n".format(id_pair[0], id_pair[1]))
f.write("\n")
# write paths
@ -157,7 +157,7 @@ class ANIM_OT_keying_set_export(Operator):
id_bpy_path = id_to_paths_cache[ksp.id][0]
else:
id_bpy_path = "None" # XXX...
f.write("{!s}, {!r}".format(id_bpy_path, ksp.data_path))
f.write("{:s}, {!r}".format(id_bpy_path, ksp.data_path))
# array index settings (if applicable)
if ksp.use_entire_array:
@ -450,7 +450,7 @@ class UpdateAnimatedTransformConstraint(Operator):
print(log)
text = bpy.data.texts.new("UpdateAnimatedTransformConstraint Report")
text.from_string(log)
self.report({'INFO'}, rpt_("Complete report available on '{!s}' text datablock").format(text.name))
self.report({'INFO'}, rpt_("Complete report available on '{:s}' text datablock").format(text.name))
return {'FINISHED'}

@ -42,7 +42,7 @@ class ConsoleExec(Operator):
if execute is not None:
return execute(context, self.interactive)
else:
print("Error: bpy.ops.console.execute_{!s} - not found".format(sc.language))
print("Error: bpy.ops.console.execute_{:s} - not found".format(sc.language))
return {'FINISHED'}
@ -64,7 +64,7 @@ class ConsoleAutocomplete(Operator):
if autocomplete:
return autocomplete(context)
else:
print("Error: bpy.ops.console.autocomplete_{!s} - not found".format(sc.language))
print("Error: bpy.ops.console.autocomplete_{:s} - not found".format(sc.language))
return {'FINISHED'}
@ -112,7 +112,7 @@ class ConsoleBanner(Operator):
if banner:
return banner(context)
else:
print("Error: bpy.ops.console.banner_{!s} - not found".format(sc.language))
print("Error: bpy.ops.console.banner_{:s} - not found".format(sc.language))
return {'FINISHED'}

@ -125,7 +125,7 @@ class WM_OT_previews_batch_generate(Operator):
if not self.use_backups:
cmd.append("--no_backups")
if subprocess.call(cmd):
self.report({'ERROR'}, rpt_("Previews generation process failed for file '{!s}'!").format(blen_path))
self.report({'ERROR'}, rpt_("Previews generation process failed for file '{:s}'!").format(blen_path))
context.window_manager.progress_end()
return {'CANCELLED'}
context.window_manager.progress_update(i + 1)
@ -235,7 +235,7 @@ class WM_OT_previews_batch_clear(Operator):
if not self.use_backups:
cmd.append("--no_backups")
if subprocess.call(cmd):
self.report({'ERROR'}, rpt_("Previews clear process failed for file '{!s}'!").format(blen_path))
self.report({'ERROR'}, rpt_("Previews clear process failed for file '{:s}'!").format(blen_path))
context.window_manager.progress_end()
return {'CANCELLED'}
context.window_manager.progress_update(i + 1)

@ -161,7 +161,7 @@ class ProjectEdit(Operator):
i = 0
while os.path.exists(bpy.path.abspath(filepath_final)):
filepath_final = filepath + "{:03d}.{!s}".format(i, EXT)
filepath_final = filepath + "{:03d}.{:s}".format(i, EXT)
i += 1
image_new.name = bpy.path.basename(filepath_final)
@ -191,7 +191,7 @@ class ProjectApply(Operator):
image_name = ProjectEdit._proj_hack[0] # TODO, deal with this nicer
image = bpy.data.images.get((image_name, None))
if image is None:
self.report({'ERROR'}, rpt_("Could not find image '{!s}'").format(image_name))
self.report({'ERROR'}, rpt_("Could not find image '{:s}'").format(image_name))
return {'CANCELLED'}
image.reload()
@ -290,7 +290,7 @@ class IMAGE_OT_open_images(Operator):
)
is_tiled = context.edit_image.source == 'TILED'
if len(files) > 1 and self.use_sequence_detection and not is_tiled:
context.edit_image.name = "{!s}{!s}{!s}".format(seq["prefix"], ("#" * seq["frame_size"]), seq["ext"])
context.edit_image.name = "{:s}{:s}{:s}".format(seq["prefix"], ("#" * seq["frame_size"]), seq["ext"])
return {'FINISHED'}

@ -98,7 +98,7 @@ class NodeAddOperator:
except AttributeError as ex:
self.report(
{'ERROR_INVALID_INPUT'},
rpt_("Node has no attribute {!s}").format(setting.name))
rpt_("Node has no attribute {:s}").format(setting.name))
print(str(ex))
# Continue despite invalid attribute

@ -364,12 +364,12 @@ class ShapeTransfer(Operator):
for ob_other in objects:
if ob_other.type != 'MESH':
self.report({'WARNING'},
rpt_("Skipping '{!s}', not a mesh").format(ob_other.name))
rpt_("Skipping '{:s}', not a mesh").format(ob_other.name))
continue
me_other = ob_other.data
if len(me_other.vertices) != len(me.vertices):
self.report({'WARNING'},
rpt_("Skipping '{!s}', vertex count differs").format(ob_other.name))
rpt_("Skipping '{:s}', vertex count differs").format(ob_other.name))
continue
target_normals = me_nos(me_other.vertices)
@ -508,7 +508,7 @@ class JoinUVs(Operator):
if not mesh.uv_layers:
self.report(
{'WARNING'},
rpt_("Object: {!s}, Mesh: '{!s}' has no UVs").format(obj.name, mesh.name),
rpt_("Object: {:s}, Mesh: '{:s}' has no UVs").format(obj.name, mesh.name),
)
else:
nbr_loops = len(mesh.loops)
@ -534,7 +534,7 @@ class JoinUVs(Operator):
self.report(
{'WARNING'},
rpt_(
"Object: {!s}, Mesh: '{!s}' has {:d} loops (for {:d} faces), expected {:d}\n"
"Object: {:s}, Mesh: '{:s}' has {:d} loops (for {:d} faces), expected {:d}\n"
).format(
obj_other.name,
mesh_other.name,
@ -552,7 +552,7 @@ class JoinUVs(Operator):
self.report(
{'ERROR'},
rpt_(
"Could not add a new UV map to object '{!s}' (Mesh '{!s}')\n"
"Could not add a new UV map to object '{:s}' (Mesh '{:s}')\n"
).format(
obj_other.name,
mesh_other.name,

@ -152,13 +152,13 @@ class AddPresetBase:
sub_value = getattr(value, sub_value_attr)
rna_recursive_attr_expand(
sub_value,
"{!s}.{!s}".format(rna_path_step, sub_value_attr),
"{:s}.{:s}".format(rna_path_step, sub_value_attr),
level,
)
elif type(value).__name__ == "bpy_prop_collection_idprop": # could use nicer method
file_preset.write("{!s}.clear()\n".format(rna_path_step))
file_preset.write("{:s}.clear()\n".format(rna_path_step))
for sub_value in value:
file_preset.write("item_sub_{:d} = {!s}.add()\n".format(level, rna_path_step))
file_preset.write("item_sub_{:d} = {:s}.add()\n".format(level, rna_path_step))
rna_recursive_attr_expand(sub_value, "item_sub_{:d}".format(level), level + 1)
else:
# convert thin wrapped sequences
@ -168,7 +168,7 @@ class AddPresetBase:
except BaseException:
pass
file_preset.write("{!s} = {!r}\n".format(rna_path_step, value))
file_preset.write("{:s} = {!r}\n".format(rna_path_step, value))
file_preset = open(filepath, "w", encoding="utf-8")
file_preset.write("import bpy\n")
@ -176,7 +176,7 @@ class AddPresetBase:
if hasattr(self, "preset_defines"):
for rna_path in self.preset_defines:
exec(rna_path)
file_preset.write("{!s}\n".format(rna_path))
file_preset.write("{:s}\n".format(rna_path))
file_preset.write("\n")
for rna_path in self.preset_values:
@ -652,7 +652,7 @@ class SavePresetInterfaceTheme(AddPresetBase, Operator):
try:
rna_xml.xml_file_write(context, filepath, preset_menu_class.preset_xml_map)
except BaseException as ex:
self.report({'ERROR'}, "Unable to overwrite preset: {!s}".format(str(ex)))
self.report({'ERROR'}, "Unable to overwrite preset: {:s}".format(str(ex)))
import traceback
traceback.print_exc()
return {'CANCELLED'}
@ -748,7 +748,7 @@ class AddPresetOperator(AddPresetBase, Operator):
for prop_id, prop in operator_rna.properties.items():
if not prop.is_skip_preset:
if prop_id not in properties_blacklist:
ret.append("op.{!s}".format(prop_id))
ret.append("op.{:s}".format(prop_id))
return ret
@ -756,7 +756,7 @@ class AddPresetOperator(AddPresetBase, Operator):
def operator_path(operator):
import os
prefix, suffix = operator.split("_OT_", 1)
return os.path.join("operator", "{!s}.{!s}".format(prefix.lower(), suffix))
return os.path.join("operator", "{:s}.{:s}".format(prefix.lower(), suffix))
class WM_MT_operator_presets(Menu):

@ -195,7 +195,7 @@ class PlayRenderedAnim(Operator):
try:
subprocess.Popen(cmd)
except BaseException as ex:
err_msg = rpt_("Couldn't run external animation player with command {!r}\n{!s}").format(cmd, str(ex))
err_msg = rpt_("Couldn't run external animation player with command {!r}\n{:s}").format(cmd, str(ex))
self.report(
{'ERROR'},
err_msg,

@ -236,7 +236,7 @@ class SequencerFadesAdd(Operator):
sequence.invalidate_cache('COMPOSITE')
sequence_string = "sequence" if len(faded_sequences) == 1 else "sequences"
self.report({'INFO'}, rpt_("Added fade animation to {:d} {!s}").format(len(faded_sequences), sequence_string))
self.report({'INFO'}, rpt_("Added fade animation to {:d} {:s}").format(len(faded_sequences), sequence_string))
return {'FINISHED'}
def calculate_fade_duration(self, context, sequence):

@ -231,7 +231,7 @@ class PREFERENCES_OT_keyconfig_import(Operator):
else:
shutil.move(self.filepath, path)
except BaseException as ex:
self.report({'ERROR'}, rpt_("Installing keymap failed: {!s}").format(str(ex)))
self.report({'ERROR'}, rpt_("Installing keymap failed: {:s}").format(str(ex)))
return {'CANCELLED'}
# sneaky way to check we're actually running the code.
@ -750,7 +750,7 @@ class PREFERENCES_OT_addon_install(Operator):
bpy.utils.refresh_script_paths()
# print message
msg = rpt_("Modules Installed ({!s}) from {!r} into {!r}").format(
msg = rpt_("Modules Installed ({:s}) from {!r} into {!r}").format(
", ".join(sorted(addons_new)), pyfile, path_addons,
)
@ -966,7 +966,7 @@ class PREFERENCES_OT_app_template_install(Operator):
bpy.utils.refresh_script_paths()
# print message
msg = rpt_("Template Installed ({!s}) from {!r} into {!r}").format(
msg = rpt_("Template Installed ({:s}) from {!r} into {!r}").format(
", ".join(sorted(app_templates_new)),
filepath,
path_app_templates,

@ -131,7 +131,7 @@ rna_module_prop = StringProperty(
def context_path_validate(context, data_path):
try:
value = eval("context.{!s}".format(data_path)) if data_path else Ellipsis
value = eval("context.{:s}".format(data_path)) if data_path else Ellipsis
except AttributeError as ex:
if str(ex).startswith("'NoneType'"):
# One of the items in the rna path is None, just ignore this
@ -139,7 +139,7 @@ def context_path_validate(context, data_path):
else:
# Print invalid path, but don't show error to the users and fully
# break the UI if the operator is bound to an event like left click.
print("context_path_validate error: context.{!s} not found (invalid keymap entry?)".format(data_path))
print("context_path_validate error: context.{:s} not found (invalid keymap entry?)".format(data_path))
value = Ellipsis
return value
@ -208,9 +208,9 @@ def description_from_data_path(base, data_path, *, prefix, value=Ellipsis):
(rna_prop := context_path_to_rna_property(base, data_path)) and
(description := iface_(rna_prop.description))
):
description = iface_("{!s}: {!s}").format(prefix, description)
description = iface_("{:s}: {:s}").format(prefix, description)
if value != Ellipsis:
description = "{!s}\n{!s}: {!s}".format(description, iface_("Value"), str(value))
description = "{:s}\n{:s}: {:s}".format(description, iface_("Value"), str(value))
return description
return None
@ -265,9 +265,9 @@ def execute_context_assign(self, context):
return {'PASS_THROUGH'}
if getattr(self, "relative", False):
exec("context.{!s} += self.value".format(data_path))
exec("context.{:s} += self.value".format(data_path))
else:
exec("context.{!s} = self.value".format(data_path))
exec("context.{:s} = self.value".format(data_path))
return operator_path_undo_return(context, data_path)
@ -340,7 +340,7 @@ class WM_OT_context_scale_float(Operator):
if value == 1.0: # nothing to do
return {'CANCELLED'}
exec("context.{!s} *= value".format(data_path))
exec("context.{:s} *= value".format(data_path))
return operator_path_undo_return(context, data_path)
@ -385,11 +385,11 @@ class WM_OT_context_scale_int(Operator):
else:
add = "-1"
func = "min"
exec("context.{!s} = {!s}(round(context.{!s} * value), context.{!s} + {!s})".format(
exec("context.{:s} = {:s}(round(context.{:s} * value), context.{:s} + {:s})".format(
data_path, func, data_path, data_path, add,
))
else:
exec("context.{!s} *= value".format(data_path))
exec("context.{:s} *= value".format(data_path))
return operator_path_undo_return(context, data_path)
@ -476,7 +476,7 @@ class WM_OT_context_set_value(Operator):
data_path = self.data_path
if context_path_validate(context, data_path) is Ellipsis:
return {'PASS_THROUGH'}
exec("context.{!s} = {!s}".format(data_path, self.value))
exec("context.{:s} = {:s}".format(data_path, self.value))
return operator_path_undo_return(context, data_path)
@ -509,7 +509,7 @@ class WM_OT_context_toggle(Operator):
if context_path_validate(base, data_path) is Ellipsis:
return {'PASS_THROUGH'}
exec("base.{!s} = not (base.{!s})".format(data_path, data_path))
exec("base.{:s} = not (base.{:s})".format(data_path, data_path))
return operator_path_undo_return(base, data_path)
@ -547,7 +547,7 @@ class WM_OT_context_toggle_enum(Operator):
# keys that some values that are only available in a particular context
try:
exec(
"context.{!s} = {!r} if (context.{!s} != {!r}) else {!r}".format(
"context.{:s} = {!r} if (context.{:s} != {!r}) else {!r}".format(
data_path,
self.value_2,
data_path,
@ -587,17 +587,17 @@ class WM_OT_context_cycle_int(Operator):
else:
value += 1
exec("context.{!s} = value".format(data_path))
exec("context.{:s} = value".format(data_path))
if self.wrap:
if value != eval("context.{!s}".format(data_path)):
if value != eval("context.{:s}".format(data_path)):
# relies on rna clamping integers out of the range
if self.reverse:
value = (1 << 31) - 1
else:
value = -1 << 31
exec("context.{!s} = value".format(data_path))
exec("context.{:s} = value".format(data_path))
return operator_path_undo_return(context, data_path)
@ -647,7 +647,7 @@ class WM_OT_context_cycle_enum(Operator):
advance_enum = enums[orig_index + 1]
# set the new value
exec("context.{!s} = advance_enum".format(data_path))
exec("context.{:s} = advance_enum".format(data_path))
return operator_path_undo_return(context, data_path)
@ -678,7 +678,7 @@ class WM_OT_context_cycle_array(Operator):
array.append(array.pop(0))
return array
exec("context.{!s} = cycle(context.{!s}[:])".format(data_path, data_path))
exec("context.{:s} = cycle(context.{:s}[:])".format(data_path, data_path))
return operator_path_undo_return(context, data_path)
@ -780,7 +780,7 @@ class WM_OT_operator_pie_enum(Operator):
try:
op_rna = op.get_rna_type()
except KeyError:
self.report({'ERROR'}, rpt_("Operator not found: bpy.ops.{!s}").format(data_path))
self.report({'ERROR'}, rpt_("Operator not found: bpy.ops.{:s}").format(data_path))
return {'CANCELLED'}
def draw_cb(self, context):
@ -826,7 +826,7 @@ class WM_OT_context_set_id(Operator):
if id_iter:
value_id = getattr(bpy.data, id_iter).get(value)
exec("context.{!s} = value_id".format(data_path))
exec("context.{:s} = value_id".format(data_path))
return operator_path_undo_return(context, data_path)
@ -882,7 +882,7 @@ class WM_OT_context_collection_boolean_set(Operator):
else:
self.report(
{'WARNING'},
rpt_("Non boolean value found: {!s}[ ].{!s}").format(data_path_iter, data_path_item),
rpt_("Non boolean value found: {:s}[ ].{:s}").format(data_path_iter, data_path_item),
)
return {'CANCELLED'}
@ -899,7 +899,7 @@ class WM_OT_context_collection_boolean_set(Operator):
else:
is_set = not is_set
exec_str = "item.{!s} = {!s}".format(data_path_item, is_set)
exec_str = "item.{:s} = {:s}".format(data_path_item, str(is_set))
for item in items_ok:
exec(exec_str)
@ -945,7 +945,7 @@ class WM_OT_context_modal_mouse(Operator):
# check this can be set, maybe this is library data.
try:
exec("item.{!s} = {!s}".format(data_path_item, value_orig))
exec("item.{:s} = {:s}".format(data_path_item, str(value_orig)))
except BaseException:
continue
@ -959,14 +959,14 @@ class WM_OT_context_modal_mouse(Operator):
data_path_item = self.data_path_item
for item, value_orig in self._values.items():
if type(value_orig) == int:
exec("item.{!s} = int({:d})".format(data_path_item, round(value_orig + delta)))
exec("item.{:s} = int({:d})".format(data_path_item, round(value_orig + delta)))
else:
exec("item.{!s} = {:f}".format(data_path_item, value_orig + delta))
exec("item.{:s} = {:f}".format(data_path_item, value_orig + delta))
def _values_restore(self):
data_path_item = self.data_path_item
for item, value_orig in self._values.items():
exec("item.{!s} = {!s}".format(data_path_item, value_orig))
exec("item.{:s} = {:s}".format(data_path_item, str(value_orig)))
self._values.clear()
@ -983,7 +983,7 @@ class WM_OT_context_modal_mouse(Operator):
if header_text:
if len(self._values) == 1:
(item, ) = self._values.keys()
header_text = header_text % eval("item.{!s}".format(self.data_path_item))
header_text = header_text % eval("item.{:s}".format(self.data_path_item))
else:
header_text = (self.header_text % delta) + rpt_(" (delta)")
context.area.header_text_set(header_text)
@ -1007,7 +1007,7 @@ class WM_OT_context_modal_mouse(Operator):
if not self._values:
self.report(
{'WARNING'},
rpt_("Nothing to operate on: {!s}[ ].{!s}").format(
rpt_("Nothing to operate on: {:s}[ ].{:s}").format(
self.data_path_iter, self.data_path_item,
),
)
@ -1100,7 +1100,7 @@ class WM_OT_url_open_preset(Operator):
return "https://www.blender.org/download/releases/{:d}-{:d}/".format(*bpy.app.version[:2])
def _url_from_manual(self, _context):
return "https://docs.blender.org/manual/{!s}/{:d}.{:d}/".format(
return "https://docs.blender.org/manual/{:s}/{:d}.{:d}/".format(
bpy.utils.manual_language_code(), *bpy.app.version[:2],
)
@ -1177,7 +1177,7 @@ class WM_OT_path_open(Operator):
filepath = os.path.normpath(filepath)
if not os.path.exists(filepath):
self.report({'ERROR'}, rpt_("File '{!s}' not found").format(filepath))
self.report({'ERROR'}, rpt_("File '{:s}' not found").format(filepath))
return {'CANCELLED'}
if sys.platform[:3] == "win":
@ -1210,9 +1210,9 @@ def _wm_doc_get_id(doc_id, *, do_url=True, url_prefix="", report=None):
if len(id_split) == 1: # rna, class
if do_url:
url = "{!s}/bpy.types.{!s}.html".format(url_prefix, id_split[0])
url = "{:s}/bpy.types.{:s}.html".format(url_prefix, id_split[0])
else:
rna = "bpy.types.{!s}".format(id_split[0])
rna = "bpy.types.{:s}".format(id_split[0])
elif len(id_split) == 2: # rna, class.prop
class_name, class_prop = id_split
@ -1220,17 +1220,17 @@ def _wm_doc_get_id(doc_id, *, do_url=True, url_prefix="", report=None):
# an operator (common case - just button referencing an op)
if operator_exists_pair(class_name, class_prop):
if do_url:
url = "{!s}/bpy.ops.{!s}.html#bpy.ops.{!s}.{!s}".format(url_prefix, class_name, class_name, class_prop)
url = "{:s}/bpy.ops.{:s}.html#bpy.ops.{:s}.{:s}".format(url_prefix, class_name, class_name, class_prop)
else:
rna = "bpy.ops.{!s}.{!s}".format(class_name, class_prop)
rna = "bpy.ops.{:s}.{:s}".format(class_name, class_prop)
elif operator_exists_single(class_name):
# note: ignore the prop name since we don't have a way to link into it
class_name, class_prop = class_name.split("_OT_", 1)
class_name = class_name.lower()
if do_url:
url = "{!s}/bpy.ops.{!s}.html#bpy.ops.{!s}.{!s}".format(url_prefix, class_name, class_name, class_prop)
url = "{:s}/bpy.ops.{:s}.html#bpy.ops.{:s}.{:s}".format(url_prefix, class_name, class_name, class_prop)
else:
rna = "bpy.ops.{!s}.{!s}".format(class_name, class_prop)
rna = "bpy.ops.{:s}.{:s}".format(class_name, class_prop)
else:
# An RNA setting, common case.
@ -1242,7 +1242,7 @@ def _wm_doc_get_id(doc_id, *, do_url=True, url_prefix="", report=None):
if rna_class is None:
if report is not None:
report({'ERROR'}, rpt_("Type \"{!s}\" cannot be found").format(class_name))
report({'ERROR'}, rpt_("Type \"{:s}\" cannot be found").format(class_name))
return None
# Detect if this is a inherited member and use that name instead.
@ -1255,15 +1255,15 @@ def _wm_doc_get_id(doc_id, *, do_url=True, url_prefix="", report=None):
rna_parent = rna_parent.base
if do_url:
url = "{!s}/bpy.types.{!s}.html#bpy.types.{!s}.{!s}".format(
url = "{:s}/bpy.types.{:s}.html#bpy.types.{:s}.{:s}".format(
url_prefix, class_name, class_name, class_prop,
)
else:
rna = "bpy.types.{!s}.{!s}".format(class_name, class_prop)
rna = "bpy.types.{:s}.{:s}".format(class_name, class_prop)
else:
# We assume this is custom property, only try to generate generic url/rna_id...
if do_url:
url = ("{!s}/bpy.types.bpy_struct.html#bpy.types.bpy_struct.items".format(url_prefix))
url = ("{:s}/bpy.types.bpy_struct.html#bpy.types.bpy_struct.items".format(url_prefix))
else:
rna = "bpy.types.bpy_struct"
@ -1280,7 +1280,7 @@ class WM_OT_doc_view_manual(Operator):
@staticmethod
def _find_reference(rna_id, url_mapping, *, verbose=True):
if verbose:
print("online manual check for: '{!s}'... ".format(rna_id))
print("online manual check for: '{:s}'... ".format(rna_id))
from fnmatch import fnmatchcase
# XXX, for some reason all RNA ID's are stored lowercase
# Adding case into all ID's isn't worth the hassle so force lowercase.
@ -1312,7 +1312,7 @@ class WM_OT_doc_view_manual(Operator):
if fnmatchcase(rna_id, pattern):
if verbose:
print(" match found: '{!s}' --> '{!s}'".format(pattern, url_suffix))
print(" match found: '{:s}' --> '{:s}'".format(pattern, url_suffix))
return url_suffix
if verbose:
print("match not found")
@ -1703,7 +1703,7 @@ class WM_OT_properties_edit(Operator):
self._init_subtype(self.subtype)
escaped_name = bpy.utils.escape_identifier(name)
self.is_overridable_library = bool(item.is_property_overridable_library('["{!s}"]'.format(escaped_name)))
self.is_overridable_library = bool(item.is_property_overridable_library('["{:s}"]'.format(escaped_name)))
# When the operator chooses a different type than the original property,
# attempt to convert the old value to the new type for continuity and speed.
@ -1807,7 +1807,7 @@ class WM_OT_properties_edit(Operator):
)
escaped_name = bpy.utils.escape_identifier(name)
item.property_overridable_library_set('["{!s}"]'.format(escaped_name), self.is_overridable_library)
item.property_overridable_library_set('["{:s}"]'.format(escaped_name), self.is_overridable_library)
def _update_blender_for_prop_change(self, context, item, name, prop_type_old, prop_type_new):
from rna_prop_ui import (
@ -1819,7 +1819,7 @@ class WM_OT_properties_edit(Operator):
# If we have changed the type of the property, update its potential anim curves!
if prop_type_old != prop_type_new:
escaped_name = bpy.utils.escape_identifier(name)
data_path = '["{!s}"]'.format(escaped_name)
data_path = '["{:s}"]'.format(escaped_name)
done = set()
def _update(fcurves):
@ -1859,7 +1859,7 @@ class WM_OT_properties_edit(Operator):
data_path = self.data_path
name = self.property_name
item = eval("context.{!s}".format(data_path))
item = eval("context.{:s}".format(data_path))
if (item.id_data and item.id_data.override_library and item.id_data.override_library.reference):
self.report({'ERROR'}, "Cannot edit properties from override data")
return {'CANCELLED'}
@ -1905,7 +1905,7 @@ class WM_OT_properties_edit(Operator):
self._old_prop_name = [name]
item = eval("context.{!s}".format(data_path))
item = eval("context.{:s}".format(data_path))
if (item.id_data and item.id_data.override_library and item.id_data.override_library.reference):
self.report({'ERROR'}, "Properties from override data cannot be edited")
return {'CANCELLED'}
@ -2071,7 +2071,7 @@ class WM_OT_properties_edit_value(Operator):
def execute(self, context):
if self.eval_string:
rna_item = eval("context.{!s}".format(self.data_path))
rna_item = eval("context.{:s}".format(self.data_path))
try:
new_value = eval(self.eval_string)
except BaseException as ex:
@ -2081,7 +2081,7 @@ class WM_OT_properties_edit_value(Operator):
return {'FINISHED'}
def invoke(self, context, _event):
rna_item = eval("context.{!s}".format(self.data_path))
rna_item = eval("context.{:s}".format(self.data_path))
if WM_OT_properties_edit.get_property_type(rna_item, self.property_name) == 'PYTHON':
self.eval_string = WM_OT_properties_edit.convert_custom_property_to_string(rna_item, self.property_name)
@ -2094,14 +2094,14 @@ class WM_OT_properties_edit_value(Operator):
def draw(self, context):
from bpy.utils import escape_identifier
rna_item = eval("context.{!s}".format(self.data_path))
rna_item = eval("context.{:s}".format(self.data_path))
layout = self.layout
if WM_OT_properties_edit.get_property_type(rna_item, self.property_name) == 'PYTHON':
layout.prop(self, "eval_string")
else:
col = layout.column(align=True)
col.prop(rna_item, '["{!s}"]'.format(escape_identifier(self.property_name)), text="")
col.prop(rna_item, '["{:s}"]'.format(escape_identifier(self.property_name)), text="")
class WM_OT_properties_add(Operator):
@ -2118,7 +2118,7 @@ class WM_OT_properties_add(Operator):
)
data_path = self.data_path
item = eval("context.{!s}".format(data_path))
item = eval("context.{:s}".format(data_path))
if (item.id_data and item.id_data.override_library and item.id_data.override_library.reference):
self.report({'ERROR'}, "Cannot add properties to override data")
@ -2174,7 +2174,7 @@ class WM_OT_properties_remove(Operator):
rna_idprop_ui_prop_update,
)
data_path = self.data_path
item = eval("context.{!s}".format(data_path))
item = eval("context.{:s}".format(data_path))
if (item.id_data and item.id_data.override_library and item.id_data.override_library.reference):
self.report({'ERROR'}, "Cannot remove properties from override data")
@ -2964,7 +2964,7 @@ class WM_OT_batch_rename(Operator):
elif ty == 'STRIP':
chars = action.strip_chars
chars_strip = (
"{!s}{!s}{!s}"
"{:s}{:s}{:s}"
).format(
string.punctuation if 'PUNCT' in chars else "",
string.digits if 'DIGIT' in chars else "",
@ -3142,7 +3142,7 @@ class WM_OT_batch_rename(Operator):
row.prop(action, "op_remove", text="", icon='REMOVE')
row.prop(action, "op_add", text="", icon='ADD')
layout.label(text=iface_("Rename {:d} {!s}").format(len(self._data[0]), self._data[2]), translate=False)
layout.label(text=iface_("Rename {:d} {:s}").format(len(self._data[0]), self._data[2]), translate=False)
def check(self, context):
changed = False
@ -3203,7 +3203,7 @@ class WM_OT_batch_rename(Operator):
change_len += 1
total_len += 1
self.report({'INFO'}, rpt_("Renamed {:d} of {:d} {!s}").format(change_len, total_len, descr))
self.report({'INFO'}, rpt_("Renamed {:d} of {:d} {:s}").format(change_len, total_len, descr))
return {'FINISHED'}
@ -3365,22 +3365,22 @@ class WM_MT_splash_about(Menu):
col = split.column(align=True)
col.scale_y = 0.8
col.label(text=iface_("Version: {!s}").format(bpy.app.version_string), translate=False)
col.label(text=iface_("Version: {:s}").format(bpy.app.version_string), translate=False)
col.separator(factor=2.5)
col.label(text=iface_("Date: {!s} {!s}").format(
col.label(text=iface_("Date: {:s} {:s}").format(
bpy.app.build_commit_date.decode("utf-8", "replace"),
bpy.app.build_commit_time.decode("utf-8", "replace")),
translate=False
)
col.label(text=iface_("Hash: {!s}").format(bpy.app.build_hash.decode("ascii")), translate=False)
col.label(text=iface_("Branch: {!s}").format(bpy.app.build_branch.decode("utf-8", "replace")), translate=False)
col.label(text=iface_("Hash: {:s}").format(bpy.app.build_hash.decode("ascii")), translate=False)
col.label(text=iface_("Branch: {:s}").format(bpy.app.build_branch.decode("utf-8", "replace")), translate=False)
# This isn't useful information on MS-Windows or Apple systems as dynamically switching
# between windowing systems is only supported between X11/WAYLAND.
from _bpy import _ghost_backend
ghost_backend = _ghost_backend()
if ghost_backend not in {'NONE', 'DEFAULT'}:
col.label(text=iface_("Windowing Environment: {!s}").format(_ghost_backend()), translate=False)
col.label(text=iface_("Windowing Environment: {:s}").format(_ghost_backend()), translate=False)
del _ghost_backend, ghost_backend
col.separator(factor=2.0)
@ -3450,7 +3450,7 @@ class WM_MT_region_toggle_pie(Menu):
assert hasattr(space_data, attr)
# Technically possible these double-up, in practice this should never happen.
if region_type in region_by_type:
print("{!s}: Unexpected double-up of region types {!r}".format(cls.__name__, region_type))
print("{:s}: Unexpected double-up of region types {!r}".format(cls.__name__, region_type))
region_by_type[region_type] = region
# Axis aligned pie menu items to populate.

@ -517,7 +517,7 @@ class MESH_UL_attributes(UIList):
sub.alignment = 'RIGHT'
sub.active = False
sub.label(
text="{!s}{!s}".format(iface_(domain_name), iface_(data_type.name)),
text="{:s}{:s}".format(iface_(domain_name), iface_(data_type.name)),
translate=False,
)
@ -639,7 +639,7 @@ class MESH_UL_color_attributes(UIList, ColorAttributesListBase):
sub = split.row()
sub.alignment = 'RIGHT'
sub.active = False
sub.label(text="{!s}{!s}".format(iface_(domain_name), iface_(data_type.name)), translate=False)
sub.label(text="{:s}{:s}".format(iface_(domain_name), iface_(data_type.name)), translate=False)
active_render = _index == data.color_attributes.render_color_index

@ -500,7 +500,7 @@ class AnnotationDataPanel:
if gpl.active_frame:
lock_status = iface_("Locked") if gpl.lock_frame else iface_("Unlocked")
lock_label = iface_("Frame: {:d} ({!s})").format(gpl.active_frame.frame_number, lock_status)
lock_label = iface_("Frame: {:d} ({:s})").format(gpl.active_frame.frame_number, lock_status)
else:
lock_label = iface_("Lock Frame")
row.prop(gpl, "lock_frame", text=lock_label, icon='UNLOCKED')

@ -96,7 +96,7 @@ class WORKSPACE_UL_addons_items(UIList):
if not module:
return addon.module
bl_info = addon_utils.module_bl_info(module)
return "{!s}: {!s}".format(iface_(bl_info["category"]), iface_(bl_info["name"]))
return "{:s}: {:s}".format(iface_(bl_info["category"]), iface_(bl_info["name"]))
@staticmethod
def _filter_addons_by_category_name(pattern, bitflag, addons, reverse=False):

@ -67,12 +67,12 @@ class TEXT_HT_footer(Header):
if text.filepath:
if text.is_dirty:
row.label(
text=iface_("File: *{!s} (unsaved)").format(text.filepath),
text=iface_("File: *{:s} (unsaved)").format(text.filepath),
translate=False,
)
else:
row.label(
text=iface_("File: {!s}").format(text.filepath),
text=iface_("File: {:s}").format(text.filepath),
translate=False,
)
else:

@ -486,7 +486,7 @@ class ToolSelectPanelHelper:
@classmethod
def _km_action_simple(cls, kc_default, kc, context_descr, label, keymap_fn):
km_idname = "{!s} {!s}, {!s}".format(cls.keymap_prefix, context_descr, label)
km_idname = "{:s} {:s}, {:s}".format(cls.keymap_prefix, context_descr, label)
km = kc.keymaps.get(km_idname)
km_kwargs = dict(space_type=cls.bl_space_type, region_type='WINDOW', tool=True)
if km is None:

@ -135,9 +135,9 @@ class _defs_view3d_generic:
kmi_remove = None
return tip_(
"Measure distance and angles.\n"
"\u2022 {!s} anywhere for new measurement.\n"
"\u2022 {:s} anywhere for new measurement.\n"
"\u2022 Drag ruler segment to measure an angle.\n"
"\u2022 {!s} to remove the active ruler.\n"
"\u2022 {:s} to remove the active ruler.\n"
"\u2022 Ctrl while dragging to snap.\n"
"\u2022 Shift while dragging to measure surface thickness"
).format(
@ -506,10 +506,10 @@ class _defs_view3d_add:
kmi_center = None
kmi_fixed_aspect = None
return tip_(
"{!s}\n"
"\u2022 {!s} toggles snap while dragging.\n"
"\u2022 {!s} toggles dragging from the center.\n"
"\u2022 {!s} toggles fixed aspect"
"{:s}\n"
"\u2022 {:s} toggles snap while dragging.\n"
"\u2022 {:s} toggles dragging from the center.\n"
"\u2022 {:s} toggles fixed aspect"
).format(
prefix,
kmi_to_string_or_none(kmi_snap),
@ -779,9 +779,9 @@ class _defs_edit_mesh:
kmi_delete = None
return tip_(
"Use multiple operators in an interactive way to add, delete, or move geometry.\n"
"\u2022 {!s} - Add geometry by moving the cursor close to an element.\n"
"\u2022 {!s} - Extrude edges by moving the cursor.\n"
"\u2022 {!s} - Delete mesh element"
"\u2022 {:s} - Add geometry by moving the cursor close to an element.\n"
"\u2022 {:s} - Extrude edges by moving the cursor.\n"
"\u2022 {:s} - Delete mesh element"
).format(
kmi_to_string_or_none(kmi_add),
kmi_to_string_or_none(kmi_extrude),

@ -378,7 +378,7 @@ class TOPBAR_MT_file_defaults(Menu):
props = layout.operator("wm.read_factory_settings", text="Load Factory Blender Settings")
props.app_template = app_template
props = layout.operator("wm.read_factory_settings",
text=iface_("Load Factory {!s} Settings",
text=iface_("Load Factory {:s} Settings",
i18n_contexts.operator_default).format(display_name),
translate=False)
props.app_template = app_template

@ -123,7 +123,7 @@ class USERPREF_MT_save_load(Menu):
display_name = bpy.path.display_name(iface_(app_template))
layout.operator("wm.read_factory_userpref", text="Load Factory Blender Preferences")
props = layout.operator("wm.read_factory_userpref",
text=iface_("Load Factory {!s} Preferences").format(display_name),
text=iface_("Load Factory {:s} Preferences").format(display_name),
translate=False)
props.use_factory_startup_app_template_only = True
del display_name
@ -2367,7 +2367,7 @@ class USERPREF_PT_addons(AddOnPanel, Panel):
sub = row.row()
sub.active = is_enabled
sub.label(text="{!s}: {!s}".format(iface_(bl_info["category"]), iface_(bl_info["name"])))
sub.label(text="{:s}: {:s}".format(iface_(bl_info["category"]), iface_(bl_info["name"])))
if bl_info["warning"]:
sub.label(icon='ERROR')
@ -2424,8 +2424,8 @@ class USERPREF_PT_addons(AddOnPanel, Panel):
).url = bl_info["tracker_url"]
elif not user_addon:
addon_info = (
"Name: {!s} {!s}\n"
"Author: {!s}\n"
"Name: {:s} {:s}\n"
"Author: {:s}\n"
).format(bl_info["name"], str(bl_info["version"]), bl_info["author"])
props = sub.operator(
"wm.url_open_preset", text="Report a Bug", icon='URL',
@ -2506,7 +2506,7 @@ class StudioLightPanelMixin:
layout.label(text=self.get_error_message())
def get_error_message(self):
return rpt_("No custom {!s} configured").format(self.bl_label)
return rpt_("No custom {:s} configured").format(self.bl_label)
def draw_studio_light(self, layout, studio_light):
box = layout.box()

@ -1252,7 +1252,7 @@ class VIEW3D_MT_editor_menus(Menu):
elif mesh.use_paint_mask_vertex and mode_string in {'PAINT_WEIGHT', 'PAINT_VERTEX'}:
layout.menu("VIEW3D_MT_select_paint_mask_vertex")
elif mode_string not in {'SCULPT', 'SCULPT_CURVES', 'PAINT_GREASE_PENCIL', 'SCULPT_GREASE_PENCIL'}:
layout.menu("VIEW3D_MT_select_{!s}".format(mode_string.lower()))
layout.menu("VIEW3D_MT_select_{:s}".format(mode_string.lower()))
if gp_edit:
pass
@ -1284,7 +1284,7 @@ class VIEW3D_MT_editor_menus(Menu):
layout.menu("VIEW3D_MT_paint_gpencil")
elif edit_object:
layout.menu("VIEW3D_MT_edit_{!s}".format(edit_object.type.lower()))
layout.menu("VIEW3D_MT_edit_{:s}".format(edit_object.type.lower()))
if mode_string == 'EDIT_MESH':
layout.menu("VIEW3D_MT_edit_mesh_vertices")
@ -1305,7 +1305,7 @@ class VIEW3D_MT_editor_menus(Menu):
elif obj:
if mode_string not in {'PAINT_TEXTURE', 'SCULPT_CURVES', 'SCULPT_GREASE_PENCIL'}:
layout.menu("VIEW3D_MT_{!s}".format(mode_string.lower()))
layout.menu("VIEW3D_MT_{:s}".format(mode_string.lower()))
if mode_string == 'SCULPT':
layout.menu("VIEW3D_MT_mask")
layout.menu("VIEW3D_MT_face_sets")
@ -1335,9 +1335,9 @@ class ShowHideMenu:
def draw(self, _context):
layout = self.layout
layout.operator("{!s}.reveal".format(self._operator_name))
layout.operator("{!s}.hide".format(self._operator_name), text="Hide Selected").unselected = False
layout.operator("{!s}.hide".format(self._operator_name), text="Hide Unselected").unselected = True
layout.operator("{:s}.reveal".format(self._operator_name))
layout.operator("{:s}.hide".format(self._operator_name), text="Hide Selected").unselected = False
layout.operator("{:s}.hide".format(self._operator_name), text="Hide Unselected").unselected = True
# Standard transforms which apply to all cases (mix-in class, not used directly).
@ -1465,7 +1465,7 @@ class VIEW3D_MT_mirror(Menu):
for (space_name, space_id) in (("Global", 'GLOBAL'), ("Local", 'LOCAL')):
for axis_index, axis_name in enumerate("XYZ"):
props = layout.operator("transform.mirror",
text="{!s} {!s}".format(axis_name, iface_(space_name)),
text="{:s} {:s}".format(axis_name, iface_(space_name)),
translate=False)
props.constraint_axis[axis_index] = True
props.orient_type = space_id

@ -512,7 +512,7 @@ class WholeCharacterMixin:
# for now, just add all of 'em
prop_rna = type(bone).bl_rna.properties.get(prop, None)
if prop_rna is None:
prop_path = '["{!s}"]'.format(bpy.utils.escape_identifier(prop))
prop_path = '["{:s}"]'.format(bpy.utils.escape_identifier(prop))
try:
rna_property = bone.path_resolve(prop_path, False)
except ValueError: