* Not necessarily valid for every meaning of the word "Everything"
Or: how do I get rid of all those red squigglies?
In CMakeCache.txt set WITH_PYTHON_MODULE:BOOL=ON
make && make install
Install them, well documented how
mkvirtualenv -p /usr/bin/python3.5 bladdons
cdvirtualenv
cd lib/python3.5/site-packages
ln -s ~/workspace/blender-git/build_bpy/bin/bpy.so
ln -s ~/workspace/blender-git/blender/release
% python
Python 3.5.2 (default, Sep 10 2016, 08:21:44)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import bpy
>>> bpy.ops.wm.quit_blender()
Blender quit
Where you want them to be
Blender Text Editor has many examples
import bpy
def main(context):
for ob in context.scene.objects:
print(ob)
class SimpleOperator(bpy.types.Operator):
"""Tooltip"""
bl_idname = "object.simple_operator"
bl_label = "Simple Object Operator"
@classmethod
def poll(cls, context):
return context.active_object is not None
def execute(self, context):
main(context)
return {'FINISHED'}
def register():
bpy.utils.register_class(SimpleOperator)
def unregister():
bpy.utils.unregister_class(SimpleOperator)
bl_info = {
'name': 'Blender Cloud',
'author': 'Sybren A. Stüvel, Francesco Siddi, Inês Almeida, Antony Riakiotakis',
'version': (1, 4, 99),
'blender': (2, 77, 0),
'location': 'Addon Preferences panel, and Ctrl+Shift+Alt+A anywhere for texture browser',
'description': 'Texture library browser and Blender Sync. Requires the Blender ID addon '
'and Blender 2.77a or newer.',
'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.6/Py/'
'Scripts/System/BlenderCloud',
'category': 'System',
'warning': 'This is a beta version; the first to support Attract.'
}
Parsed, not executed
bpy.ops.bcloud.browseclass BCLOUD_OT_browsebl_idname='mesh.scramble'... and similar for menus, headers, etc.
unregister()register()
# Your code
x = 5
# Your new code
x = 8
if "bpy" in locals():
import importlib
importlib.reload(Boltfactory)
else:
from add_mesh_BoltFactory import Boltfactory
import bpy
...
self.report()print() statementslogging moduleprint() statementssudo apt-get install eclipse-pydev/home/sybren/.p2/pool/plugins/org.python.pydev_5.3.0.201610121612/pysrc/pydevd.py






print()
class SimpleOperator(bpy.types.Operator):
bl_idname = "object.simple_operator"
bl_label = "Simple Object Operator"
log = logging.getLogger('bpy.ops.%s' % bl_idname)
def execute(self, context):
self.log.info('It is happening now in scene %s', context.scene)
if not context.object:
self.log.warning('No active object, not doing anything')
self.log.debug('Not doing anything here either')
return {'FINISHED'}
Shown on stdout, only WARNING or higher level.
No active object, not doing anything
Still shown on stdout, INFO or higher level.
DEBUG level for selected loggers.
Metadata shown partially.
16:00:03.03 bpy.ops.object.simple_operator WARNING No active object, not doing anything
16:00:03.13 bpy.ops.object.simple_operator DEBUG Not doing anything here either
Loaded at Blender startup.
.../scripts/startup/config_logging.py
~/.config/blender/2.78/...%APPDATA%\Blender Foundation\Blender\2.78\.../Users/$USER/Library/Application Support/Blender/2.78/...
import logging.config
logging.config.dictConfig({
'version': 1,
'formatters': {'default': {'format': '%(asctime)-15s %(levelname)8s %(name)s %(message)s'}},
'handlers': {
'console': {
'class': 'logging.StreamHandler',
'formatter': 'default',
'stream': 'ext://sys.stderr',
}
},
'loggers': {
'bpy.ops.': {'level': 'DEBUG'},
'blenderid': {'level': 'DEBUG'},
'bid_api': {'level': 'DEBUG'},
'bid_addon_support': {'level': 'DEBUG'},
},
'root': {
'level': 'WARNING',
'handlers': ['console'],
}
})
The what & how should be clear from code.
Docstring can describe the what, and is the first thing to write.
Warning: There is a known bug with using a callback, Python must keep a reference to the strings returned or Blender will misbehave or even crash.
def pyside_cache(wrapped):
"""Stores the result of the callable in Python-managed memory.
This is to work around the warning at
https://www.blender.org/api/blender_python_api_master/bpy.props.html#bpy.props.EnumProperty
"""
import functools
@functools.wraps(wrapped)
# We can't use (*args, **kwargs), because EnumProperty explicitly checks
# for the number of fixed positional arguments.
def wrapper(self, context):
result = None
try:
result = wrapped(self, context)
return result
finally:
wrapped._cached_result = result
return wrapper
This stores the cached results in the bl_rna dict for the property, rather
than on the callback function. A downside is that the decorator now needs the name of
the property it's a callback for.
def pyside_cache(propname):
if callable(propname):
raise TypeError('Usage: pyside_cache("property_name")')
def decorator(wrapped):
"""Stores the result of the callable in Python-managed memory.
This is to work around the warning at
https://www.blender.org/api/blender_python_api_master/bpy.props.html#bpy.props.EnumProperty
"""
import functools
@functools.wraps(wrapped)
# We can't use (*args, **kwargs), because EnumProperty explicitly checks
# for the number of fixed positional arguments.
def wrapper(self, context):
result = None
try:
result = wrapped(self, context)
return result
finally:
rna_type, rna_info = getattr(self.bl_rna, propname)
rna_info['_cached_result'] = result
return wrapper
return decorator
"A function should have only one point of return"
... and use break, continue etc.
def some_func(param1: int, param2: float) -> float:
"""Performs our special snowflake multiplication.
:param param1: non-zero integer
:param param2: positive float
:returns: our magic number
"""
if param1 != 0:
if param2 > 0:
return param1 * param2
else:
raise ValueError('param2 must be positive')
else:
raise ValueError('param1 may not be zero')
def some_func(param1: int, param2: float) -> float:
"""Performs our special snowflake multiplication.
:param param1: non-zero integer
:param param2: positive float
:returns: our magic number
"""
if param1 == 0:
raise ValueError('param1 may not be zero')
if param2 <= 0:
raise ValueError('param2 must be positive')
return param1 * param2
def somefunc(...):
...
if jemoeder.weight > 3:
return True
else:
return False
def somefunc(...):
...
return jemoeder.weight > 3
bpy.utils.user_resource('CACHE') (once T47684 is done)
https://github.com/ActiveState/appdirs/blob/master/appdirs.py
is not the same as