-
Notifications
You must be signed in to change notification settings - Fork 619
Code. Guide
The purpose of this document is to define guidelines for designing the API of vispy.
In case of doubt, follow PEP8.
Each public element (methods, classes, properties) of the API should be documented, so that we can use Sphinx to automatically generate the API documentation. We shall follow numpy's docstring convention.
Each module should have a docstring that briefly describes its purpose.
Private methods/classes should be documented too (if necessary) to help fellow coders.
- methods use underscores: do_something()
- attributes and properties as well.
- Class names are UpperCamelCase
- Module names are all lowercase, underscores should be avoided.
To help distinguish users between properties and methods, both should be carefully named: properties should clearly be nouns, methods should clearly be verbs.
There are no public attributes; attributes are made public via a property, such that it can be properly documented, inputs can be checked, and it can be decorated if necessary.
We make use of properties where we can. As a rule of thumb, in case there is a value that can be get (and set), there should be a property, unless setting/getting that value would take a long time.
Here are a few ways to use properties, we should pick one and use that throughout:
class Example(object):
def _get_spam(self):
return self._spam
def _set_spam(self, value):
self._spam = value
spam = property(_get_spam, _set_spam, None, "Docstring goes here?")
@Property
def foo():
""" Docstring goes here.
"""
fget(self):
return self._foo
fset(self, value):
self._foo = value
return locals() # Necessary at least with the best Property decorator that I know of
@property
def bar(self):
""" Docstring goes here.
"""
return self._bar
@bar.setter
def bar(self, value):
self._bar = value
[AK] I prefer the middle one, but the last one makes sense as well.
Use of private attributes should ideally be limited to within the class that defines them and classes that are defined in the same module. Private attributes are in no way part of the public API.
Each module should contain different code sections: imports, different groups of classes and functions, etc. Putting salient comments to separate these sections make the code easier to read. We could use for example the following code section headers:
# -----------------------------------------------------------------------------
# Code section
# -----------------------------------------------------------------------------
There should be 77 dashes so that the total number of characters per line is 79 (PEP8 recommandation).
The first section header should be # Imports
with all imports in the following order:
- native Python modules
- third-party modules
- vispy modules
A docstring explaining what the module does must appear before the first Imports section.
Within a class containing many methods, we can also put subsections like this:
class A(object):
"""Docstring..."""
# Foo methods
# -----------
def foo1(self):
pass
def foo2(self):
pass
# Bar methods
# -----------
def bar1(self):
pass
Comments should always start with a capital letter and end with a dot:
# We do this because we need to.
self.do_this()
We should write as many unit tests as possible and target a high test coverage. Every sub-package must contains a tests
subfolder with a __init__.py
file, and a test_mymodule.py
for each mymodule.py
module in the sub-package. Each test_mymodule.py
module should contain one or several test_xxx
functions. Fixtures setup
and teardown
can be defined in the test modules or in the tests
folder.
Vispy does not rely on automatic code formatting toolsk. Consistent style and formatting is enforced by hand fo now.
Example tools: Black
Reasons:
- Black would split long argument lists in functions on many lines, making the definition too long. See discussion.