
Coding Style
************

In order to contribute code to the project, you must diligently follow
the style rules describe in this chapter. Having a clean and
structured code is very important for our development lifecycle, and
not compliant code will most likely be rejected.

Essentially Cuckoo's code style is based on PEP 8 - Style Guide for
Python Code and PEP 257 -- Docstring Conventions.


Formatting
==========


Copyright header
----------------

All source code files must start with the following copyright header:

   # Copyright (C) 2010-2013 Claudio Guarnieri.
   # Copyright (C) 2014-2016 Cuckoo Foundation.
   # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org
   # See the file 'docs/LICENSE' for copying permission.


Indentation
-----------

The code must have a 4-spaces-tabs indentation. Since Python enforce
the indentation, make sure to configure your editor properly or your
code might cause malfunctioning.


Maximum Line Length
-------------------

Limit all lines to a maximum of 79 characters.


Blank Lines
-----------

Separate the class definition and the top level function with one
blank line. Methods definitions inside a class are separated by a
single blank line:

   class MyClass:
       """Doing something."""

       def __init__(self):
           """Initialize"""
           pass

       def do_it(self, what):
           """Do it.
           @param what: do what.
           """
           pass

Use blank lines in functions, sparingly, to isolate logic sections.
Import blocks are separated by a single blank line, import blocks are
separated from classes by one blank line.


Imports
-------

Imports must be on separate lines. If you're importing multiple
objects from a package, use a single line:

   from lib import a, b, c

**NOT**:

   from lib import a
   from lib import b
   from lib import c

Always specify explicitly the objects to import:

   from lib import a, b, c

**NOT**:

   from lib import *


Strings
-------

Strings must be delimited by double quotes (").


Printing and Logging
--------------------

We discourage the use of "print()": if you need to log an event please
use Python's "logging" which is already initialized by Cuckoo.

In your module add:

   import logging
   log = logging.getLogger(__name__)

And use the "log" handle, for more details refer to the Python
documentation.

In case you really need to print a string to standard output, use the
"print()" function:

   print("foo")

**NOT** the statement:

   print "foo"


Checking for keys in data structures
------------------------------------

When checking for a key in a data structure use the clause "in"
instead of methods like "has_key()", for example:

   if "bar" in foo:
       do_something(foo["bar"])


Exceptions
==========

Custom exceptions must be defined in the
*lib/cuckoo/common/exceptions.py* file or in the local module if the
exception should not be global.

The following is the current Cuckoo exceptions chain:

   .-- CuckooCriticalError
   |   |-- CuckooStartupError
   |   |-- CuckooDatabaseError
   |   |-- CuckooMachineError
   |   `-- CuckooDependencyError
   |-- CuckooOperationalError
   |   |-- CuckooAnalysisError
   |   |-- CuckooProcessingError
   |   `-- CuckooReportError
   `-- CuckooGuestError

Beware that the use of "CuckooCriticalError" and its child exceptions
will cause Cuckoo to terminate.


Naming
------

Custom exception names must start with "Cuckoo" and end with "Error"
if it represents an unexpected malfunction.


Exception handling
------------------

When catching an exception and accessing its handle, use "as e":

   try:
       foo()
   except Exception as e:
       bar()

**NOT**:

   try:
       foo()
   except Exception, something:
       bar()

It's a good practice use "e" instead of "e.message".


Documentation
=============

All code must be documented in docstring format, see PEP 257 --
Docstring Conventions. Additional comments may be added in logical
blocks to make the code easier to understand.


Automated testing
=================

We believe in automated testing to provide high quality code and avoid
dumb bugs. When possible, all code must be committed with proper unit
tests. Particular attention must be placed when fixing bugs: it's good
practice to write unit tests to reproduce the bug. All unit tests and
fixtures are placed in the tests folder in the Cuckoo root. We adopted
Nose as unit testing framework.
