2.2. Style
Preferred Plone coding style
Python, like any programming language, can be written in a number of styles. We're the first to admit that Zope and Plone are not the finest examples of stylistic integrity, but that doesn't stop us from trying!
First of all, you need to read PEP 8 - the python style guide. You might also have a look at the Zope codying style guidelines but these are not a mandatory reading.
Naming conventions
- Above all else, be consistent with any code your are modifying!
- Write method names and variable names in mixedCase
- Write class names in CapitalisedCase
File conventions
- If you need to create a new file, chances are you're doing something fairly fundamental. In that case, you should probably discuss it with the release manager or someone else more experienced first.
- In Zope 2, file names used to be MixedCase. In Zope 3, and thus in Plone going forward, we prefer all-lowercase filenames. This has the advantage that you can instantly see if you refer to a module / file or a class:
from zope.pagetemplate.pagetemplate import PageTemplate
compare that to:
from Products.PageTemplates.PageTemplate import PageTemplate
- Filenames should be short and descriptive. Think about how an import would read:
from Products.CMFPlone.utils import safe_hasattr
compare that to:
from Products.CMFPlone.PloneUtilities import safe_hasattr
the former is obviously much easier to read, less redundant and generally more aesthetically pleasing.
Some concrete rules
Certain things should never be seen in code. Some of these are covered in more detail in the patterns section, but briefly:
- Do not use tabs in Python code! Use spaces as indenting, 4 spaces for each level. Maybe you didn't hear that - do not use tabs and keep indentation to 4, that's four, spaces.
- Indent properly, even in HTML. (limi's note: especially in HTML ;)
- Never use a bare except. Anything like
except: passwill get you in real trouble - Avoid tal:on-error, since this swallows exceptions
- Don't use hasattr() - this swallows exceptions, use
CMFPlone.utils.base_hasattrorCMFPlone.utils.safe_hasattrinstead!The problem with swallowed exceptions is not just poor error reporting. This can also mask ConflictErrors, which indicate that something has gone wront at the ZODB level!
- Never, ever put any HTML in Python code and return it as a string
- Do not raise string exceptions - raise proper exception objects instead
- Do not acquire tools e.g. using
context.plone_utils. Instead, use:from Products.CMFCore.utils import getToolByName plone_utils = getToolByName(context, 'plone_utils')
(it's OK to acquire tools in unit tests)
- Do not put too much logic in ZPT (use Views instead!)
- Remember to add i18n tags in ZPTs and Python code