Bungeni Source Code Style Guide — Site
Personal tools

Skip to content. | Skip to navigation

 
You are here:

Document Actions


3.1. Bungeni Source Code Style Guide

Bungeni Source Code Style Guide

Recommendations for Bungeni source code style, with the aim of enhancing source code read-ability, grep-ability and print-ability and consequently, understand-ability, debug-ability, test-ability, maintain-ability, etc.

However, if conforming to these source style recommendations reduces any of the above code qualities in any way then conformance should not be adhered to -- use your good judgement instead.

General - All Formats

Guidelines that apply to all project source code, irrespective of format e.g. .py, .xml, .zcml, .js, .css, etc.

Applies to all project source code, irrespective of format.

Indentation and line length

Use 4 spaces per indentation level.

Limit all lines to a maximum of 79 characters.

Quote characters

Prefer the double-quote " instead of the single-quote ' character, whenever you have the choice.

Revisit Comments

Use Revisit comments for code that is temporary, a short-term solution to be reworked, or for code on which there is still questions to be resolved or understood.

A Revisit comments should have a:

  • !+ : must explicitly start with these 2 characters
  • label : for easier grepping, and to be able to relate multiple comments in different places (by giving them the same label)
  • author identifier : so others know who to follow-up with if needed
  • date : so it is easier to jusdge relevance and status at a later time
  • description : should also indicate what conditions/events would render the comment obsolete.

Authoring a revisit comment is not a commitment to revisit it yourself.

These pieces of information should be formatted in the following way:

!+LABEL(author, date) description...

And should be specified in a comment as per the source format i.e. any of python, XML, doctest text files, HTML templates, css, js, etc.

As example, here are 2 related revisit comments in different ZCML files:

models/configure.zcml

<!-- !+CONSTITUENCY-Issue666(mr, 23-Jul-2010)
why is the include="domain.zcml" above commented?
-->


models/permissions.zcml

<!-- !+CONSTITUENCY-Issue666(mr, 23-Jul-2010)
The grant below is a temporary workaround to the problem that,
when NOT logged in, clicking on a consituency (below archive/ )
to view it would result in the following error:

<class 'zope.security.interfaces.Unauthorized'>:
(<zope.app.publisher.browser.viewmeta.DisplayForm object at 0xb717c8c>, 'browserDefault', 'zope.View')

For some reason, this is not needed for any other object -:- this should
be removed when it is understood why bungeni.Anybody does not get
zope.View on domain.Constituency type, as for other anonymously visible
domain types.
-->
<grant permission="bungeni.constituency.View" role="bungeni.Anybody" />

Naming

Workflow States and Transitions

Workflow state/transition names:

  • State names should be lowercase adjectives.
  • Transition names should be lowercase verbs.
  • Given that all workflow names are specified as XML @id attributes, state and transition names must be unique for the XML document.
  • All multiple word names are joined using an _ (underscore) character.

Python

All Bungeni python source code should follow these style rules.

For any styling issue not explicitly specified here, heed the recommendations of the following Python Style Guides:

Quote characters

Always use a single double-quote char " to delineate a short literal string. Only use single-quote ' when the literal string itself contains double-quote characters that would otherwise require explicit escaping.

Always use triple double-quote chars """ to delineate a multi-line string. Only use triple single-quotes ''' when the literal string contains itself triple double-quote characters that would otherwise require explicit escaping.

The use of triple single-quotes ''' should be reserved only to temporarily comment out entire code sections.

For long string that should not include any additional whitespace as a result of pretty source formatting should use the auto-concatenation feature of adjacent strings e.g. (preferably):

long_string = "some text as part of a sible line string " \
"more text for the same string "


or:

long_string = ("some text as part of a sible line string "
"more text for the same string")


but not:

long_string = ("some text as part of a sible line string " +
"more text for the same string")


Quoting inlined source code strings

Always delineate embedded code with triple double-quote chars """ -- even if the string is not multi-line. Example, here's a snippet of inlined SQL:

rdb.CheckConstraint("""active_p in ('A', 'I', 'D')"""),

Multi-line parameter lists, literal lists and objects

  • The closing parenthesis, brace or bracket should be directly below the beginning of the opening symbol.
  • Continuation lines should be indented as per their nesting level i.e. 4 spaces per depth level implied by an open parenthesis, brace, bracket or any other way.
  • Only use multiple lines when a single line (of max 79 chars) is not sufficient.
  • Always include the most key of parameters on the opening line.

Some examples:

columns = [
rdb.Column("version_id", rdb.Integer, primary_key=True),
rdb.Column("content_id", rdb.Integer, rdb.ForeignKey(table.c[fk_id])),
rdb.Column("change_id", rdb.Integer,
rdb.ForeignKey("%s_changes.change_id" % entity_name)
),
rdb.Column("manual", rdb.Boolean, nullable=False, default=False),
]

mapper(domain.User, schema.users,
properties={"user_addresses": relation(domain.UserAddress)}
)

mapper(domain.QuestionVersion, schema.question_versions,
properties={
"change": relation(domain.QuestionChange, uselist=False),
"head": relation(domain.Question, uselist=False),
"attached_files": relation(domain.AttachedFileVersion,
primaryjoin=rdb.and_(
schema.question_versions.c.content_id ==
schema.attached_file_versions.c.item_id,
schema.question_versions.c.version_id ==
schema.attached_file_versions.c.file_version_id
),
foreign_keys=[schema.attached_file_versions.c.item_id,
schema.attached_file_versions.c.file_version_id
]
),
}
)

Multiple forms for same -- adopt and use one

Comparison operators

Always use != and not <> (that is equivalent).

XML / ZCML

Use 4 spaces per indentation level.

Limit all lines to a maximum of 79 characters.

No blank lines -- only use a single blank line between elements on the uncommon occasion when those elements are completely unrelated to each other.

Multi-line elements

Empty XML elements should have the /> ending:

  • either on same single line as the opening tag
  • or at exactly same indent as opening tag

For example:

<browser:menu id="admin_navigation" title="Actions Admin" />
<browser:menuItem menu="admin_navigation"
for="bungeni.models.interfaces.IBungeniApplication"
title="Application Settings"
action="settings"
layer=".interfaces.IAdministratorWorkspace"
permission="zope.ManageSite"
/>


When an element has a clear key attribute -- i.e. the one most obvious attribute by which the element could be identified or grouped e.g. the id or name attribute, the menu attribute for <menuItem> elements, etc. -- it should be specified first and on same line as opening tag. For example:

<adapter factory=".workspace.WorkspaceContainerTraverser"
permission="zope.Public"
trusted="true"
/>