Style Guidelines
The goal of these guidelines is encourage clean, maintainable code that passes our specific linter and formatter (ruff).
Please follow these guidelines when submitting code.
Style Hierarchy (Priority Order)
- Project Specific Exceptions (Highest Priority - Overrides everything else)
- Google Python Style Guide (Medium Priority - Applied where not overridden)
- PEP 8 (Lowest Priority - Fallback)
1. Project Specific Overrides (HIGHEST PRIORITY)
Naming Conventions (Strict)
- Initialisms & Acronyms: Treat them as full words (CamelCase or snake_case).
- Good:
HtmlRequest,html_request,NatoCountry,nato_country - Bad:
HTMLRequest,h_t_m_l_request,NATOCountry
- Good:
Formatting & Linting
- Formatter: Use
ruffrules (no manual formatting adjustments). - Line Length: 88 characters (Overrides Google's 80).
- Linter: Optimize code to pass
ruff. - No Formatting Exceptions: Do not use
# fmt: offunless absolutely critical. - Final Empty Line: Files should end with an empty blank line.
Imports
- Allowed: Importing individual classes or functions is PERMITTED (Overrides Google's "packages only" rule).
- Absolute Imports: Use absolute imports for all packages/modules whenever possible.
Comments (Clean Code Style)
- Philosophy: "Comments are a failure to express code in the language itself."
- Avoid: Do not write comments for obvious code.
- Refactor First: If a block needs a comment to explain what it does, rename variables/functions or extract the code into a well-named function instead.
- Extraction: If you feel the need to comment a section, extract it.
- License: License boilerplate is not required in every file.
Function Length (Strict)
- Goal: Short functions.
- Guideline: "~10 statements should be plenty. Note this is statements, not lines"
- Smell: Any function > 9 statements is a candidate for refactoring.
- Action: Break large functions into many small, single-purpose functions.
Function Order
- Goal: Easy to read the file top down
- Guidelines::
- The top function should be a public function, and then order of the following function is listed in the order they would be called.
- After that, the next public function not yet called is listed.
- For example:
def main(): _fn_a() fn_b() _fn_c() def _fn_a(): fn_d() def fn_d(): pass def fn_b() _fn_a() def _fn_c(): pass def fn_g(): _fn_h() def _fn_h(): pass
JSON Normalization
- Format: Multiline (pretty print), 4-space indent, keys sorted alphabetically.
Type Hints
- Mandatory: Use type hints for all function signatures except in
examples/andtests/
2. Google Python Style Guide (Applied where not overridden)
Code Structure & Logic
- Main: Executable files must always use
if __name__ == '__main__': main(). - Global State: Avoid mutable global state. Module-level constants should be
ALL_CAPS. - Nested Functions: Use only for closures/decorators. Do not nest just to hide code (use
_private_module_funcinstead). - Comprehensions: Allowed for simple cases. Prohibited if they contain multiple
forclauses or complex filter expressions. - Default Arguments: NEVER use mutable objects (lists, dicts) as default values. Use
Noneand initialize inside the function. - True/False Evaluations: Use implicit false.
- Yes:
if not users: - No:
if len(users) == 0:
- Yes:
- Lambdas: One-liners only. If it's longer, define a function.
- Conditional Expressions: Allowed for simple cases (
x = y if c else z). - Power Features: Avoid metaclasses, bytecode access, reflection (
getattrallowed only if necessary), and__del__.
Classes & OOP
- Properties: Use
@propertyfor simple data access or light logic. - Accessors: Use
get_foo()/set_foo()only if the logic is complex or expensive. Otherwise, use public attributes or properties. - Inheritance: Inherit from
Exceptionfor custom errors (suffix withError). - Decorators: Must be clearly documented. Avoid external dependencies (DB, sockets) in decorators (import time safety).
Strings & TODOs
- Formatting: Prefer f-strings (
f"Name: {name}") over%or.format(). - Accumulation: Do not use
+to accumulate strings in a loop (O(n^2)). Uselist.append()and''.join(). - TODOs: Format:
# TODO(username): description of task.
Exceptions
- Handling: NEVER use catch-all
except:orexcept Exception:. Catch specific errors. - Raising: Do not raise generic
Exception. UseValueError,TypeError, or custom classes. - Asserts: Do not use
assertfor control flow or validation; use it only for tests or internal invariants.
Docstrings (API Documentation)
- Requirement: Mandatory for all public modules, classes, and functions under
src/scadview/api/ - Format: Three double quotes
""". - Structure:
"""One line summary. Extended description. Args: arg_name: Description. Returns: Description. Raises: ErrorType: Description. """
3. PEP 8 (Fallback)
- Use standard PEP 8 conventions for any naming or style rules not covered by the above.