script for automating pep8 checks.

On ubuntu/debian install these tools...

   sudo apt-get install pylint pyflakes python-setuptools python-pip
   sudo pip install pep8

then run from blenders source dir...
   python release/test/pep8.py

This searches for the comments "# <pep8 compliant>" and "# <pep8-80 compliant>", running the checking tools on these scripts only.

* some minor pep8 corrections too.
This commit is contained in:
Campbell Barton 2009-12-13 13:59:16 +00:00
parent c1bfd014bd
commit a1656300ba
20 changed files with 230 additions and 116 deletions

View File

@ -36,6 +36,7 @@ ops = _ops_module.ops_fake_module
import sys
DEBUG = ("-d" in sys.argv)
def load_scripts(reload_scripts=False):
import os
import traceback
@ -47,7 +48,7 @@ def load_scripts(reload_scripts=False):
def test_import(module_name):
try:
t = time.time()
ret= __import__(module_name)
ret = __import__(module_name)
if DEBUG:
print("time %s %.4f" % (module_name, time.time() - t))
return ret
@ -78,6 +79,7 @@ def load_scripts(reload_scripts=False):
if DEBUG:
print("Time %.4f" % (time.time() - t_main))
def _main():
# a bit nasty but this prevents help() and input() from locking blender
@ -99,5 +101,3 @@ def _main():
load_scripts()
_main()

View File

@ -134,7 +134,6 @@ class bpy_ops_submodule_op(object):
__keys__ = ('module', 'func')
def _get_doc(self):
return op_as_string(self.idname())

View File

@ -21,6 +21,7 @@
import bpy
import os
def expandpath(path):
if path.startswith("//"):
return os.path.join(os.path.dirname(bpy.data.filename), path[2:])
@ -44,15 +45,17 @@ _unclean_chars = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, \
_unclean_chars = ''.join([chr(i) for i in _unclean_chars])
def clean_name(name, replace="_"):
'''
All characters besides A-Z/a-z, 0-9 are replaced with "_"
or the replace argumet if defined.
'''
for ch in _unclean_chars:
name = name.replace(ch, replace)
name = name.replace(ch, replace)
return name
def display_name(name):
'''
Only capitalize all lowercase names, mixed case use them as is.
@ -75,6 +78,7 @@ def display_name(name):
_scripts = os.path.join(os.path.dirname(__file__), os.path.pardir, os.path.pardir)
_scripts = (os.path.normpath(_scripts), )
def script_paths(*args):
scripts = list(_scripts)
@ -105,6 +109,7 @@ def script_paths(*args):
_presets = os.path.join(_scripts[0], "presets") # FIXME - multiple paths
def preset_paths(subdir):
'''
Returns a list of paths for a spesific preset.

View File

