| Melange follows the [Google Python Style Guide](http://google-styleguide.googlecode.com/svn/trunk/pyguide.html); this document describes only those respects in which Melange's style differs from what is laid out in that document. |
| |
| The [SoC framework](SoCOverview.md), and |
| [Melange web applications](MelangeIntro.md) built upon it, are implemented in |
| Python (it is one of the programming language besides Java and Go which are currently supported by |
| [Google App Engine](http://code.google.com/appengine/)). The Google Python Style Guide and these amendments to it are a |
| list of dos and don'ts for Python contributions to the Melange project. |
| |
| The rules below are not guidelines or recommendations, but strict rules. You |
| may not disregard the rules we list below except as approved on a need-to-use |
| basis. But note also the advice on consistency at the end of the guide. |
| |
| If you have questions about these guidelines, you can send mail to the |
| [developer mailing list](MailingListsGuidelines#Developer_list.md). |
| Please put **Python style:** in the subject line to make it easier to locate |
| these discussions in the mailing list archives. |
| |
| Since this style guide is documented in the Melange wiki, it can be changed via |
| the existing [documentation review process](DocumentationReviews.md). However, |
| changes to the style guide should not be made lightly, since |
| [consistency](PythonStyleGuide#Conclusion.md) is one of the key goals |
| of this style guide, and old code will not necessarily be updated for new |
| style guide changes. |
| |
| # Summary |
| |
| ## Python Language Rules |
| |
| 1. [Imports](PythonStyleGuide#Imports.md): _Import only modules and only by name **(no wildcard imports)**_ |
| 1. [Function Arguments](PythonStyleGuide#Function_Arguments.md): _Pass positional arguments positionally and keyword arguments by keyword._ |
| 1. [Threading](PythonStyleGuide#Threading.md): _**For now, do not use** (but it is on its way as part of [issue 1596](https://code.google.com/p/soc/issues/detail?id=1596))_ |
| |
| ## Python Style Rules |
| |
| Programs are much easier to maintain when all files have a consistent |
| style. Here is the canonical Melange Python style. |
| |
| 1. [Indentation](PythonStyleGuide#Indentation.md): _**2** spaces (**no tabs**),_ **differs from [PEP8](http://www.python.org/dev/peps/pep-0008/)** |
| 1. [Python Interpreter](PythonStyleGuide#Python_Interpreter.md): _Variable, either omitted, `#!/usr/bin/python`, or `#!/usr/bin/python2.7`_ |
| 1. [Copyright And License Notices](PythonStyleGuide#Copyright_And_License_Notices.md): _Include in every file._ |
| 1. [Imports grouping, order and sorting](PythonStyleGuide#Imports_grouping_and_order.md): _One per line, grouped and ordered by packages, sorted alphabetically_ |
| 1. [Naming](PythonStyleGuide#Naming.md): _`foo_bar.py` not `foo-bar.py`,_ **some differ from [PEP8](http://www.python.org/dev/peps/pep-0008/)** |
| 1. [Conclusion](PythonStyleGuide#Conclusion.md): _Look at what's around you!_ |
| |
| # Python Language Rules |
| |
| ## Imports |
| |
| **What it is:** Mechanism for making use of code between modules. |
| |
| **Pros:** Very flexible relative to other languages. Packages, modules, classes, |
| functions, and fields all may be imported. |
| |
| **Cons:** `from foo import *` or `import bar.baz.Spar` is very nasty and can |
| lead to serious maintenance issues because it makes it hard to find module |
| dependencies. |
| |
| **Decision:** Import only modules. Use `as` to resolve name conflicts if |
| necessary. Use `from` for all imports below top-level. Use only absolute |
| imports; do not use relative imports. Do not import packages, classes, |
| functions, fields, or anything that is not a module. |
| |
| ``` |
| import os |
| import sys |
| |
| from models.graphics import views as graphics_views |
| from models.sounds import views as sounds_views |
| from sound.effects import echo |
| ... |
| echo.echofilter(input, output, delay=0.7, atten=4) |
| ``` |
| |
| Even if the module is in the same package, do not directly import the module |
| without the full package name. This might cause the package to be imported |
| twice and have unintended side effects. |
| |
| ## Function Arguments |
| |
| **What they are:** Arguments passed to functions either by position or by name. |
| |
| **Pros:** Passing arguments always by name can help code be self-documenting. |
| |
| **Cons:** Passing positional arguments by name can make a call site appear as |
| though all arguments are optional. Passing keyword arguments by position can |
| make a call site appear as though all arguments are required. |
| |
| **Decision:** Always pass positional arguments positionally and keyword |
| arguments by keyword. |
| |
| ## Threading |
| |
| Melange as of January 2013 is not thread-safe. Work to support thread safety |
| is happening as part of [https://code.google.com/p/soc/issues/detail?id=1596 |
| issue 1596 (on Google Code)], but for now avoid threading. |
| |
| # Python Style Rules |
| |
| ## Indentation |
| |
| _Note that this differs from |
| [PEP8](http://www.python.org/dev/peps/pep-0008/) |
| and instead follows the original Google Python Style guide from which |
| this style guide originated._ |
| |
| Indent your code blocks with 2 spaces. Never use tabs or mix tabs and |
| spaces. In cases of implied line continuation, you should align wrapped |
| elements either vertically, as per the examples in the line length |
| section; or using a hanging indent of **4** spaces (not 2, so as not to be |
| confused with an immediately-following nested block), in which case there |
| should be no argument on the first line. |
| |
| **Yes:** |
| |
| ``` |
| # Aligned with opening delimiter |
| foo = longFunctionName(var_one, var_two, |
| var_three, var_four) |
| |
| # 4-space hanging indent; nothing on first line |
| foo = longFunctionName( |
| var_one, var_two, var_three, |
| var_four) |
| ``` |
| |
| **No:** |
| |
| ``` |
| # Stuff on first line forbidden |
| foo = longFunctionName(var_one, var_two, |
| var_three, var_four) |
| |
| # 2-space hanging indent forbidden |
| foo = longFunctionName( |
| var_one, var_two, var_three, |
| var_four) |
| ``` |
| |
| ### Python Interpreter |
| |
| Modules which are not intended for direct execution (and which have no effect if executed) should not include a shebang line. |
| |
| Modules intended for direct execution should begin with a shebang line specifying the Python interpreter used to execute the program, most likely `#!/usr/bin/python` or `#!/usr/bin/python2.7`. |
| |
| ## Copyright And License Notices |
| |
| Every module should feature the following either at the top or just below |
| the module's shebang and blank-comment-following-shebang lines. |
| |
| ``` |
| # Copyright [current year] the Melange authors. |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| ``` |
| |
| ## Imports grouping and order |
| |
| Imports should be on separate lines, e.g.: |
| |
| **Yes:** |
| |
| ``` |
| import os |
| import sys |
| ``` |
| |
| **No:** |
| |
| ``` |
| import sys, os |
| ``` |
| |
| Imports are always put at the top of the file, just after any module |
| comments and `__doc__` strings and before module globals and constants. |
| Imports should be grouped with the order being most generic to least |
| generic: |
| |
| * standard library imports |
| * third-party library imports |
| * Google App Engine imports |
| * django framework imports |
| * SoC framework imports |
| * SoC-based module imports |
| * application specific imports |
| * imports from "tests/" - test utilities and Melange-specific test modules |
| |
| Sorting should be done alphabetically. |
| |
| ``` |
| import a_standard |
| import b_standard |
| |
| import a_third_party |
| import b_third_party |
| |
| from a_soc import f |
| from a_soc import g |
| from b_soc import d |
| ``` |
| |
| Resolution of clashing names between soc-framework and soc-module modules should be done by prefixing the soc-module module with the name of the soc-module from which it was imported: |
| |
| ``` |
| from soc.views.helper import url_patterns |
| from soc.modules.gsoc.views.helper import url_patterns as gsoc_url_patterns |
| ``` |
| |
| ## Naming |
| |
| ### Names to avoid |
| |
| * single character names, except for counters or iterators |
| * dashes (`-`) in any package/module name |
| * `__double_leading_and_trailing_underscore__` names (reserved by Python) |
| |
| ### Naming convention |
| |
| _Note that some naming conventions differ from |
| [PEP8](http://www.python.org/dev/peps/pep-0008/) |
| and instead follow the original Google Python Style guide from which |
| this style guide originated._ |
| |
| * "Internal" means internal to a module or protected or private within a class. |
| * Prepending a single underscore (`_`) has some support for protecting module variables and functions (not included with `import * from`). |
| * Prepending a double underscore (`__`) to an instance variable or method effectively serves to make the variable or method private to its class (using name mangling). |
| * Place related classes and top-level functions together in a module. Unlike Java, there is no need to limit yourself to one class per module. However, make sure the classes and top-level functions in the same module have [high cohesion](http://en.wikipedia.org/wiki/Cohesion_(computer_science)). |
| * Use `CapWords` for class names, but `lower_with_under.py` for module names. |
| |
| ### Naming examples |
| |
| | **Type** | **Public** | **Internal** | |
| |:---------|:-----------|:-------------| |
| | _Packages_ | `lower_with_under` | | |
| | _Modules_ | `lower_with_under` | `_lower_with_under` | |
| | _Classes_ | `CapWords` | `_CapWords` | |
| | _Exceptions_ | `CapWords` | | |
| | _Functions_ | `firstLowerCapWords()` | `_firstLowerCapWords()` | |
| | _Global/Class Constants_ | `CAPS_WITH_UNDER` | `_CAPS_WITH_UNDER` | |
| | _Global/Class Variables_ | `lower_with_under` | `_lower_with_under` | |
| | _Instance Variables_ | `lower_with_under` | `_lower_with_under` _(protected)_ or `__lower_with_under` _(private)_ | |
| | _Method Names_<sup>*</sup> | `firstLowerCapWords()` | `_firstLowerCapWords()` _(protected)_ or `__firstLowerCapWords()` _(private)_ | |
| | _Function/Method Parameters_ | `lower_with_under` | | |
| | _Local Variables_ | `lower_with_under` | | |
| |
| <sup>*</sup> Consider just using |
| [direct access to public attributes](PythonStyleGuide#Access_control.md) |
| in preference to getters and setters, as function calls are expensive |
| in Python, and `property` can be used later to turn attribute access into a |
| function call without changing the access syntax. |
| |
| ## Conclusion |
| |
| _BE CONSISTENT._ |
| |
| If you are editing code, take a few minutes to look at the code around |
| you and determine its style. If spaces are used around the `if` clauses, |
| you should, too. If the comments have little boxes of stars around them, |
| make your comments have little boxes of stars around them, too. |
| |
| The point of having style guidelines is to have a common vocabulary |
| of coding so people can concentrate on what you are saying rather than |
| on how you are saying it. We present global style rules here so people |
| know the vocabulary, but local style is also important. If code you add |
| to a file looks drastically different from the existing code around it, |
| it throws readers out of their rhythm when they go to read it. Try to |
| avoid this. |
| |
| |
| --- |
| |
| _Copyright 2008 Google Inc._ |
| _This work is licensed under a_ |
| [Creative Commons Attribution 2.5 License](http://soc.googlecode.com/svn/wiki/html/licenses/cc-by-attribution-2_5.html). |
| [](http://creativecommons.org/licenses/by/2.5/) |