Cleanup: pep8

This commit is contained in:
Campbell Barton 2021-07-06 12:05:27 +10:00
parent 36584bbc2d
commit 432bfbf7a3
48 changed files with 89 additions and 46 deletions

View File

@ -12,6 +12,7 @@ such cases, lock the interface (Render → Lock Interface or
Below is an example of a mesh that is altered from a handler: Below is an example of a mesh that is altered from a handler:
""" """
def frame_change_pre(scene): def frame_change_pre(scene):
# A triangle that shifts in the z direction # A triangle that shifts in the z direction
zshift = scene.frame_current * 0.1 zshift = scene.frame_current * 0.1

View File

@ -16,10 +16,12 @@ execution_queue = queue.Queue()
def run_in_main_thread(function): def run_in_main_thread(function):
execution_queue.put(function) execution_queue.put(function)
def execute_queued_functions(): def execute_queued_functions():
while not execution_queue.empty(): while not execution_queue.empty():
function = execution_queue.get() function = execution_queue.get()
function() function()
return 1.0 return 1.0
bpy.app.timers.register(execute_queued_functions) bpy.app.timers.register(execute_queued_functions)

View File

@ -31,11 +31,13 @@ owner = object()
subscribe_to = bpy.context.object.location subscribe_to = bpy.context.object.location
def msgbus_callback(*args): def msgbus_callback(*args):
# This will print: # This will print:
# Something changed! (1, 2, 3) # Something changed! (1, 2, 3)
print("Something changed!", args) print("Something changed!", args)
bpy.msgbus.subscribe_rna( bpy.msgbus.subscribe_rna(
key=subscribe_to, key=subscribe_to,
owner=owner, owner=owner,

View File

@ -44,7 +44,7 @@ class OBJECT_OT_object_to_curve(bpy.types.Operator):
# Remove temporary curve. # Remove temporary curve.
obj.to_curve_clear() obj.to_curve_clear()
# Invoke to_curve() with applying modifiers. # Invoke to_curve() with applying modifiers.
curve_with_modifiers = obj.to_curve(depsgraph, apply_modifiers = True) curve_with_modifiers = obj.to_curve(depsgraph, apply_modifiers=True)
self.report({'INFO'}, f"{len(curve_with_modifiers.splines)} splines in new curve with modifiers.") self.report({'INFO'}, f"{len(curve_with_modifiers.splines)} splines in new curve with modifiers.")
# Remove temporary curve. # Remove temporary curve.
obj.to_curve_clear() obj.to_curve_clear()

View File

@ -21,6 +21,7 @@ batch = batch_for_shader(
}, },
) )
def draw(): def draw():
shader.bind() shader.bind()
shader.uniform_sampler("image", texture) shader.uniform_sampler("image", texture)

View File

@ -781,7 +781,6 @@ class I18nMessages:
print("Could not import bpy, find_best_messages_matches must be run from whithin Blender.") print("Could not import bpy, find_best_messages_matches must be run from whithin Blender.")
return return
# Build helper mappings. # Build helper mappings.
# Note it's user responsibility to know when to invalidate (and hence force rebuild) this cache! # Note it's user responsibility to know when to invalidate (and hence force rebuild) this cache!
if self._reverse_cache is None: if self._reverse_cache is None:

View File

@ -140,6 +140,7 @@ def main():
args.func(args=args, settings=settings) args.func(args=args, settings=settings)
if __name__ == "__main__": if __name__ == "__main__":
print("\n\n *** Running {} *** \n".format(__file__)) print("\n\n *** Running {} *** \n".format(__file__))
main() main()

View File

@ -449,6 +449,5 @@ def generate(context, space_type, *, use_fallback_keys=True, use_reset=True):
) )
kmi.properties.skip_depressed = True kmi.properties.skip_depressed = True
wm.keyconfigs.update() wm.keyconfigs.update()
return keymap return keymap

View File

@ -37,6 +37,7 @@ OBJECT_TYPES_RENDER = {'MESH', 'CURVE', 'SURFACE', 'META', 'FONT'}
def ids_nolib(bids): def ids_nolib(bids):
return (bid for bid in bids if not bid.library) return (bid for bid in bids if not bid.library)
def ids_nolib_with_preview(bids): def ids_nolib_with_preview(bids):
return (bid for bid in bids if (not bid.library and bid.preview)) return (bid for bid in bids if (not bid.library and bid.preview))

View File

@ -23,6 +23,7 @@ __all__ = (
"decompose_data_path", "decompose_data_path",
) )
class _TokenizeDataPath: class _TokenizeDataPath:
""" """
Class to split up tokens of a data-path. Class to split up tokens of a data-path.

View File

