Scripting is a very important feature in Blender and it's already possible to extend the program in more ways than we could imagine with Python code.
But programming is not only about cool and useful functionality. Good code and interfaces, robustness with proper error checking and documentation are just as important as the coded features themselves. And with our scripting resources and programmers to keep fixing and improving it, there's no reason for a script not to be as stable and easy to use as any other Blender functionality.
Blender itself is quickly becoming better and more polished with each release. That's where we want and need to be, too. This project is intended to define the best way to manage scripting in Blender, and is open to the participation of all interested coders and users.
Bundle and Extra Package
- Blender will continue to have some scripts bundled with it, especially importers and exporters.
- We will create an extra package of scripts that we can release together with Blender, but also update when needed. Installing a new version of this package is a way to update all scripts in Blender: the bundled and the ones in the package. So we don't have to wait for a new Blender release to update the scripts.
- We will use the scripts' project cvs to manage scripts, because there more script writers can have cvs write access.
Hopefully this will be a fun and productive community effort and enough enthusiasts will help in discussions and small tasks:
- All issues about official scripts: including, removing, upgrading, splitting, merging, etc. will be discussed in forum threads.
- Documentation and interfaces also need to be tested, to make sure they are good and follow the main guidelines for docs and Blender ui.
- We will also discuss what Blender needs: what functionality is missing that we can provide well with scripts. Once decided, the need becomes a project:
- We define the expected functionality
- We check the available scripts that do what we need, if any
- If one or more of them are offered for inclusion in Blender, we decide and work to improve the script(s) where needed. Otherwise some volunteer(s) create the script.
- CVS and mailing list: bf-scripts project
- Mailing list: bf-scripts-dev
TODO: choose a forum for our discussions. The BlenderArtists forum is more active, so maybe it's better to use it.
At the moment this document is a draft that has yet to be discussed and changed by input from the scripting community --Ideasman42 03:42, 4 August 2006 (CEST)
This document outlines standards that scripts should follow in order to be bundled with Blender or a separate official package of scripts yet to be created.
Scripts are evaluated based on:
- Maintainability (readability) and active maintainer
- Correctness and completeness
- Consistency, (The interface, and functionality, should try to match the existing feel and conventions of Blender as closely as possible).
Its also recommended that external scripts to adhere to these guidelines.
- Single tab indenting. no mixing tabs with spaces.
- All significant functions, classes and functions within classes should have a docstring explaining what they do, variables they receive and return.
Note, for our purposes a significant function is one that is not obvious at a glance to a python programmer who is not experienced in the specifics that the script deals with.
even fairly simple functions should have a docstring if they are more then a few lines
- Comments and variable names in US English.
- Constant variable names all upper case.
Note, Python has no constants, this refers to variables that do not change in the script, PI, EUL for a small number, RAD_TO_DEG, IDENTITY_MATRIX4X4 are examples of names you might use
- No reliance on deprecated parts of the Blender/Python API.
- There are no limits on line lengths, however we ask that very long lines are split for improved readability.
This mainly applys to importers and scripts that operate in Object mode but may alter object data.
For most scripts the assumed context is the context "Blender users".
- A user must be made aware of the data that is modified by running the script (If the script operates on data outside its context, eg. Object script modifying a mesh, Object script changing objects on hidden layers).
- Scripts should not overwrite existing data (Request to deprecate NMesh.PutRaw() - Ideasman42)
- For scripts that deal with all objects Object.Get() is often misused.
Blender can have multiple scenes and each scene has its objects.
So an exporter that exports objects in Object.Get() - with no name specified. could export 10 scenes all overlapping, which is undesirable and possibly slow.
Getting all objects is only to be used in cases where getting objects from the current scene with Scene.GetCurrent().objects is not appropriate.
- Scripts must not operate on hidden data such as objects not in the visible layers, objects in other scenes and hidden verts unless specifically stated.
- Match Blender's functionality where possible.
- Scripts that do a wide variety of operations may need to be split into separate scripts that have a clearly defined purpose.
- Scripts that may take some time to run should use the wait cursor to let the user know that Blender is busy.
- The Status bar may also be used for feedback (be careful not to call this too often otherwise it will slow the script down)
- Console output should be used with care. details can be printed to the console but it should be limited so that users don't have to scroll through pages of text. Debug information should also be removed or commented out for scripts released with Blender.
- Scripts with obvious inefficiency's must have these improved before becoming a part of Blender's bundled scripts.
Some common examples of slow Python code and their faster counterpart are listed below.
This will convert the Mesh to an NMesh, which is costly.
If all you want is the name, it should be as follows:
Looping on dictionary values
This is an unnecessary lookup.
For iterating its best to use the 'iter' prefix.
for key in my_dict.keys(): value= my_dict[key] ...
for value in my_dict.itervalues(): ...
Looping on a list with an index
This does a list lookup each loop.
If all you want is the name, it should be as follows:
for item in my_list: index= my_list.index(item) ...
for index, item in enumerate(my_list): ...
- Scripts should never raise a Python error (apart from very exceptional cases). It's much better to inform the user with an error popup and / or a message to the console.
- Using try/except to manage handle errors is good, but should be clearly defined, the code that runs in a try/except statement must be limited to the operations that are known to cause the error.
- Following one of Python's motto (It's easier to ask forgiveness than permission) is a good way to differenciate when is a good time to use exception handling and when is not.
- A BPyMessages.py module has been added to show popups of common errors and warnings, like "File exists", "No object selected", etc. This must be used where possible, so we have a standard interface. New messages should be added to BPyMessages.py if they are generic enough to be reused by other scripts.
- Ensure that your script does atomic operations. That is, it shouldn't leave unfinished business if it encounters an error (internal or external).
- Scripts must not overwrite files without asking the user (See, BPyMessages.py)
- Similar to above, scripts that read files should test for the file not existing.
Scripts that read and write files should use the file selector to do so. (except in rare cases where there is a reason not to)
- Scripts can not use eval() exec(), this is a major security issue either by issuing incorrect or malicious input.
- Scripts that must modify files, especially when overwriting and removing. do so with care, and are well tested.
- Scripts names must indicate what they do.
- Tooltips should extend on this information in the name but need not include it.
- User visible parts of the scripts such as the name, tooltip, docstring, error messages, and user interface must not have spelling errors.
- Current email address/contact info for official maintainer
- file names must be all lowercase with underscore delimiters
- have the "Group" as a name prefix. Eg.
import_3ds.py, animation_armature_symmetry.py, object_axis_copy.py
- Modules written in python may use capitals, they are stored in the bpymodules directory. TODO Define rules for module names, do we need to?
Before release scripts must contain complete and approved documentation, in the form of doc strings and wiki page. We all can decide on a basic format and layout for all such documentation for a more integrated and professional work, nicer and easier to understand and maintain.
These are written directly in the scripts.
Read the section "Documenting Scripts" in the official BPython reference guide: API related pageRun the Scripts Help Browser script from the "Help" menu in Blender. Then check the source of any script with good documentation to see how it's done.
The docstring should include:
- Short description of the script and what it is used for.
- Extended info, if needed
- Usage info
- Steps to use the script effectively
- Note any issues the user should be aware of
- Contact emails and website urls can also be added
The changelog should not be a part of the docstring.
We'd like to have the same information written in docstrings also available as wiki pages in Blender's wiki: http://mediawiki.blender.org
All scripts should be documented here: http://mediawiki.blender.org/index.php/Scripts/Manual
(TODO: create a simple script to generate a wiki page skeleton from docstrings)
The wiki pages can have further information, pictures and so on. With that it will be easy later to create a book about the scripts in Blender, for example.
As scripts are reviewed by the script developers and accepted, a copy will be made in the Blender CVS.
Experienced script writers are encouraged to become part of this group to help with their contributions and input as well as to maintain their own or others unmaintained scripts.
This copy will be updated from the scripts CVS before Blender release.
Scripts that do not adhere to the above specifications will not be distributed with Blender. Note, is some cases it may be a design decision not to adhere to one of these guidelines, in this case we need to decide as a group whether an exception is allowed
Duplicate scripts may exist during development but before distribution with Blenders script bundle, a decision will be made by the group as to which script to keep and which to remove before a blender release. - both scripts may coexist in the scripts CVS, however a decision should be reached at some point how to best remove the duplicate.
If the author wants to contest this, they have a week to make the necessary improvements for review.
This may include merging functionality from both scripts or even re-implementing functionality in Blender.
All scripts are to be licensed under GPL or compatible license. The license is to be included under the Blender/Python header.