repoman: export GPG_TTY for bug #477728
[portage.git] / DEVELOPING
index 01eb9bd42695b28f375c29eeac47991dae2083c4..5f15e1590a481ebf7f5548a449facc96270f5546 100644 (file)
@@ -1,35 +1,57 @@
 Code Guidelines
 ---------------
-A few code guidelines to try to stick to, please comment of none of these make
+A few code guidelines to try to stick to, please comment if none of these make
 sense, they are pretty basic and mostly apply to old code.  However for people
 who are looking at current code, they make take up bad habits that exist in the
 current codebase.
 
-Strings
--------
-Try not to use the functions in the string module, they are deprecated.
+Python Version
+--------------
 
-string.join(<iterable>," ")
+Python 2.6 is the minimum supported version, since it is the first version to
+support Python 3 syntax. All exception handling should use Python 3 'except'
+syntax, and the print function should be used instead of Python 2's print
+statement (from __future__ import print_function).
 
-should be replaced with:
+Dependencies
+------------
 
-" ".join(<iterable>)
+Python and Bash should be the only hard dependencies. Any other dependencies,
+including external Python modules that are not included with Python itself,
+must be optionally enabled by run-time detection.
 
-and:
+Tabs
+----
 
-string.split(string, delimeter)
+The current code uses tabs, not spaces.  Keep whitespace usage consistent
+between files.  New files should use tabs.
 
-should be replaced with:
+Line-Wrapping
+-------------
 
-string.split(delimeter)
+Lines should typically not be longer than 80 characters; if they are an attempt
+should be made to wrap them.  Move code to the line below and indent once (\t).
 
-Nearly all other methods in string work on string objects and have similar calling
-conventions.
+errors.append(MalformedMetadata(
+       errors.DESCRIPTION_TOO_LONG_ERROR % \
+       (length, max_desc_len),
+       attr='DESCRIPTION.toolong')
+
+Do not do this:
+
+errors.append(MalformedMetadata(
+              errors.DESCRIPTION_TOO_LONG_ERROR % \
+              (length, max_desc_len),
+              attr='DESCRIPTION.toolong')
+
+The mixing of tabs and spaces means other developers can't read what you did.
+This is why the python peps state spaces over tabs; because with spaces the line
+wrapping is always clear (but you cannot convert spaces as easily as tabwidth).
 
 Comparisons
 -----------
 
-if foo == None
+if foo != None
 
 should be replaced with:
 
@@ -65,3 +87,76 @@ except KeyError:
        dict[foo] = default_value
 
 The get call is nicer (compact) and faster (try,except are slow).
+
+Exceptions
+----------
+
+Don't use the format raise Exception, "string"
+It will be removed in py3k.
+
+YES:
+  raise KeyError("No key")
+
+NO:
+  raise KeyError, "No key"
+
+Imports
+-------
+
+Import things one per line
+
+YES:
+  import os
+  import time
+  import sys
+
+NO:
+  import os,sys,time
+
+When importing from a module, you may import more than 1 thing at a time.
+
+YES:
+  from portage.module import foo, bar, baz
+
+Multiline imports are ok (for now :))
+
+Try to group system and package imports separately.
+
+YES:
+  import os
+  import sys
+  import time
+
+  from portage.locks import lockfile
+  from portage.versions import vercmp
+
+NO:
+  import os
+  import portage
+  import portage.util
+  import time
+  import sys
+
+Try not to import large numbers of things into the namespace of a module.
+I realize this is done all over the place in current code but it really makes it
+a pain to do code reflection when the namespace is cluttered with identifiers 
+from other modules.
+
+YES:
+
+from portage import output
+
+NO:
+
+from portage.output import bold, create_color_func, darkgreen, \
+  green, nocolor, red, turquoise, yellow
+
+The YES example imports the 'output' module into the current namespace.
+The negative here is having to use output.COLOR all over the place instead of
+just COLOR.  However it means during introspection of the current namespace
+'green','red', 'yellow', etc. will not show up.
+
+The NO example just imports a set of functions from the output module.  It is
+somewhat annoying because the import line needs to be modified when functions
+are needed and often unused functions are left in the import line until someone
+comes along with a linter to clean up (does not happen often).