ebuild: fetch: Flatten conditionals in _get_fetch_resume_size
[portage.git] / DEVELOPING
1 Code Guidelines
2 ---------------
3 A few code guidelines to try to stick to, please comment if none of these make
4 sense, they are pretty basic and mostly apply to old code.  However for people
5 who are looking at current code, they make take up bad habits that exist in the
6 current codebase.
7
8 Python Version
9 --------------
10
11 Python 2.6 is the minimum supported version, since it is the first version to
12 support Python 3 syntax. All exception handling should use Python 3 'except'
13 syntax, and the print function should be used instead of Python 2's print
14 statement (from __future__ import print_function).
15
16 Dependencies
17 ------------
18
19 Python and Bash should be the only hard dependencies. Any other dependencies,
20 including external Python modules that are not included with Python itself,
21 must be optionally enabled by run-time detection.
22
23 Tabs
24 ----
25
26 The current code uses tabs, not spaces.  Keep whitespace usage consistent
27 between files.  New files should use tabs.
28
29 Line-Wrapping
30 -------------
31
32 Lines should typically not be longer than 80 characters; if they are an attempt
33 should be made to wrap them.  Move code to the line below and indent once (\t).
34
35 errors.append(MalformedMetadata(
36         errors.DESCRIPTION_TOO_LONG_ERROR % \
37         (length, max_desc_len),
38         attr='DESCRIPTION.toolong')
39
40 Do not do this:
41
42 errors.append(MalformedMetadata(
43               errors.DESCRIPTION_TOO_LONG_ERROR % \
44               (length, max_desc_len),
45               attr='DESCRIPTION.toolong')
46
47 The mixing of tabs and spaces means other developers can't read what you did.
48 This is why the python peps state spaces over tabs; because with spaces the line
49 wrapping is always clear (but you cannot convert spaces as easily as tabwidth).
50
51 Comparisons
52 -----------
53
54 if foo != None
55
56 should be replaced with:
57
58 if foo is not None:
59
60 Is not does a reference comparison (address1 = address2 basically) and
61 the == forces a by value compare (with __eq__())
62
63 Dict Lookups
64 ------------
65
66 Try not to use has_key, you can use
67
68 if foo in dict
69
70 instead of if dict.has_key(foo)
71
72 Also don't do stuff like:
73
74 if foo in dict and dict[foo]:
75
76 Generally you can do two things here, if you are messing with defaults..
77
78 dict.get(foo, some_default)
79
80 will try to retrieve foo from dict, if there is a KeyError, will insert foo
81 into dict with the value of some_default.  This method is preferred in cases where
82 you are messing with defaults:
83
84 try:
85         dict[foo]
86 except KeyError:
87         dict[foo] = default_value
88
89 The get call is nicer (compact) and faster (try,except are slow).
90
91 Exceptions
92 ----------
93
94 Don't use the format raise Exception, "string"
95 It will be removed in py3k.
96
97 YES:
98   raise KeyError("No key")
99
100 NO:
101   raise KeyError, "No key"
102
103 Imports
104 -------
105
106 Import things one per line
107
108 YES:
109   import os
110   import time
111   import sys
112
113 NO:
114   import os,sys,time
115
116 When importing from a module, you may import more than 1 thing at a time.
117
118 YES:
119   from portage.module import foo, bar, baz
120
121 Multiline imports are ok (for now :))
122
123 Try to group system and package imports separately.
124
125 YES:
126   import os
127   import sys
128   import time
129
130   from portage.locks import lockfile
131   from portage.versions import vercmp
132
133 NO:
134   import os
135   import portage
136   import portage.util
137   import time
138   import sys
139
140 Try not to import large numbers of things into the namespace of a module.
141 I realize this is done all over the place in current code but it really makes it
142 a pain to do code reflection when the namespace is cluttered with identifiers
143 from other modules.
144
145 YES:
146
147 from portage import output
148
149 NO:
150
151 from portage.output import bold, create_color_func, darkgreen, \
152   green, nocolor, red, turquoise, yellow
153
154 The YES example imports the 'output' module into the current namespace.
155 The negative here is having to use output.COLOR all over the place instead of
156 just COLOR.  However it means during introspection of the current namespace
157 'green','red', 'yellow', etc. will not show up.
158
159 The NO example just imports a set of functions from the output module.  It is
160 somewhat annoying because the import line needs to be modified when functions
161 are needed and often unused functions are left in the import line until someone
162 comes along with a linter to clean up (does not happen often).
163
164
165 Releases
166 --------
167
168 First update the NEWS and RELEASE-NOTES files and commit.
169
170 Second create a git tag for this release:
171         git tag v2.2.8
172
173 Then create the tarball and run the tests:
174         ./mkrelease.sh --changelog-rev v2.2.7 --tag --runtests 2.2.8
175 Make sure you have all supported python versions installed first
176 (see PYTHON_SUPPORTED_VERSIONS in runtests.sh).
177
178 Version bump the ebuild and verify it can re-install itself:
179         emerge portage
180         emerge portage
181
182 Publish the results (no going back now):
183         - Push the new git tag
184         - Upload the tarball
185         - Commit the new ebuild version
186
187 Close the bugs blocking the tracker bug for this release.