@ -155,6 +155,7 @@ def _test_import(module_name, loaded_modules):
# This supports the case of loading a new preferences file which may reset scripts path. # This supports the case of loading a new preferences file which may reset scripts path.
_sys_path_ensure_paths = set() _sys_path_ensure_paths = set()
def _sys_path_ensure_prepend(path): def _sys_path_ensure_prepend(path):
if path not in _sys.path: if path not in _sys.path:
_sys.path.insert(0, path) _sys.path.insert(0, path)

View File

@ -31,6 +31,7 @@ __all__ = (
"SpaceAssetInfo", "SpaceAssetInfo",
) )
class SpaceAssetInfo: class SpaceAssetInfo:
@classmethod @classmethod
def is_asset_browser(cls, space_data: bpy.types.Space): def is_asset_browser(cls, space_data: bpy.types.Space):
@ -46,6 +47,7 @@ class SpaceAssetInfo:
active_file = context.active_file active_file = context.active_file
return active_file.asset_data if active_file else None return active_file.asset_data if active_file else None
class AssetBrowserPanel: class AssetBrowserPanel:
bl_space_type = 'FILE_BROWSER' bl_space_type = 'FILE_BROWSER'
@ -53,6 +55,7 @@ class AssetBrowserPanel:
def poll(cls, context): def poll(cls, context):
return SpaceAssetInfo.is_asset_browser_poll(context) return SpaceAssetInfo.is_asset_browser_poll(context)
class AssetMetaDataPanel: class AssetMetaDataPanel:
bl_space_type = 'FILE_BROWSER' bl_space_type = 'FILE_BROWSER'
bl_region_type = 'TOOL_PROPS' bl_region_type = 'TOOL_PROPS'

View File

@ -681,7 +681,10 @@ class ShaderImageTextureWrapper():
tree = self.owner_shader.material.node_tree tree = self.owner_shader.material.node_tree
node_image = tree.nodes.new(type='ShaderNodeTexImage') node_image = tree.nodes.new(type='ShaderNodeTexImage')
self.owner_shader._grid_to_location(-1, 0 + self.grid_row_diff, dst_node=node_image, ref_node=self.node_dst) self.owner_shader._grid_to_location(
-1, 0 + self.grid_row_diff,
dst_node=node_image, ref_node=self.node_dst,
)
tree.links.new(node_image.outputs["Alpha" if self.use_alpha else "Color"], self.socket_dst) tree.links.new(node_image.outputs["Alpha" if self.use_alpha else "Color"], self.socket_dst)
if self.use_alpha: if self.use_alpha:
@ -778,7 +781,7 @@ class ShaderImageTextureWrapper():
socket_dst = self.node_image.inputs["Vector"] socket_dst = self.node_image.inputs["Vector"]
# If not already existing, we need to create texcoords -> mapping link (from UV). # If not already existing, we need to create texcoords -> mapping link (from UV).
socket_src = (socket_dst.links[0].from_socket if socket_dst.is_linked socket_src = (socket_dst.links[0].from_socket if socket_dst.is_linked
else self.owner_shader.node_texcoords.outputs['UV']) else self.owner_shader.node_texcoords.outputs['UV'])
tree = self.owner_shader.material.node_tree tree = self.owner_shader.material.node_tree
node_mapping = tree.nodes.new(type='ShaderNodeMapping') node_mapping = tree.nodes.new(type='ShaderNodeMapping')

View File

@ -41,7 +41,7 @@ RE_DEF_COMPLETE = re.compile(
# allow empty string # allow empty string
'''|)''' '''|)'''
# allow opening bracket(s) # allow opening bracket(s)
'''(?:\(|\s)*)$''') r'''(?:\(|\s)*)$''')
def reduce_newlines(text): def reduce_newlines(text):

View File

@ -20,6 +20,7 @@ from __future__ import annotations
from bpy.types import Operator from bpy.types import Operator
class SPREADSHEET_OT_toggle_pin(Operator): class SPREADSHEET_OT_toggle_pin(Operator):
'''Turn on or off pinning''' '''Turn on or off pinning'''
bl_idname = "spreadsheet.toggle_pin" bl_idname = "spreadsheet.toggle_pin"

View File

@ -135,7 +135,7 @@ def context_path_decompose(data_path):
if base_path: if base_path:
assert(base_path.startswith(".")) assert(base_path.startswith("."))
base_path= base_path[1:] base_path = base_path[1:]
if prop_attr: if prop_attr:
assert(prop_attr.startswith(".")) assert(prop_attr.startswith("."))
prop_attr = prop_attr[1:] prop_attr = prop_attr[1:]

View File

