Converted PythonStyleGuide.md
diff --git a/PythonStyleGuide.md b/PythonStyleGuide.md new file mode 100644 index 0000000..c7132e9 --- /dev/null +++ b/PythonStyleGuide.md
@@ -0,0 +1,284 @@ +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/) \ No newline at end of file
diff --git a/PythonStyleGuide.wiki b/PythonStyleGuide.wiki deleted file mode 100644 index 1d18a16..0000000 --- a/PythonStyleGuide.wiki +++ /dev/null
@@ -1,284 +0,0 @@ -#summary Style guide for Python code contributed to Melange -#labels Contents-Complete,Phase-Guidelines,Importance-Featured,Featured - -Melange follows the [http://google-styleguide.googlecode.com/svn/trunk/pyguide.html Google Python Style Guide]; this document describes only those respects in which Melange's style differs from what is laid out in that document. - -The [SoCOverview SoC framework], and -[MelangeIntro Melange web applications] built upon it, are implemented in -Python (it is one of the programming language besides Java and Go which are currently supported by -[http://code.google.com/appengine/ Google App Engine]). 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 -[MailingListsGuidelines#Developer_list developer mailing list]. -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 [DocumentationReviews documentation review process]. However, -changes to the style guide should not be made lightly, since -[PythonStyleGuide#Conclusion consistency] 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 == - - # [PythonStyleGuide#Imports Imports]: _Import only modules and only by name *(no wildcard imports)*_ - # [PythonStyleGuide#Function_Arguments Function Arguments]: _Pass positional arguments positionally and keyword arguments by keyword._ - # [PythonStyleGuide#Threading Threading]: _*For now, do not use* (but it is on its way as part of [https://code.google.com/p/soc/issues/detail?id=1596 issue 1596])_ - -== Python Style Rules == - -Programs are much easier to maintain when all files have a consistent -style. Here is the canonical Melange Python style. - - # [PythonStyleGuide#Indentation Indentation]: _*2* spaces (*no tabs*),_ *differs from [http://www.python.org/dev/peps/pep-0008/ PEP8]* - # [PythonStyleGuide#Python_Interpreter Python Interpreter]: _Variable, either omitted, `#!/usr/bin/python`, or `#!/usr/bin/python2.7`_ - # [PythonStyleGuide#Copyright_And_License_Notices Copyright And License Notices]: _Include in every file._ - # [PythonStyleGuide#Imports_grouping_and_order Imports grouping, order and sorting]: _One per line, grouped and ordered by packages, sorted alphabetically_ - # [PythonStyleGuide#Naming Naming]: _`foo_bar.py` not `foo-bar.py`,_ *some differ from [http://www.python.org/dev/peps/pep-0008/ PEP8]* - # [PythonStyleGuide#Conclusion Conclusion]: _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], but for now avoid threading. - -= Python Style Rules = - -== Indentation == - -_Note that this differs from -[http://www.python.org/dev/peps/pep-0008/ PEP8] -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 -[http://www.python.org/dev/peps/pep-0008/ PEP8] -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 [http://en.wikipedia.org/wiki/Cohesion_(computer_science) high cohesion]. - * 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_^*^ || `firstLowerCapWords()` || `_firstLowerCapWords()` _(protected)_ or `__firstLowerCapWords()` _(private)_ || -|| _Function/Method Parameters_ || `lower_with_under` || || -|| _Local Variables_ || `lower_with_under` || || - -^*^ Consider just using -[PythonStyleGuide#Access_control direct access to public attributes] -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_ -[http://soc.googlecode.com/svn/wiki/html/licenses/cc-by-attribution-2_5.html Creative Commons Attribution 2.5 License]. -[http://creativecommons.org/licenses/by/2.5/ http://soc.googlecode.com/svn/wiki/html/licenses/cc-by-2_5-88x31.png] \ No newline at end of file