@ -25,14 +25,18 @@ from Mathutils import Vector
from rna_prop_ui import rna_idprop_ui_prop_get
SPECIAL_TYPES = "root",
class RigifyError(Exception):
"""Exception raised for errors in the metarig.
"""
def __init__(self, message):
self.message = message
def __str__(self):
return repr(self.message)
def submodule_func_from_type(bone_type):
type_pair = bone_type.split(".")
@ -63,6 +67,7 @@ def get_submodule_types():
return sorted(submodules)
def get_bone_type_options(pbone, type_name):
options = {}
bone_name = pbone.name
@ -75,6 +80,7 @@ def get_bone_type_options(pbone, type_name):
return options
def validate_rig(context, obj):
'''
Makes no changes
@ -319,7 +325,6 @@ def generate_rig(context, obj_orig, prefix="ORG-", META_DEF=True):
obj.data.pose_position = 'POSE'
context.user_preferences.edit.global_undo = global_undo
return obj
@ -344,7 +349,7 @@ def generate_test(context, metarig_type="", GENERATE_FINAL=True):
continue
# XXX workaround!, problem with updating the pose matrix.
if module_name=="delta":
if module_name == "delta":
continue
type_name, submodule, func = submodule_func_from_type(module_name)

View File

@ -24,7 +24,7 @@ from rna_prop_ui import rna_idprop_ui_prop_get
METARIG_NAMES = ("cpy",)
# note, this example is just a bone with copy property.
def metarig_template():
# generated by rigify.write_meta_rig
bpy.ops.object.mode_set(mode='EDIT')
@ -40,6 +40,7 @@ def metarig_template():
pbone = obj.pose.bones['Bone']
pbone['type'] = 'copy'
def metarig_definition(obj, orig_bone_name):
return [orig_bone_name]

View File

@ -118,7 +118,6 @@ def main(obj, bone_definition, base_names, options):
bpy.ops.object.mode_set(mode='OBJECT')
# Move the child bone to the deltas location
obj.animation_data_create()
delta_pbone = obj.pose.bones[delta_name]

View File

@ -106,7 +106,7 @@ def metarig_definition(obj, orig_bone_name):
children = bone.children
# Now there must be 2 children, only one connected
if len(children) != 2:
raise RigifyError("expected the foot bone:'%s' to have 2 children" % bone.name )
raise RigifyError("expected the foot bone:'%s' to have 2 children" % bone.name)
if children[0].connected == children[1].connected:
raise RigifyError("expected one bone to be connected")

View File

@ -25,6 +25,7 @@ from rna_prop_ui import rna_idprop_ui_prop_get
# not used, defined for completeness
METARIG_NAMES = tuple()
def metarig_template():
# generated by rigify.write_meta_rig
bpy.ops.object.mode_set(mode='EDIT')

View File

@ -32,6 +32,7 @@ from rna_prop_ui import rna_idprop_ui_prop_get
DELIMITER = '-._'
EMPTY_LAYER = [False] * 32
def add_stretch_to(obj, from_name, to_name, name):
'''
Adds a bone that stretches from one to another
@ -244,7 +245,6 @@ def add_pole_target_bone(obj, base_bone_name, name, mode='CROSS'):
return poll_name
def get_side_name(name):
'''
Returns the last part of a string (typically a bone's name) indicating
@ -256,6 +256,7 @@ def get_side_name(name):
else:
return ""
def get_base_name(name):
'''
Returns the part of a string (typically a bone's name) corresponding to it's
@ -327,8 +328,9 @@ def write_meta_rig(obj, func_name="metarig_template"):
return "\n".join(code)
# *** bone class collection ***
def bone_class_instance(obj, slots, name="BoneContainer"):
'''
bone collection utility class to help manage cases with
@ -361,6 +363,7 @@ def bone_class_instance(obj, slots, name="BoneContainer"):
instance = auto_class_instance(slots, name, class_dict)
return instance
def auto_class(slots, name="ContainerClass", class_dict=None):
if class_dict:

View File

@ -219,7 +219,6 @@ class WM_OT_properties_edit(bpy.types.Operator):
return ('RUNNING_MODAL',)
class WM_OT_properties_add(bpy.types.Operator):
'''Internal use (edit a property path)'''
bl_idname = "wm.properties_add"

View File

@ -126,4 +126,3 @@ class Retopo(bpy.types.Operator):
bpy.ops.add(SelectPattern)
bpy.ops.add(SubdivisionSet)
bpy.ops.add(Retopo)

View File

@ -23,6 +23,7 @@ import os
from bpy.props import *
class MESH_OT_delete_edgeloop(bpy.types.Operator):
'''Export a single object as a stanford PLY with normals,
colours and texture coordinates.'''
@ -42,7 +43,8 @@ rna_path_prop = StringProperty(name="Context Attributes",
rna_reverse_prop = BoolProperty(name="Reverse",
description="Cycle backwards", default=False)
class NullPathMember:
class NullPath:
pass
@ -53,7 +55,7 @@ def context_path_validate(context, path):
except AttributeError:
if "'NoneType'" in str(sys.exc_info()[1]):
# One of the items in the rna path is None, just ignore this
value = NullPathMember
value = NullPath
else:
# We have a real error in the rna path, dont ignore that
raise
@ -62,7 +64,7 @@ def context_path_validate(context, path):
def execute_context_assign(self, context):
if context_path_validate(context, self.properties.path) == NullPathMember:
if context_path_validate(context, self.properties.path) == NullPath:
return ('PASS_THROUGH',)
exec("context.%s=self.properties.value" % self.properties.path)
return ('FINISHED',)
@ -136,10 +138,12 @@ class WM_OT_context_toggle(bpy.types.Operator):
def execute(self, context):
if context_path_validate(context, self.properties.path) == NullPathMember:
if context_path_validate(context, self.properties.path) == NullPath:
return ('PASS_THROUGH',)
exec("context.%s=not (context.%s)" % (self.properties.path, self.properties.path))
exec("context.%s=not (context.%s)" %
(self.properties.path, self.properties.path))
return ('FINISHED',)
@ -157,11 +161,13 @@ class WM_OT_context_toggle_enum(bpy.types.Operator):
def execute(self, context):
if context_path_validate(context, self.properties.path) == NullPathMember:
if context_path_validate(context, self.properties.path) == NullPath:
return ('PASS_THROUGH',)
exec("context.%s = ['%s', '%s'][context.%s!='%s']" % \
(self.properties.path, self.properties.value_1, self.properties.value_2, self.properties.path, self.properties.value_2))
(self.properties.path, self.properties.value_1,\
self.properties.value_2, self.properties.path,
self.properties.value_2))
return ('FINISHED',)
@ -177,7 +183,7 @@ class WM_OT_context_cycle_int(bpy.types.Operator):
def execute(self, context):
value = context_path_validate(context, self.properties.path)
if value == NullPathMember:
if value == NullPath:
return ('PASS_THROUGH',)
self.properties.value = value
@ -209,7 +215,7 @@ class WM_OT_context_cycle_enum(bpy.types.Operator):
def execute(self, context):
value = context_path_validate(context, self.properties.path)
if value == NullPathMember:
if value == NullPath:
return ('PASS_THROUGH',)
orig_value = value
@ -318,9 +324,12 @@ class WM_OT_doc_edit(bpy.types.Operator):
def execute(self, context):
class_name, class_prop = self.properties.doc_id.split('.')
doc_id = self.properties.doc_id
doc_new = self.properties.doc_new
if not self.properties.doc_new:
class_name, class_prop = doc_id.split('.')
if not doc_new:
return ('RUNNING_MODAL',)
# check if this is an operator
@ -333,25 +342,25 @@ class WM_OT_doc_edit(bpy.types.Operator):
if op_class:
rna = op_class.bl_rna
doc_orig = rna.description
if doc_orig == self.properties.doc_new:
if doc_orig == doc_new:
return ('RUNNING_MODAL',)
print("op - old:'%s' -> new:'%s'" % (doc_orig, self.properties.doc_new))
upload["title"] = 'OPERATOR %s:%s' % (self.properties.doc_id, doc_orig)
upload["description"] = self.properties.doc_new
print("op - old:'%s' -> new:'%s'" % (doc_orig, doc_new))
upload["title"] = 'OPERATOR %s:%s' % (doc_id, doc_orig)
upload["description"] = doc_new
self._send_xmlrpc(upload)
else:
rna = getattr(bpy.types, class_name).bl_rna
doc_orig = rna.properties[class_prop].description
if doc_orig == self.properties.doc_new:
if doc_orig == doc_new:
return ('RUNNING_MODAL',)
print("rna - old:'%s' -> new:'%s'" % (doc_orig, self.properties.doc_new))
upload["title"] = 'RNA %s:%s' % (self.properties.doc_id, doc_orig)
print("rna - old:'%s' -> new:'%s'" % (doc_orig, doc_new))
upload["title"] = 'RNA %s:%s' % (doc_id, doc_orig)
upload["description"] = self.properties.doc_new
upload["description"] = doc_new
self._send_xmlrpc(upload)

View File

@ -182,6 +182,7 @@ class INFO_MT_mesh_add(dynamic_menu.DynMenu):
layout.operator("mesh.primitive_grid_add", icon='MESH_GRID', text="Grid")
layout.operator("mesh.primitive_monkey_add", icon='MESH_MONKEY', text="Monkey")
class INFO_MT_armature_add(dynamic_menu.DynMenu):
bl_idname = "INFO_MT_armature_add"
bl_label = "Armature"

View File

@ -134,7 +134,7 @@ class SEQUENCER_MT_select(bpy.types.Menu):
class SEQUENCER_MT_marker(bpy.types.Menu):
bl_label = "Marker (TODO)"
bl_label = "Marker"
def draw(self, context):
layout = self.layout

93
release/test/pep8.py Normal file
View File

@ -0,0 +1,93 @@
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
import os
# depends on pep8, pyflakes, pylint
# for ubuntu/debian
#
# sudo apt-get install pylint pyflakes
#
# sudo apt-get install python-setuptools python-pip
# sudo pip install pep8
# how many lines to read into the file, pep8 comment
# should be directly after the licence header, ~20 in most cases
PEP8_SEEK_COMMENT = 40
SKIP_PREFIX = "./tools", "./config", "./scons", "./extern"
def file_list_py(path):
for dirpath, dirnames, filenames in os.walk(path):
for filename in filenames:
if filename.endswith(".py"):
yield os.path.join(dirpath, filename)
def is_pep8(path):
f = open(path, 'r')
for i in range(PEP8_SEEK_COMMENT):
line = f.readline()
if line.startswith("# <pep8"):
if line.startswith("# <pep8 compliant>"):
return 1
elif line.startswith("# <pep8-80 compliant>"):
return 2
f.close()
return 0
def main():
files = []
files_skip = []
for f in file_list_py("."):
pep8_type = is_pep8(f)
if pep8_type:
# so we can batch them for each tool.
files.append((f, pep8_type))
else:
if not [None for prefix in SKIP_PREFIX if f.startswith(prefix)]:
files_skip.append(f)
print("\nSkipping...")
for f in files_skip:
print(" %s" % f)
# pyflakes
print("\n\n\n# running pep8...")
for f, pep8_type in files:
if pep8_type == 1:
# E501:80 line length
os.system("pep8 --repeat --ignore=E501 '%s'" % (f))
else:
os.system("pep8 --repeat '%s'" % (f))
print("\n\n\n# running pyflakes...")
for f, pep8_type in files:
os.system("pyflakes '%s'" % f)
print("\n\n\n# running pylint...")
for f, pep8_type in files:
# let pep8 complain about line length
os.system("pylint --reports=n --max-line-length=1000 '%s'" % f)
if __name__ == "__main__":
main()