@ -35,7 +35,7 @@ def lineart_make_line_type_entry(col, line_type, text_disp, expand, search_from)
if line_type.use and expand: if line_type.use and expand:
col.prop_search(line_type, "layer", search_from, col.prop_search(line_type, "layer", search_from,
"layers", icon='GREASEPENCIL') "layers", icon='GREASEPENCIL')
col.prop_search(line_type, "material", search_from, col.prop_search(line_type, "material", search_from,
"materials", icon='SHADING_TEXTURE') "materials", icon='SHADING_TEXTURE')
@ -90,7 +90,7 @@ class COLLECTION_PT_lineart_collection(CollectionButtonsPanel, Panel):
row = layout.row(align=True, heading="Masks") row = layout.row(align=True, heading="Masks")
row.active = collection.lineart_use_intersection_mask row.active = collection.lineart_use_intersection_mask
for i in range(0,8): for i in range(8):
row.prop(collection, "lineart_intersection_mask", index=i, text=str(i), toggle=True) row.prop(collection, "lineart_intersection_mask", index=i, text=str(i), toggle=True)

View File

@ -93,8 +93,8 @@ class GPENCIL_MT_layer_context_menu(Menu):
gpd = ob.data gpd = ob.data
gpl = gpd.layers.active gpl = gpd.layers.active
layout.operator("gpencil.layer_duplicate", text="Duplicate", icon='DUPLICATE').mode='ALL' layout.operator("gpencil.layer_duplicate", text="Duplicate", icon='DUPLICATE').mode = 'ALL'
layout.operator("gpencil.layer_duplicate", text="Duplicate Empty Keyframes").mode='EMPTY' layout.operator("gpencil.layer_duplicate", text="Duplicate Empty Keyframes").mode = 'EMPTY'
layout.separator() layout.separator()
@ -113,8 +113,8 @@ class GPENCIL_MT_layer_context_menu(Menu):
layout.operator("gpencil.layer_merge", icon='SORT_ASC', text="Merge Down") layout.operator("gpencil.layer_merge", icon='SORT_ASC', text="Merge Down")
layout.separator() layout.separator()
layout.operator("gpencil.layer_duplicate_object", text="Copy Layer to Selected").only_active=True layout.operator("gpencil.layer_duplicate_object", text="Copy Layer to Selected").only_active = True
layout.operator("gpencil.layer_duplicate_object", text="Copy All Layers to Selected").only_active=False layout.operator("gpencil.layer_duplicate_object", text="Copy All Layers to Selected").only_active = False
class DATA_PT_gpencil_layers(DataButtonsPanel, Panel): class DATA_PT_gpencil_layers(DataButtonsPanel, Panel):

View File

@ -847,6 +847,7 @@ class GreasePencilLayerRelationsPanel:
col.enabled = bool(gpl.viewlayer_render) col.enabled = bool(gpl.viewlayer_render)
col.prop(gpl, "use_viewlayer_masks") col.prop(gpl, "use_viewlayer_masks")
class GreasePencilLayerDisplayPanel: class GreasePencilLayerDisplayPanel:
def draw(self, context): def draw(self, context):

View File

@ -1477,9 +1477,13 @@ class CLIP_MT_track(Menu):
layout.separator() layout.separator()
layout.operator("clip.solve_camera", layout.operator(
text="Solve Camera Motion" if tracking_object.is_camera "clip.solve_camera",
else "Solve Object Motion") text=(
"Solve Camera Motion" if tracking_object.is_camera else
"Solve Object Motion"
),
)
layout.separator() layout.separator()

View File

@ -609,9 +609,9 @@ class DOPESHEET_MT_context_menu(Menu):
layout.operator_menu_enum("action.keyframe_type", "type", text="Keyframe Type") layout.operator_menu_enum("action.keyframe_type", "type", text="Keyframe Type")
if st.mode != 'GPENCIL': if st.mode != 'GPENCIL':
layout.operator_menu_enum("action.handle_type", "type", text="Handle Type") layout.operator_menu_enum("action.handle_type", "type", text="Handle Type")
layout.operator_menu_enum("action.interpolation_type", "type", text="Interpolation Mode") layout.operator_menu_enum("action.interpolation_type", "type", text="Interpolation Mode")
layout.operator_menu_enum("action.easing_type", "type", text="Easing Mode") layout.operator_menu_enum("action.easing_type", "type", text="Easing Mode")
layout.separator() layout.separator()
@ -625,8 +625,8 @@ class DOPESHEET_MT_context_menu(Menu):
layout.operator("action.delete") layout.operator("action.delete")
if st.mode == 'GPENCIL': if st.mode == 'GPENCIL':
layout.operator("gpencil.interpolate_reverse") layout.operator("gpencil.interpolate_reverse")
layout.operator("gpencil.frame_clean_duplicate", text="Delete Duplicate Frames") layout.operator("gpencil.frame_clean_duplicate", text="Delete Duplicate Frames")
layout.separator() layout.separator()

View File

