Guidelines:CodingStyle: Difference between revisions
| Line 97: | Line 97: | ||
Type specifications for parameters and return value are optional, but strongly recommended where the types are not obvious. | Type specifications for parameters and return value are optional, but strongly recommended where the types are not obvious. | ||
In some trivial cases, PEP484-style type hints can also be acceptable - but are otherwise discouraged as not every syntax highlighter will aid the visual parsing of function annotations. | In some trivial cases, PEP484-style type hints can also be acceptable - but are otherwise discouraged as they can easily impair comprehensibility, and not every syntax highlighter will aid the visual parsing of function annotations. | ||
<syntaxhighlight lang="python"> | <syntaxhighlight lang="python"> | ||
Revision as of 21:35, 28 October 2026
Coding Style Guide
These conventions should be followed in all code.
This facilitates a team of developers working on the same code base. If each developer were to use their own style, there would be jarring changes in the code as someone read through it. This slows comprehension and can also cause spurious differences in changesets as developers alter style in frivolous ways on the code they touch.
Our style guide aims to make the code base appear as if it was written by one precise punctilious programmer, rather than a a cacophony of competing coders. As with many aspects of coding and writing, there can be differences of opinion about the best style. These issues distract from the goal of writing code that works. Most project contributors have a slightly different personal coding style, but we all use the Sahana Eden style when contributing to the Sahana Eden project.
Quotes
- for string literals in Python use double-quotes
" ", unless the string contains double-quotes - for triple-quoted strings (such as Docstrings or Inline-XML) use
""" """with double-quotes, except: - for Inline-JavaScript or JSON inside Python code use
''' '''with single-quotes
Note though that this:
inline_javascript = '''sometext="%s";''' % sometext
is a potential bug - the script breaks when sometext contains a ". A safer way to do that is:
inline_javascript = '''sometext=%s;''' % json.dumps(sometext)
- for string literals in JavaScript use single-quotes
' ', unless the string contains single-quotes
- for attributes in HTML (such as view templates) use single-quotes
attr='value' - for attributes in other XML (e.g. XSLT) use double-quotes
" "(inner quotes must be escaped anyway)
Names
General
- Names should be obvious and explicit, but not overly verbose (i.e. as long as they need to be to not make people think). They shouldn't require someone to look in another file or solve a puzzle to figure out what they mean, but shouldn't take too long to write. Avoid inventing new acronyms. e.g.
bad:prm_lkp,method_that_allows_us_to_create_a_gis_layergood:personnel_search,create_gis_layer
Python
- Class names start with an uppercase letter.
- CamelCase is for class names only.
- Constant names are all-uppercase and with underscores as word separator.
- everything else (including table names and field names) should be all-lowercase with underscores as word separator.
- Names should not be Python keywords or standard library names
- Variable names should not start with _undersore (a trailing underscore_ is acceptable in local scope, though)
- Indexes in names should be avoided (e.g. file1, file2), except where they designate new versions of classes/functions (e.g. AddPersonWidget2)
- Names for Eden-specific subclasses of web2py classes and all classes which replace existing web2py classes should have the suffix "S3" (e.g.
AuthS3) - Names for Eden-specific methods (not overrides) in subclasses of web2py classes should start with the prefix "s3_" (e.g.
s3_logged_in()) - Eden-specific classes can have an "S3" prefix to their name in order to avoid name collisions, but ideally they should not (i.e.
BasicCRUDrather thanS3BasicCRUD) - Method names in Eden-specific classes do not need to (and thus should not) be prefixed
- avoid "s3" or "S3" prefixes in all other cases
DataModelsubclasses ins3dbshould start with the all-uppercase module prefix, e.g.DVRCaseModelCRUDMethodsubclasses ins3dbmust start with the all-lowercase module prefix plus underscore, e.g.pr_Contacts
Docstrings
All classes and functions must have docstrings that explain what the class or function is intended for and how it is to be used.
Exceptions can be made where the docstring would merely repeat documentation that already exists in another place, e.g. controllers, or standard interface methods inherited from (and thus documented in) a parent class.
The function description in the docstring should be a statement in the third person about what the function does — not an imperative instruction telling it what to do.
Acceptable style:
def card_details(r, idcard):
"""
Displays the details of the new registration card, and offers
a button to download the PDF.
Args:
(CRUDRequest) r: the request context
(IDCard) idcard: the new registration card
Returns:
DIV: the card contents
Raises:
ValueError: if the idcard is invalid
Note:
Card secrets will not be rendered.
"""
Type specifications for parameters and return value are optional, but strongly recommended where the types are not obvious.
In some trivial cases, PEP484-style type hints can also be acceptable - but are otherwise discouraged as they can easily impair comprehensibility, and not every syntax highlighter will aid the visual parsing of function annotations.
def card_details(r: CRUDRequest, idcard: IDCard) -> DIV:
"""
Displays the details of the new registration card, and offers
a button to download the PDF
Args:
r: the request context
idcard: the new registration card
Returns:
the card contents
Raises:
ValueError: if the idcard is invalid or expired
Note:
Card secrets will not be rendered.
"""
Internationalisation
- All user-visible strings and labels must be internationalised:
T("My string")