@ -260,6 +260,7 @@ class IMAGE_MT_image_flip(Menu):
layout.operator("image.flip", text="Horizontally").use_flip_x = True layout.operator("image.flip", text="Horizontally").use_flip_x = True
layout.operator("image.flip", text="Vertically").use_flip_y = True layout.operator("image.flip", text="Vertically").use_flip_y = True
class IMAGE_MT_image_invert(Menu): class IMAGE_MT_image_invert(Menu):
bl_label = "Invert" bl_label = "Invert"

View File

@ -442,7 +442,6 @@ class OUTLINER_PT_filter(Panel):
row.prop(space, "use_filter_lib_override_system", text="System Overrides") row.prop(space, "use_filter_lib_override_system", text="System Overrides")
classes = ( classes = (
OUTLINER_HT_header, OUTLINER_HT_header,
OUTLINER_MT_editor_menus, OUTLINER_MT_editor_menus,

View File

@ -400,7 +400,7 @@ class SEQUENCER_MT_view(Menu):
layout.menu("SEQUENCER_MT_proxy") layout.menu("SEQUENCER_MT_proxy")
layout.operator_context = 'INVOKE_DEFAULT' layout.operator_context = 'INVOKE_DEFAULT'
layout.separator() layout.separator()
layout.operator_context = 'INVOKE_REGION_WIN' layout.operator_context = 'INVOKE_REGION_WIN'
layout.operator("sequencer.refresh_all", icon='FILE_REFRESH', text="Refresh All") layout.operator("sequencer.refresh_all", icon='FILE_REFRESH', text="Refresh All")
@ -467,6 +467,7 @@ class SEQUENCER_MT_select_handle(Menu):
layout.operator("sequencer.select_handles", text="Left Neighbor").side = 'LEFT_NEIGHBOR' layout.operator("sequencer.select_handles", text="Left Neighbor").side = 'LEFT_NEIGHBOR'
layout.operator("sequencer.select_handles", text="Right Neighbor").side = 'RIGHT_NEIGHBOR' layout.operator("sequencer.select_handles", text="Right Neighbor").side = 'RIGHT_NEIGHBOR'
class SEQUENCER_MT_select_channel(Menu): class SEQUENCER_MT_select_channel(Menu):
bl_label = "Select Channel" bl_label = "Select Channel"
@ -1415,7 +1416,7 @@ class SEQUENCER_PT_source(SequencerButtonsPanel, Panel):
split.label(text="%dx%d" % size, translate=False) split.label(text="%dx%d" % size, translate=False)
else: else:
split.label(text="None") split.label(text="None")
#FPS # FPS
if elem.orig_fps: if elem.orig_fps:
split = col.split(factor=0.5, align=False) split = col.split(factor=0.5, align=False)
split.alignment = 'RIGHT' split.alignment = 'RIGHT'
@ -1424,7 +1425,6 @@ class SEQUENCER_PT_source(SequencerButtonsPanel, Panel):
split.label(text="%.2f" % elem.orig_fps, translate=False) split.label(text="%.2f" % elem.orig_fps, translate=False)
class SEQUENCER_PT_scene(SequencerButtonsPanel, Panel): class SEQUENCER_PT_scene(SequencerButtonsPanel, Panel):
bl_label = "Scene" bl_label = "Scene"
bl_category = "Strip" bl_category = "Strip"
@ -1857,7 +1857,7 @@ class SEQUENCER_PT_cache_settings(SequencerButtonsPanel, Panel):
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
show_developer_ui = context.preferences.view.show_developer_ui show_developer_ui = context.preferences.view.show_developer_ui
return cls.has_sequencer(context) and context.scene.sequence_editor and show_developer_ui return cls.has_sequencer(context) and context.scene.sequence_editor and show_developer_ui
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
@ -2286,12 +2286,12 @@ class SEQUENCER_PT_snapping(Panel):
layout.use_property_decorate = False layout.use_property_decorate = False
col = layout.column(heading="Snap to", align=True) col = layout.column(heading="Snap to", align=True)
col.prop(sequencer_tool_settings, "snap_to_current_frame" ) col.prop(sequencer_tool_settings, "snap_to_current_frame")
col.prop(sequencer_tool_settings, "snap_to_hold_offset") col.prop(sequencer_tool_settings, "snap_to_hold_offset")
col = layout.column(heading="Ignore", align=True) col = layout.column(heading="Ignore", align=True)
col.prop(sequencer_tool_settings, "snap_ignore_muted", text="Muted Strips") col.prop(sequencer_tool_settings, "snap_ignore_muted", text="Muted Strips")
col.prop(sequencer_tool_settings, "snap_ignore_sound",text="Sound Strips") col.prop(sequencer_tool_settings, "snap_ignore_sound", text="Sound Strips")
classes = ( classes = (

View File

@ -58,7 +58,7 @@ class SPREADSHEET_HT_header(bpy.types.Header):
layout.label(text="No active viewer node.", icon='INFO') layout.label(text="No active viewer node.", icon='INFO')
layout.separator_spacer() layout.separator_spacer()
row = layout.row(align=True) row = layout.row(align=True)
sub = row.row(align=True) sub = row.row(align=True)
sub.active = self.selection_filter_available(space) sub.active = self.selection_filter_available(space)
@ -115,6 +115,7 @@ class SPREADSHEET_HT_header(bpy.types.Header):
return False return False
return True return True
classes = ( classes = (
SPREADSHEET_HT_header, SPREADSHEET_HT_header,
) )

View File

@ -1391,7 +1391,6 @@ class USERPREF_PT_file_paths_asset_libraries(FilePathsPanel, Panel):
row.separator() row.separator()
row.label(text="Path") row.label(text="Path")
for i, library in enumerate(paths.asset_libraries): for i, library in enumerate(paths.asset_libraries):
name_col.prop(library, "name", text="") name_col.prop(library, "name", text="")
row = path_col.row() row = path_col.row()

View File

@ -3129,7 +3129,6 @@ class VIEW3D_MT_mask(Menu):
layout.menu("VIEW3D_MT_random_mask", text="Random Mask") layout.menu("VIEW3D_MT_random_mask", text="Random Mask")
class VIEW3D_MT_face_sets(Menu): class VIEW3D_MT_face_sets(Menu):
bl_label = "Face Sets" bl_label = "Face Sets"
@ -3259,6 +3258,7 @@ class VIEW3D_MT_random_mask(Menu):
op = layout.operator("sculpt.mask_init", text='Per Loose Part') op = layout.operator("sculpt.mask_init", text='Per Loose Part')
op.mode = 'RANDOM_PER_LOOSE_PART' op.mode = 'RANDOM_PER_LOOSE_PART'
class VIEW3D_MT_particle(Menu): class VIEW3D_MT_particle(Menu):
bl_label = "Particle" bl_label = "Particle"

View File

@ -1731,7 +1731,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_paint_falloff(GreasePencilBrushFalloff
from bl_ui.space_toolsystem_common import ToolSelectPanelHelper from bl_ui.space_toolsystem_common import ToolSelectPanelHelper
tool = ToolSelectPanelHelper.tool_active_from_context(context) tool = ToolSelectPanelHelper.tool_active_from_context(context)
if tool and tool.idname != 'builtin_brush.Tint': if tool and tool.idname != 'builtin_brush.Tint':
return False return False
gptool = brush.gpencil_tool gptool = brush.gpencil_tool
@ -2057,7 +2057,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_mixcolor(View3DPanel, Panel):
from bl_ui.space_toolsystem_common import ToolSelectPanelHelper from bl_ui.space_toolsystem_common import ToolSelectPanelHelper
tool = ToolSelectPanelHelper.tool_active_from_context(context) tool = ToolSelectPanelHelper.tool_active_from_context(context)
if tool and tool.idname in('builtin.cutter', 'builtin.eyedropper', 'builtin.interpolate'): if tool and tool.idname in {'builtin.cutter', 'builtin.eyedropper', 'builtin.interpolate'}:
return False return False
if brush.gpencil_tool == 'TINT': if brush.gpencil_tool == 'TINT':
@ -2118,7 +2118,7 @@ class VIEW3D_PT_tools_grease_pencil_brush_mix_palette(View3DPanel, Panel):
from bl_ui.space_toolsystem_common import ToolSelectPanelHelper from bl_ui.space_toolsystem_common import ToolSelectPanelHelper
tool = ToolSelectPanelHelper.tool_active_from_context(context) tool = ToolSelectPanelHelper.tool_active_from_context(context)
if tool and tool.idname in('builtin.cutter', 'builtin.eyedropper', 'builtin.interpolate'): if tool and tool.idname in {'builtin.cutter', 'builtin.eyedropper', 'builtin.interpolate'}:
return False return False
if brush.gpencil_tool == 'TINT': if brush.gpencil_tool == 'TINT':

View File

@ -383,6 +383,7 @@ class BUILTIN_KSI_Available(KeyingSetInfo):
############################### ###############################
class WholeCharacterMixin: class WholeCharacterMixin:
# these prefixes should be avoided, as they are not really bones # these prefixes should be avoided, as they are not really bones
# that animators should be touching (or need to touch) # that animators should be touching (or need to touch)

View File

@ -20,9 +20,9 @@ input_image.pixels.foreach_get(pixel_data.ravel())
# Do whatever image processing you want using numpy here: # Do whatever image processing you want using numpy here:
# Example 1: Inverse red green and blue channels. # Example 1: Inverse red green and blue channels.
pixel_data[:,:,:3] = 1.0 - pixel_data[:,:,:3] pixel_data[:, :, :3] = 1.0 - pixel_data[:, :, :3]
# Example 2: Change gamma on the red channel. # Example 2: Change gamma on the red channel.
pixel_data[:,:,0] = np.power(pixel_data[:,:,0], 1.5) pixel_data[:, :, 0] = np.power(pixel_data[:, :, 0], 1.5)
# Create output image. # Create output image.
if output_image_name in bpy.data.images: if output_image_name in bpy.data.images:

View File

@ -6,6 +6,7 @@ from bpy.props import (
FloatProperty, FloatProperty,
) )
def add_box(width, height, depth): def add_box(width, height, depth):
""" """
This function takes inputs and returns vertex and face arrays. This function takes inputs and returns vertex and face arrays.

View File

@ -5,4 +5,3 @@ from .device import TestDevice, TestMachine
from .config import TestEntry, TestQueue, TestConfig from .config import TestEntry, TestQueue, TestConfig
from .test import Test, TestCollection from .test import Test, TestCollection
from .graph import TestGraph from .graph import TestGraph

View File

@ -10,12 +10,14 @@ from typing import Dict, List
from .test import TestCollection from .test import TestCollection
def get_build_hash(args: None) -> str: def get_build_hash(args: None) -> str:
import bpy import bpy
import sys import sys
build_hash = bpy.app.build_hash.decode('utf-8') build_hash = bpy.app.build_hash.decode('utf-8')
return '' if build_hash == 'Unknown' else build_hash return '' if build_hash == 'Unknown' else build_hash
@dataclass @dataclass
class TestEntry: class TestEntry:
"""Test to run, a combination of revision, test and device.""" """Test to run, a combination of revision, test and device."""
@ -42,6 +44,7 @@ class TestEntry:
for field in self.__dataclass_fields__: for field in self.__dataclass_fields__:
setattr(self, field, json_dict[field]) setattr(self, field, json_dict[field])
class TestQueue: class TestQueue:
"""Queue of tests to be run or inspected. Matches JSON file on disk.""" """Queue of tests to be run or inspected. Matches JSON file on disk."""
@ -99,6 +102,7 @@ class TestQueue:
with open(self.filepath, 'w') as f: with open(self.filepath, 'w') as f:
json.dump(json_entries, f, indent=2) json.dump(json_entries, f, indent=2)
class TestConfig: class TestConfig:
"""Test configuration, containing a subset of revisions, tests and devices.""" """Test configuration, containing a subset of revisions, tests and devices."""

View File

@ -4,6 +4,7 @@ import platform
import subprocess import subprocess
from typing import List from typing import List
def get_cpu_name() -> str: def get_cpu_name() -> str:
# Get full CPU name. # Get full CPU name.
if platform.system() == "Windows": if platform.system() == "Windows":
@ -19,6 +20,7 @@ def get_cpu_name() -> str:
return "Unknown CPU" return "Unknown CPU"
def get_gpu_device(args: None) -> List: def get_gpu_device(args: None) -> List:
# Get the list of available Cycles GPU devices. # Get the list of available Cycles GPU devices.
import bpy import bpy
@ -41,6 +43,7 @@ def get_gpu_device(args: None) -> List:
return result return result
class TestDevice: class TestDevice:
def __init__(self, device_type: str, device_id: str, name: str, operating_system: str): def __init__(self, device_type: str, device_id: str, name: str, operating_system: str):
self.type = device_type self.type = device_type
@ -48,6 +51,7 @@ class TestDevice:
self.name = name self.name = name
self.operating_system = operating_system self.operating_system = operating_system
class TestMachine: class TestMachine:
def __init__(self, env, need_gpus: bool): def __init__(self, env, need_gpus: bool):
operating_system = platform.system() operating_system = platform.system()
@ -65,4 +69,3 @@ class TestMachine:
def cpu_device(self) -> TestDevice: def cpu_device(self) -> TestDevice:
return self.devices[0] return self.devices[0]

View File

@ -15,6 +15,7 @@ from typing import Callable, Dict, List
from .config import TestConfig from .config import TestConfig
from .device import TestMachine from .device import TestMachine
class TestEnvironment: class TestEnvironment:
def __init__(self, blender_git_dir: pathlib.Path, base_dir: pathlib.Path): def __init__(self, blender_git_dir: pathlib.Path, base_dir: pathlib.Path):
self.blender_git_dir = blender_git_dir self.blender_git_dir = blender_git_dir

View File

@ -6,6 +6,7 @@ import json
import pathlib import pathlib
from typing import Dict, List from typing import Dict, List
class TestGraph: class TestGraph:
def __init__(self, json_filepaths: List[pathlib.Path]): def __init__(self, json_filepaths: List[pathlib.Path]):
# Initialize graph from JSON file. Note that this is implemented without # Initialize graph from JSON file. Note that this is implemented without
@ -102,4 +103,3 @@ class TestGraph:
contents = template.replace('%JSON_DATA%', self.json) contents = template.replace('%JSON_DATA%', self.json)
with open(filepath, "w") as f: with open(filepath, "w") as f:
f.write(contents) f.write(contents)

View File

@ -4,6 +4,7 @@ import abc
import fnmatch import fnmatch
from typing import Dict, List from typing import Dict, List
class Test: class Test:
@abc.abstractmethod @abc.abstractmethod
def name(self) -> str: def name(self) -> str:
@ -29,6 +30,7 @@ class Test:
Execute the test and report results. Execute the test and report results.
""" """
class TestCollection: class TestCollection:
def __init__(self, env, names_filter: List=['*'], categories_filter: List=['*']): def __init__(self, env, names_filter: List=['*'], categories_filter: List=['*']):
import importlib import importlib

View File

@ -1,2 +1 @@
# Apache License, Version 2.0 # Apache License, Version 2.0

View File

@ -3,6 +3,7 @@
import api import api
import os import os
def _run(args): def _run(args):
import bpy import bpy
import time import time
@ -18,6 +19,7 @@ def _run(args):
result = {'time': elapsed_time} result = {'time': elapsed_time}
return result return result
class AnimationTest(api.Test): class AnimationTest(api.Test):
def __init__(self, filepath): def __init__(self, filepath):
self.filepath = filepath self.filepath = filepath
@ -33,6 +35,7 @@ class AnimationTest(api.Test):
result, _ = env.run_in_blender(_run, args) result, _ = env.run_in_blender(_run, args)
return result return result
def generate(env): def generate(env):
filepaths = env.find_blend_files('animation') filepaths = env.find_blend_files('animation')
return [AnimationTest(filepath) for filepath in filepaths] return [AnimationTest(filepath) for filepath in filepaths]

View File

@ -4,6 +4,7 @@ import api
import os import os
import pathlib import pathlib
def _run(filepath): def _run(filepath):
import bpy import bpy
import time import time
@ -20,6 +21,7 @@ def _run(filepath):
result = {'time': elapsed_time} result = {'time': elapsed_time}
return result return result
class BlendLoadTest(api.Test): class BlendLoadTest(api.Test):
def __init__(self, filepath): def __init__(self, filepath):
self.filepath = filepath self.filepath = filepath
@ -34,6 +36,7 @@ class BlendLoadTest(api.Test):
result, _ = env.run_in_blender(_run, str(self.filepath)) result, _ = env.run_in_blender(_run, str(self.filepath))
return result return result
def generate(env): def generate(env):
filepaths = env.find_blend_files('*/*') filepaths = env.find_blend_files('*/*')
return [BlendLoadTest(filepath) for filepath in filepaths] return [BlendLoadTest(filepath) for filepath in filepaths]

View File

@ -3,6 +3,7 @@
import api import api
import os import os
def _run(args): def _run(args):
import bpy import bpy
import time import time
@ -39,6 +40,7 @@ def _run(args):
return None return None
class CyclesTest(api.Test): class CyclesTest(api.Test):
def __init__(self, filepath): def __init__(self, filepath):
self.filepath = filepath self.filepath = filepath
@ -74,6 +76,7 @@ class CyclesTest(api.Test):
raise Exception("Error parsing render time output") raise Exception("Error parsing render time output")
def generate(env): def generate(env):
filepaths = env.find_blend_files('cycles-x/*') filepaths = env.find_blend_files('cycles-x/*')
return [CyclesTest(filepath) for filepath in filepaths] return [CyclesTest(filepath) for filepath in filepaths]

View File

@ -40,6 +40,7 @@ class AbstractAnimationTest:
self.assertTrue(self.testdir.exists(), self.assertTrue(self.testdir.exists(),
'Test dir %s should exist' % self.testdir) 'Test dir %s should exist' % self.testdir)
class FCurveEvaluationTest(AbstractAnimationTest, unittest.TestCase): class FCurveEvaluationTest(AbstractAnimationTest, unittest.TestCase):
def test_fcurve_versioning_291(self): def test_fcurve_versioning_291(self):
# See D8752. # See D8752.

View File

@ -69,7 +69,7 @@ class TestLibraryOverrides(TestHelper, unittest.TestCase):
assert(len(local_id.override_library.properties) == 1) assert(len(local_id.override_library.properties) == 1)
override_prop = local_id.override_library.properties[0] override_prop = local_id.override_library.properties[0]
assert(override_prop.rna_path == "location"); assert(override_prop.rna_path == "location")
assert(len(override_prop.operations) == 1) assert(len(override_prop.operations) == 1)
override_operation = override_prop.operations[0] override_operation = override_prop.operations[0]
assert(override_operation.operation == 'REPLACE') assert(override_operation.operation == 'REPLACE')
@ -96,7 +96,7 @@ class TestLibraryOverrides(TestHelper, unittest.TestCase):
self.assertIsNone(local_id.data.override_library) self.assertIsNone(local_id.data.override_library)
assert(len(local_id.override_library.properties) == 1) assert(len(local_id.override_library.properties) == 1)
override_prop = local_id.override_library.properties[0] override_prop = local_id.override_library.properties[0]
assert(override_prop.rna_path == "scale"); assert(override_prop.rna_path == "scale")
assert(len(override_prop.operations) == 1) assert(len(override_prop.operations) == 1)
override_operation = override_prop.operations[0] override_operation = override_prop.operations[0]
assert(override_operation.operation == 'NOOP') assert(override_operation.operation == 'NOOP')
@ -116,14 +116,14 @@ class TestLibraryOverrides(TestHelper, unittest.TestCase):
assert(len(local_id.override_library.properties) == 2) assert(len(local_id.override_library.properties) == 2)
override_prop = local_id.override_library.properties[0] override_prop = local_id.override_library.properties[0]
assert(override_prop.rna_path == "scale"); assert(override_prop.rna_path == "scale")
assert(len(override_prop.operations) == 1) assert(len(override_prop.operations) == 1)
override_operation = override_prop.operations[0] override_operation = override_prop.operations[0]
assert(override_operation.operation == 'NOOP') assert(override_operation.operation == 'NOOP')
assert(override_operation.subitem_local_index == -1) assert(override_operation.subitem_local_index == -1)
override_prop = local_id.override_library.properties[1] override_prop = local_id.override_library.properties[1]
assert(override_prop.rna_path == "location"); assert(override_prop.rna_path == "location")
assert(len(override_prop.operations) == 1) assert(len(override_prop.operations) == 1)
override_operation = override_prop.operations[0] override_operation = override_prop.operations[0]
assert(override_operation.operation == 'REPLACE') assert(override_operation.operation == 'REPLACE')

View File

@ -140,6 +140,7 @@ class TestIdPropertyCreation(TestHelper, unittest.TestCase):
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
self.id["a"] = self self.id["a"] = self
class TestIdPropertyGroupView(TestHelper, unittest.TestCase): class TestIdPropertyGroupView(TestHelper, unittest.TestCase):
def test_type(self): def test_type(self):

View File

@ -16,6 +16,7 @@ try:
except ImportError: except ImportError:
inside_blender = False inside_blender = False
def get_arguments(filepath, output_filepath): def get_arguments(filepath, output_filepath):
return [ return [
"--background", "--background",

View File

@ -57,6 +57,7 @@ BLACKLIST_GPU = [
'transparent_shadow_hair.*.blend', 'transparent_shadow_hair.*.blend',
] ]
def get_arguments(filepath, output_filepath): def get_arguments(filepath, output_filepath):
dirname = os.path.dirname(filepath) dirname = os.path.dirname(filepath)
basedir = os.path.dirname(dirname) basedir = os.path.dirname(dirname)

View File

@ -680,7 +680,7 @@ class RunTest:
test_name = each_test.test_name test_name = each_test.test_name
if self.verbose: if self.verbose:
print() print()
print("Running test {}/{}: {}...".format(test_number+1, len(self.tests), test_name)) print("Running test {}/{}: {}...".format(test_number + 1, len(self.tests), test_name))
success = self.run_test(test_name) success = self.run_test(test_name)
if not success: if not success:

View File

@ -321,7 +321,7 @@ def main():
MeshTest("CubeEdgeUnsubdivide", "testCubeEdgeUnsubdivide", "expectedCubeEdgeUnsubdivide", MeshTest("CubeEdgeUnsubdivide", "testCubeEdgeUnsubdivide", "expectedCubeEdgeUnsubdivide",
[OperatorSpecEditMode("unsubdivide", {}, "EDGE", {i for i in range(6)})]), [OperatorSpecEditMode("unsubdivide", {}, "EDGE", {i for i in range(6)})]),
MeshTest("UVSphereUnsubdivide", "testUVSphereUnsubdivide", "expectedUVSphereUnsubdivide", MeshTest("UVSphereUnsubdivide", "testUVSphereUnsubdivide", "expectedUVSphereUnsubdivide",
[OperatorSpecEditMode("unsubdivide", {'iterations': 9}, "FACE", {i for i in range(512)})]), [OperatorSpecEditMode("unsubdivide", {'iterations': 9}, "FACE", {i for i in range(512)})]),
# vert connect path # vert connect path
# Tip: It works only if there is an already existing face or more than 2 vertices. # Tip: It works only if there is an already existing face or more than 2 vertices.