public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/depres/, roverlay/config/, roverlay/, roverlay/rpackage/, ...
@ 2012-06-22 18:13 André Erdmann
  0 siblings, 0 replies; only message in thread
From: André Erdmann @ 2012-06-22 18:13 UTC (permalink / raw
  To: gentoo-commits

commit:     7bcd6b886d402fda204ffe87c3e89b64207b4c88
Author:     André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Jun 22 18:08:17 2012 +0000
Commit:     André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Jun 22 18:08:17 2012 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=7bcd6b88

comments and minor fixes

	deleted:    roverlay/Makefile
	modified:   roverlay/config/const.py
	modified:   roverlay/config/loader.py
	modified:   roverlay/config/tree.py
	modified:   roverlay/config/util.py
	deleted:    roverlay/depres/Makefile
	modified:   roverlay/depres/channels.py
	modified:   roverlay/depres/communication.py
	modified:   roverlay/depres/depenv.py
	modified:   roverlay/depres/depresolver.py
	modified:   roverlay/depres/deprule.py
	modified:   roverlay/depres/listeners.py
	modified:   roverlay/depres/simpledeprule.py
	modified:   roverlay/ebuild/abstractcomponents.py
	modified:   roverlay/ebuild/creation.py
	modified:   roverlay/ebuild/depres.py
	modified:   roverlay/ebuild/ebuilder.py
	modified:   roverlay/ebuild/evars.py
	modified:   roverlay/manifest/helpers.py
	modified:   roverlay/metadata/__init__.py
	modified:   roverlay/metadata/abstractnodes.py
	modified:   roverlay/metadata/nodes.py
	modified:   roverlay/overlay/__init__.py
	modified:   roverlay/overlay/category.py
	modified:   roverlay/overlay/package.py
	modified:   roverlay/rpackage/descriptionfields.py
	modified:   roverlay/rpackage/descriptionreader.py

---
 roverlay/Makefile                      |    3 -
 roverlay/config/const.py               |    2 +-
 roverlay/config/loader.py              |   33 +++++++--
 roverlay/config/tree.py                |   18 +++--
 roverlay/config/util.py                |   22 ++++--
 roverlay/depres/Makefile               |    1 -
 roverlay/depres/channels.py            |   18 ++++-
 roverlay/depres/communication.py       |    8 ++-
 roverlay/depres/depenv.py              |   13 +++-
 roverlay/depres/depresolver.py         |    4 +-
 roverlay/depres/deprule.py             |   10 ++-
 roverlay/depres/listeners.py           |   12 +++
 roverlay/depres/simpledeprule.py       |    4 +-
 roverlay/ebuild/abstractcomponents.py  |   36 +++++++++-
 roverlay/ebuild/creation.py            |   82 ++++++++++++++-------
 roverlay/ebuild/depres.py              |   23 ++++++-
 roverlay/ebuild/ebuilder.py            |   30 ++++++--
 roverlay/ebuild/evars.py               |   26 ++++++-
 roverlay/manifest/helpers.py           |    2 -
 roverlay/metadata/__init__.py          |    1 -
 roverlay/metadata/abstractnodes.py     |    5 +-
 roverlay/metadata/nodes.py             |    8 +--
 roverlay/overlay/__init__.py           |   11 +--
 roverlay/overlay/category.py           |    3 +-
 roverlay/overlay/package.py            |   18 +++--
 roverlay/rpackage/descriptionfields.py |   22 ++++---
 roverlay/rpackage/descriptionreader.py |  123 ++++++++++++++++++++-----------
 27 files changed, 376 insertions(+), 162 deletions(-)

diff --git a/roverlay/Makefile b/roverlay/Makefile
deleted file mode 100644
index bfbbe98..0000000
--- a/roverlay/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-.PHONY: default
-default: ../Makefile
-	cd .. && make

diff --git a/roverlay/config/const.py b/roverlay/config/const.py
index a69a33a..18e4614 100644
--- a/roverlay/config/const.py
+++ b/roverlay/config/const.py
@@ -8,7 +8,7 @@ import time
 _CONSTANTS = dict (
 	DESCRIPTION = dict (
 		field_separator  = ':',
-		comment_char     = '#',
+		comment_chars    = '#;',
 		list_split_regex = '\s*[,;]{1}\s*',
 		file_name        = 'DESCRIPTION',
 	),

diff --git a/roverlay/config/loader.py b/roverlay/config/loader.py
index 62f0980..5983b72 100644
--- a/roverlay/config/loader.py
+++ b/roverlay/config/loader.py
@@ -1,4 +1,4 @@
-# R overlay -- config module
+# R overlay -- config module, config file loader
 # Copyright 2006-2012 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 
@@ -18,6 +18,12 @@ class ConfigLoader ( object ):
 
 
 	def __init__ ( self, config_tree, logger=None ):
+		"""Initializes a ConfigLoader.
+
+		arguments:
+		* config_tree -- ConfigTree
+		* logger      -- logger to use, defaults to config_tree's logger
+		"""
 		self.ctree = config_tree
 
 		self.config_root = None
@@ -28,6 +34,13 @@ class ConfigLoader ( object ):
 	# --- end of __init__ (...) ---
 
 	def _setval ( self, path, value, allow_empty_value=False ):
+		"""Sets a value in the config tree.
+
+		arguments:
+		* path              -- config path
+		* value             -- config value
+		* allow_empty_value --
+		"""
 		self.ctree._findpath (
 			path,
 			value=value,
@@ -39,6 +52,15 @@ class ConfigLoader ( object ):
 	# --- end of _setval (...) ---
 
 	def _config_entry ( self, cref, option, value, config_root ):
+		"""Adds a normal config entry to the assigned ConfigTree.
+
+		arguments:
+		* cref        -- reference to the config option's entry in the
+		                  CONFIG_ENTRY_MAP
+		* option      -- name of the config option
+		* value       -- value read from a config file (will be verified here)
+		* config_root -- ignored;
+		"""
 		# determine the config path
 		path = None
 		if 'path' in cref:
@@ -196,12 +218,12 @@ class ConfigLoader ( object ):
 
 	def _make_and_verify_value ( self, value_type, value ):
 		"""Prepares the value of a config option so that it can be used
-		in the ConfigLoader.
+		in the config.
 
 		arguments:
-		* value_type      -- type of the value,
-									 look above for explanation concerning this
-		* value           -- value to verify and transform
+		* value_type -- type of the value,
+							  look above for explanation concerning this
+		* value      -- value to verify and transform
 		"""
 
 		def to_int ( val, fallback_value=-1 ):
@@ -289,6 +311,7 @@ class ConfigLoader ( object ):
 		# --- end of fs_dir (...) ---
 
 		def repo ( val ):
+			"""To be removed. (FIXME)"""
 			if not val: return None
 
 			name, sepa, remainder = val.partition ( ':' )

diff --git a/roverlay/config/tree.py b/roverlay/config/tree.py
index b38bc2c..707aa8a 100644
--- a/roverlay/config/tree.py
+++ b/roverlay/config/tree.py
@@ -55,10 +55,12 @@ class ConfigTree ( object ):
 	# --- end of __init__ (...) ---
 
 	def get_loader ( self ):
+		"""Returns a ConfigLoader for this ConfigTree."""
 		return ConfigLoader ( self )
 	# --- end of get_loader (...) ---
 
-	def _findpath ( self, path,
+	def _findpath (
+		self, path,
 		root=None, create=False, value=None, forcepath=False, forceval=False
 	):
 		"""All-in-one method that searches for a config path.
@@ -66,13 +68,13 @@ class ConfigTree ( object ):
 		value to it.
 
 		arguments:
-		* path   -- config path as path list ([a,b,c]) or as path str (a.b.c)
-		* root   -- config root (dict expected).
-		             Uses self._config if None (the default)
-		* create -- create path if nonexistent
-		* value  -- assign value to the last path element
-		             an empty dict will be created if this is None and
-		             create is True
+		* path      -- config path as path list ([a,b,c]) or as path str (a.b.c)
+		* root      -- config root (dict expected).
+		                Uses self._config if None (the default)
+		* create    -- create path if nonexistent
+		* value     -- assign value to the last path element
+		                an empty dict will be created if this is None and
+		                create is True
 		* forcepath -- if set and True: do not 'normalize' path if path is a list
 		* forceval  -- if set and True: accept None as value
 		"""

diff --git a/roverlay/config/util.py b/roverlay/config/util.py
index c1aef66..ea70465 100644
--- a/roverlay/config/util.py
+++ b/roverlay/config/util.py
@@ -1,9 +1,14 @@
-# R Overlay -- config, <?>
+# R Overlay -- config, utility functions
 # Copyright 2006-2012 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 
 def get_config_path ( key ):
-	"""Creates a config path for key."""
+	"""Creates a config path for key.
+
+	arguments:
+	* key --
+
+	"""
 	_path = key.split ( '.' ) if isinstance ( key, str ) else key
 	if isinstance ( _path, ( list, tuple ) ):
 		# config paths are [ CAPSLOCK, CAPSLOCK,.... , lowercase item ]
@@ -12,14 +17,19 @@ def get_config_path ( key ):
 		return _path
 # --- end of get_config_path (...) ---
 
-def unquote ( _str ):
+def unquote ( _str, keep_going=False):
+	"""Removes enclosing quotes from a string.
+
+	arguments:
+	* _str --
+	* keep_going -- remove all enclosing quotes ("'"a"'" -> a)
+	"""
 	if len ( _str ) < 2: return _str
-	chars  = '"'
-	chars += "'"
+	chars  = '\"\''
 
 	for c in chars:
 		if _str [0] == c and _str [-1] == c:
-			return _str[1:-1]
+			return unquote ( _str[1:-1] ) if keep_going else _str[1:-1]
 
 	return _str
 # --- end of unquote (...) ---

diff --git a/roverlay/depres/Makefile b/roverlay/depres/Makefile
deleted file mode 120000
index d0b0e8e..0000000
--- a/roverlay/depres/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-../Makefile
\ No newline at end of file

diff --git a/roverlay/depres/channels.py b/roverlay/depres/channels.py
index 765d241..65d4d45 100644
--- a/roverlay/depres/channels.py
+++ b/roverlay/depres/channels.py
@@ -52,6 +52,7 @@ class EbuildJobChannel ( DependencyResolverChannel ):
 	# --- end of __init__ (...) ---
 
 	def close ( self ):
+		"""Closes this channel."""
 		if self._depdone >= 0:
 			# else already closed
 
@@ -64,7 +65,13 @@ class EbuildJobChannel ( DependencyResolverChannel ):
 	# --- end of close (...) ---
 
 	def set_resolver ( self, resolver, channel_queue, **extra ):
-		""" comment todo """
+		"""Assigns a resolver to this channel.
+
+		arguments:
+		* resolver      --
+		* channel_queue -- the queue where the resolver puts processed DepEnvs in
+		* **extra       -- ignored;
+		"""
 		if self._depres_master is None:
 			self._depres_master = resolver
 			self._depres_queue  = channel_queue
@@ -180,6 +187,10 @@ class EbuildJobChannel ( DependencyResolverChannel ):
 				return False
 		# --- end of handle_queue_item (...) ---
 
+
+		# loop until
+		#  (a) at least one dependency could not be resolved or
+		#  (b) all deps processed
 		while self._depdone < len ( self.dep_env_list ) and satisfiable:
 			# tell the resolver to start
 			self._depres_master.start()
@@ -187,6 +198,7 @@ class EbuildJobChannel ( DependencyResolverChannel ):
 			# wait for one result at least
 			satisfiable = handle_queue_item ( self._depres_queue.get() )
 
+			# and process all available results
 			while not self._depres_queue.empty() and satisfiable:
 				satisfiable = handle_queue_item ( self._depres_queue.get_nowait() )
 		# --- end while
@@ -197,6 +209,4 @@ class EbuildJobChannel ( DependencyResolverChannel ):
 		else:
 			if close_if_unresolvable: self.close()
 			return None
-
-
-	# --- end of join (...) ---
+	# --- end of satisfy_request (...) ---

diff --git a/roverlay/depres/communication.py b/roverlay/depres/communication.py
index 33e1e8f..943e2ca 100644
--- a/roverlay/depres/communication.py
+++ b/roverlay/depres/communication.py
@@ -65,7 +65,13 @@ class DependencyResolverChannel ( object ):
 	# --- end of __init__ (...) ---
 
 	def set_resolver ( self, resolver, channel_queue=None, **extra ):
-		"""comment todo."""
+		"""Assigns a resolver to this channel.
+
+		arguments:
+		* resolver      --
+		* channel_queue -- ignored;
+		* **extra       -- ignored
+		"""
 		self._depres_master = resolver
 	# --- end of set_resolver (...) ---
 

diff --git a/roverlay/depres/depenv.py b/roverlay/depres/depenv.py
index 889af9c..0cb81e8 100644
--- a/roverlay/depres/depenv.py
+++ b/roverlay/depres/depenv.py
@@ -22,12 +22,14 @@ class DepEnv ( object ):
 		self.status      = DepEnv.STATUS_UNDONE
 		self.resolved_by = None
 
-		# TODO: analyze dep_str: extract dep name, dep version, useless comments,...
+		# TODO: analyze dep_str:
+		#   extract dep name, dep version, useless comments,...
 
 	# --- end of __init__ (...) ---
 
 	def set_resolved ( self, resolved_by, append=False ):
-		"""Marks this DepEnv as resolved with resolved_by as corresponding portage package.
+		"""Marks this DepEnv as resolved with resolved_by as corresponding
+		portage package.
 
 		arguments:
 		* resolved_by -- resolving portage package
@@ -39,7 +41,9 @@ class DepEnv ( object ):
 			# useful?
 			raise Exception ( "appending is not supported..." )
 		else:
-			raise Exception ( "dependency is already resolved and append is disabled." )
+			raise Exception (
+				"dependency is already resolved and append is disabled."
+			)
 
 		# add RESOLVED status
 		self.status |= DepEnv.STATUS_RESOLVED
@@ -50,7 +54,8 @@ class DepEnv ( object ):
 		"""Marks this DepEnv as unresolvable.
 
 		arguments:
-		force -- force unresolvable status even if this DepEnv is already resolved
+		force -- force unresolvable status even if this DepEnv
+		          is already resolved
 		"""
 		if force or not self.status & DepEnv.STATUS_RESOLVED:
 			self.resolved_by = None

diff --git a/roverlay/depres/depresolver.py b/roverlay/depres/depresolver.py
index cb70c14..3b0e481 100644
--- a/roverlay/depres/depresolver.py
+++ b/roverlay/depres/depresolver.py
@@ -294,8 +294,8 @@ class DependencyResolver ( object ):
 				self._report_event ( 'UNRESOLVABLE', dep_env )
 
 				if channel_id in self._depqueue_done:
-					## todo/fixme/whatever: this 'if' can filter out channels that have
-					##  been added again
+					## todo/fixme/whatever: this 'if' can filter out channels
+					## that have been added again
 					self._depqueue_done [channel_id].put ( dep_env )
 
 			except queue.Empty:

diff --git a/roverlay/depres/deprule.py b/roverlay/depres/deprule.py
index a585de3..b02213c 100644
--- a/roverlay/depres/deprule.py
+++ b/roverlay/depres/deprule.py
@@ -36,14 +36,16 @@ class DependencyRulePool ( object ):
 		self.rules       = list ()
 		self.name        = name
 		self.priority    = priority
-		# the "rule weight" is the sum of the rules' priorities - it's used to
-		#  compare/sort dependency pools with the same priority (lesser weight is better)
+		# the "rule weight" is the sum of the rules' priorities
+		#  it's used to compare/sort dependency pools with
+		#  the same priority (lesser weight is better)
 		self.rule_weight = 0
 	# --- end of __init__ (...) ---
 
 	def sort ( self ):
-		"""Sorts this rule pool and determines its weight which is used to compare
-		rule pools."""
+		"""Sorts this rule pool and determines its weight which is used
+		to compare rule pools.
+		"""
 
 		self.rules.sort ( key=lambda rule : rule.priority )
 

diff --git a/roverlay/depres/listeners.py b/roverlay/depres/listeners.py
index 5034a70..0c123c0 100644
--- a/roverlay/depres/listeners.py
+++ b/roverlay/depres/listeners.py
@@ -9,8 +9,16 @@ from roverlay.depres.depenv        import DepEnv
 from roverlay.depres.communication import DependencyResolverListener
 
 class FileListener ( DependencyResolverListener ):
+	"""A dependency resolution listener that writes events to a file."""
 
 	def __init__ ( self, _file, listen_mask ):
+		"""Initializes a FileListener.
+
+		arguments:
+		* _file       -- file to write
+		* listen_mask -- a bit mask (int) that defines the events to be
+		                 processed.
+	  """
 		super ( FileListener, self ) . __init__ ()
 
 		self.fh    = None
@@ -22,6 +30,7 @@ class FileListener ( DependencyResolverListener ):
 	# --- end of __init__ (...) ---
 
 	def _event ( self, event_type, to_write ):
+		"""Writes to_write if event_type is accepted by self.listen_mask."""
 		if self.mask & event_type:
 			if not self.fh: self.fh = open ( self._file, 'a' ) # or w?
 			self.fh.write ( to_write + "\n" )
@@ -29,11 +38,13 @@ class FileListener ( DependencyResolverListener ):
 	# --- end of _event (...) ---
 
 	def close ( self ):
+		"""Closes this listener (closes the file handle if open)."""
 		if self.fh: self.fh.close()
 	# --- end of close (...) ---
 
 
 class ResolvedFileListener ( FileListener ):
+	"""A FileListener that listens to 'dependency resolved' events."""
 
 	def __init__ ( self, _file ):
 		super ( ResolvedFileListener, self ) . __init__ (
@@ -48,6 +59,7 @@ class ResolvedFileListener ( FileListener ):
 	# --- end of notify (...) ---
 
 class UnresolvableFileListener ( FileListener ):
+	"""A FileListener that listens to 'dependency unresolvable' events."""
 	def __init__ ( self, _file ):
 		super ( UnresolvableFileListener, self ) . __init__ (
 			_file, events.DEPRES_EVENTS ['UNRESOLVABLE']

diff --git a/roverlay/depres/simpledeprule.py b/roverlay/depres/simpledeprule.py
index 55732c4..ee40045 100644
--- a/roverlay/depres/simpledeprule.py
+++ b/roverlay/depres/simpledeprule.py
@@ -103,7 +103,7 @@ class SimpleIgnoreDependencyRule ( deprule.DependencyRule ):
 			else:
 				resolving_package = resolving_to
 
-			# todo hardcoded here
+			# todo hardcoded rule format here
 			if alias_count > 1:
 
 				retlist = [ resolving_package + ' {\n' ] + \
@@ -219,7 +219,7 @@ class SimpleDependencyRuleReader ( object ):
 	one_line_separator = re.compile ( '\s+::\s+' )
 	multiline_start    = '{'
 	multiline_stop     = '}'
-	comment_chars      = list ( '#;' )
+	comment_chars      = "#;"
 	# todo: const/config?
 	package_ignore     = [ '!' ]
 

diff --git a/roverlay/ebuild/abstractcomponents.py b/roverlay/ebuild/abstractcomponents.py
index 73dac03..019c252 100644
--- a/roverlay/ebuild/abstractcomponents.py
+++ b/roverlay/ebuild/abstractcomponents.py
@@ -5,11 +5,23 @@
 INDENT = '\t'
 
 def listlike ( ref ):
+	"""Returns True if ref is listlike (a non-str iterable)."""
 	return hasattr ( ref, '__iter__' ) and not isinstance ( ref, str )
 
 
 class ListValue ( object ):
+	"""An evar value with a list of elements."""
 	def __init__ ( self, value, indent_level=1, empty_value=None ):
+		"""Initializes a ListValue.
+
+		arguments:
+		* value        --
+		* indent_level -- indention level ('\t') for extra value lines
+		* empty_value  -- if set: a string value that is always part
+		                          of this ListValue's elements but ignored
+		                          by len().
+		                          Use cases are '${IUSE:-}' in the IUSE var etc.
+		"""
 		self.set_level ( indent_level )
 
 		self.empty_value = empty_value
@@ -23,13 +35,14 @@ class ListValue ( object ):
 		self.val_join = ' '
 
 		self.set_value ( value )
-
+	# --- end of __init__ (...) ---
 
 	def __len__ ( self ):
 		l = len ( self.value )
 		return l if self.empty_value is None else l - 1
 
 	def set_level ( self, level ):
+		"""Sets the indention level."""
 		self.level      = level
 		self.var_indent = (level - 1) * INDENT
 		self.val_indent = level * INDENT
@@ -37,6 +50,7 @@ class ListValue ( object ):
 	# --- end of set_level (...) ---
 
 	def set_value ( self, value ):
+		"""Sets the value."""
 		self.value = list()
 		if self.empty_value is not None:
 			self.value.append ( self.empty_value )
@@ -44,6 +58,7 @@ class ListValue ( object ):
 	# --- end of set_value (...) ---
 
 	def add_value ( self, value ):
+		"""Adds/Appends a value."""
 		if value is None:
 			pass
 		elif listlike ( value ):
@@ -55,6 +70,7 @@ class ListValue ( object ):
 	add = add_value
 
 	def to_str ( self ):
+		"""Returns a string representing this ListValue."""
 		if len ( self.value ) == 0:
 			ret = ""
 		elif len ( self.value ) == 1:
@@ -73,21 +89,37 @@ class ListValue ( object ):
 
 
 class EbuildVar ( object ):
+	"""An ebuild variable."""
 
 	def __init__ ( self, name, value, priority ):
+		"""Initializes an EbuildVar.
+
+		arguments:
+		* name     -- e.g. 'SRC_URI'
+		* value    --
+		* priority -- used for sorting (e.g. 'R_SUGGESTS' before 'DEPEND'),
+		               lower means higher priority
+		"""
 		self.name     = name
 		self.priority = priority
 		self.value    = value
 		self.set_level ( 0 )
 
 	def set_level ( self, level ):
+		"""Sets the indention level."""
 		self.level  = level
 		self.indent = self.level * INDENT
 		if hasattr ( self.value, 'set_level' ):
 			self.value.set_level ( level + 1 )
 	# --- end of set_level (...) ---
 
-	def active ( self ): return True
+	def active ( self ):
+		"""Returns True if this EbuildVar is enabled and has a string to
+		return.
+		(EbuildVar's active() returns always True, derived classes may
+		override this.)
+		"""
+		return True
 
 	def __str__ ( self ):
 		return '%s%s="%s"' % ( self.indent, self.name, self.value )

diff --git a/roverlay/ebuild/creation.py b/roverlay/ebuild/creation.py
index e2f4872..fca864d 100644
--- a/roverlay/ebuild/creation.py
+++ b/roverlay/ebuild/creation.py
@@ -1,4 +1,4 @@
-# R Overlay -- ebuild creation, <?>
+# R Overlay -- ebuild creation
 # Copyright 2006-2012 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 
@@ -10,13 +10,26 @@ from roverlay.rpackage.descriptionreader import DescriptionReader
 
 LOGGER = logging.getLogger ( 'EbuildCreation' )
 
+# USE_FULL_DESCRIPTION
+#  * True: use Title and Description for ebuild's DESCRIPTION variable
+#  * else: use Title _or_ Description
 USE_FULL_DESCRIPTION = False
 
+# FALLBACK_DESCRIPTION is used as DESCRIPTION= value if not empty and
+#  the R package has no Title/Description
+FALLBACK_DESCRIPTION = "<none>"
 
 class EbuildCreation ( object ):
+	"""Used to create an ebuild using DESCRIPTION data."""
 
 	def __init__ ( self, package_info, depres_channel_spawner=None ):
+		"""Initializes the creation of an ebuild.
 
+		arguments:
+		* package_info           --
+		* depres_channel_spawner -- function that returns a communication
+		                             channel to the resolver
+		"""
 		self.package_info = package_info
 
 		self.logger = LOGGER.getChild ( package_info ['name'] )
@@ -24,7 +37,6 @@ class EbuildCreation ( object ):
 		# > 0 busy/working; 0 == done,success; < 0 done,fail
 		self.status = 1
 
-
 		self.depres_channel_spawner = depres_channel_spawner
 
 		self.package_info.set_readonly()
@@ -36,6 +48,7 @@ class EbuildCreation ( object ):
 	def fail    ( self ) : return self.status  < 0
 
 	def run ( self ):
+		"""Creates an ebuild. Returns None (implicit)."""
 		if self.status < 1:
 			raise Exception ( "Cannot run again." )
 
@@ -58,6 +71,8 @@ class EbuildCreation ( object ):
 	# --- end of run (...) ---
 
 	def _lazyimport_desc_data ( self ):
+		"""Reads R package description data."""
+		# TODO/FIXME: read this somewhere else?
 		if self.package_info.get ( 'desc_data',
 			fallback_value=None, do_fallback=True ) is None:
 
@@ -75,23 +90,51 @@ class EbuildCreation ( object ):
 
 	# --- end of _lazyimport_desc_data (...) ---
 
+	def _get_ebuild_description ( self ):
+		"""Creates a DESCRIPTION variable."""
+		desc = self.package_info ['desc_data']
+
+		description = None
+		if USE_FULL_DESCRIPTION:
+			# use Title and Description for DESCRIPTION=
+			if 'Title' in desc:
+				description = desc ['Title']
+
+			if 'Description' in desc:
+				if description is None:
+					description = desc ['Description']
+				else:
+					description += '// ' + desc ['Description']
+		else:
+			# use either Title or Description for DESCRIPTION=
+			# (Title preferred 'cause it should be shorter)
+			if 'Title' in desc:
+				description = desc ['Title']
+			elif 'Description' in desc:
+				description = desc ['Description']
+
+
+		if description is not None:
+			return evars.DESCRIPTION ( description )
+		elif FALLBACK_DESCRIPTION:
+			return evars.DESCRIPTION ( FALLBACK_DESCRIPTION )
+		else:
+			return None
+	# --- end of _get_ebuild_description (...) ---
 
 	def _make_ebuild ( self ):
-		desc = self.package_info ['desc_data']
-		if desc is None:
+		"""Tries to create ebuild data."""
+		if self.package_info ['desc_data'] is None:
 			self.logger (
 				'desc empty - cannot create an ebuild for this package.'
 			)
 			return False
 
-		ebuild = ebuilder.Ebuilder()
-
 		_dep_resolution = depres.EbuildDepRes (
 			self.package_info, self.logger,
 			create_iuse=True, run_now=True,
 			depres_channel_spawner=self.depres_channel_spawner
 		)
-
 		if not _dep_resolution.success():
 			# log here? (FIXME)
 			return False
@@ -99,29 +142,15 @@ class EbuildCreation ( object ):
 
 		dep_result = _dep_resolution.get_result()
 
+		ebuild = ebuilder.Ebuilder()
+
 		# add *DEPEND, IUSE to the ebuild
 		ebuild.use ( *dep_result [1] )
 
-		description = None
-		if USE_FULL_DESCRIPTION:
-			if 'Title' in desc:
-				description = desc ['Title']
-
-			if 'Description' in desc:
-				if description is None:
-					description = desc ['Description']
-				else:
-					description += '// ' + desc ['Description']
-		else:
-			if 'Title' in desc:
-				description = desc ['Title']
-			elif 'Description' in desc:
-				description = desc ['Description']
-
-
-		if description is not None:
-			ebuild.use ( evars.DESCRIPTION ( description ) )
+		# DESCRIPTION
+		ebuild.use ( self._get_ebuild_description() )
 
+		# SRC_URI
 		ebuild.use ( evars.SRC_URI ( self.package_info ['SRC_URI'] ) )
 
 		ebuild_text = ebuild.to_str()
@@ -132,3 +161,4 @@ class EbuildCreation ( object ):
 		)
 
 		return True
+	# --- end of _make_ebuild (...) ---

diff --git a/roverlay/ebuild/depres.py b/roverlay/ebuild/depres.py
index db0f906..3838060 100644
--- a/roverlay/ebuild/depres.py
+++ b/roverlay/ebuild/depres.py
@@ -6,7 +6,7 @@ import roverlay.static.depres
 
 from roverlay.ebuild import evars
 
-# move this to const / config
+# TODO/FIXME/IGNORE move this to const / config
 FIELDS = {
 	'R_SUGGESTS' : [ 'Suggests' ],
 	'DEPENDS'    : [ 'Depends', 'Imports' ],
@@ -21,11 +21,21 @@ EBUILDVARS = {
 
 
 class EbuildDepRes ( object ):
+	"""Handles dependency resolution for a single ebuild."""
 
 	def __init__ (
 		self, package_info, logger, depres_channel_spawner,
 		create_iuse=True, run_now=True
 	):
+		"""Initializes an EbuildDepRes.
+
+		arguments:
+		* package_info           --
+		* logger                 -- parent logger
+		* depres_channel_spawner -- used to get channels to the dep resolver
+		* create_iuse            -- create an IUSE evar (if True)
+		* run_now                -- immediately start after initialization
+		"""
 		self.logger       = logger.getChild ( 'depres' )
 		self.package_info = package_info
 
@@ -56,10 +66,14 @@ class EbuildDepRes ( object ):
 	def fail    ( self ) : return self.status  < 0
 
 	def get_result ( self ):
+		"""Returns the result of dependency resolution,
+		as tuple ( <status>, <evars>, <has R suggests> )
+		"""
 		return ( self.status, self.result, self.has_suggests )
 	# --- end of get_result (...) ---
 
 	def resolve ( self ):
+		"""Try to make/get dependency resolution results. Returns None."""
 		try:
 			self.result = None
 			self._init_channels()
@@ -80,6 +94,7 @@ class EbuildDepRes ( object ):
 	# --- end of resolve (...) ---
 
 	def _get_channel ( self, dependency_type ):
+		"""Creates and returns a communication channel to the dep resolver."""
 		if dependency_type not in self._channels:
 			self._channels [dependency_type] = self.request_resolver (
 				name=dependency_type,
@@ -89,6 +104,9 @@ class EbuildDepRes ( object ):
 	# --- end of get_channel (...) ---
 
 	def _init_channels ( self ):
+		"""Initializes the resolver channels, one for each existing
+		dependency type. Queues dependencies, too.
+		"""
 		# collect dep strings and initialize resolver channels
 
 		if self.request_resolver is None:
@@ -125,6 +143,7 @@ class EbuildDepRes ( object ):
 	# --- end of _init_channels (...) ---
 
 	def _close_channels ( self ):
+		"""Closes the resolver channels."""
 		if self._channels is None: return
 
 		for channel in self._channels.values(): channel.close()
@@ -132,6 +151,7 @@ class EbuildDepRes ( object ):
 	# --- end of _close_channels (...) ---
 
 	def _wait_resolve ( self ):
+		"""Wait for dep resolution."""
 		# True if no channels
 		for c in self._channels.values():
 			if c.satisfy_request() is None:
@@ -140,6 +160,7 @@ class EbuildDepRes ( object ):
 	# --- end of _wait_resolve (...) ---
 
 	def _make_result ( self ):
+		"""Make evars using the depres result."""
 		_result = list()
 		for dep_type, channel in self._channels.items():
 			deplist = list ( filter ( None, channel.collect_dependencies() ) )

diff --git a/roverlay/ebuild/ebuilder.py b/roverlay/ebuild/ebuilder.py
index 275c6d2..aa7d8f5 100644
--- a/roverlay/ebuild/ebuilder.py
+++ b/roverlay/ebuild/ebuilder.py
@@ -1,22 +1,31 @@
-# R Overlay -- ebuild creation, <?>
+# R Overlay -- ebuild construction
 # Copyright 2006-2012 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 
 class Ebuilder ( object ):
+	"""Used to create ebuilds."""
 
 	def __init__ ( self ):
 		self._evars = list()
+		# newlines \n will be inserted after an evar if the priority
+		# delta (current evar, next evar) is >= this value.
+		# <= 0 means newline after each statement
+		self.min_newline_distance = 20
 
 	def sort ( self ):
-		self._evars.sort ( key=lambda e: e.priority )
+		"""Sorts the content of the Ebuilder."""
+		self._evars.sort ( key=lambda e: ( e.priority, e.name ) )
+		#self._evars.sort ( key=lambda e: e.priority )
 
 	def get_lines ( self ):
+		"""Creates and returns (ordered) text lines."""
+
 		self.sort()
 		last = len ( self._evars ) - 1
 
-		newline = lambda i, k=1 : \
-			abs ( self._evars [i + k].priority - self._evars [i].priority ) >= 20
-
+		newline = lambda i, k=1 : abs (
+			self._evars [i + k].priority - self._evars [i].priority
+		) >= self.min_newline_distance
 
 		lines = list()
 		for index, e in enumerate ( self._evars ):
@@ -25,12 +34,17 @@ class Ebuilder ( object ):
 				if index < last and newline ( index ): lines.append ( '' )
 
 		return lines
+	# --- end of get_lines (...) ---
 
-	def to_str ( self ):
-		return '\n'.join ( self.get_lines() )
 
+	def to_str ( self ): return '\n'.join ( self.get_lines() )
 	__str__ = to_str
 
 	def use ( self, *evar_list ):
+		"""Adds evars to this Ebuilder.
+
+		arguments:
+		* *evar_list --
+		"""
 		for e in evar_list:
-			self._evars.append ( e )
+			if e is not None: self._evars.append ( e )

diff --git a/roverlay/ebuild/evars.py b/roverlay/ebuild/evars.py
index 78a7326..da34c68 100644
--- a/roverlay/ebuild/evars.py
+++ b/roverlay/ebuild/evars.py
@@ -1,4 +1,4 @@
-# R Overlay -- ebuild creation, <?>
+# R Overlay -- ebuild construction, ebuild variables
 # Copyright 2006-2012 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 
@@ -12,24 +12,40 @@ RSUGGESTS_NAME = "R_SUGGESTS"
 # ignoring case policies here (camel case,..)
 
 class DESCRIPTION ( EbuildVar ):
-	def __init__ ( self, description ):
+	"""A DESCRIPTION="..." statement."""
+	def __init__ ( self, description, maxlen=50 ):
+		"""A DESCRIPTION="..." statement. Long values will be truncated.
+
+		arguments:
+		* description -- description text
+		* maxlen      -- maximum value length (defaults to 50 chars)
+		"""
 		super ( DESCRIPTION, self ) . __init__ ( 'DESCRIPTION', description, 80 )
+		self.maxlen = 50 if maxlen is None else maxlen
 
 	def __str__ ( self ):
 		return '%s%s="%s"' % (
 			self.indent,
 			self.name,
-			shorten_str ( str ( self.value ) , 50, '... (see metadata)' )
+			shorten_str ( str ( self.value ) , self.maxlen, '... (see metadata)' )
 		)
 
 
 class SRC_URI ( EbuildVar ):
+	"""A SRC_URI="..." statement."""
 	def __init__ ( self, src_uri ):
 		super ( SRC_URI, self ) . __init__ ( 'SRC_URI', src_uri, 90 )
 
 
 class IUSE ( EbuildVar ):
+	"""An IUSE="..." statement."""
 	def __init__ ( self, use_flags=None, using_suggests=False ):
+		"""An IUSE="..." statement.
+
+		arguments:
+		* use_flags      -- IUSE value
+		* using_suggests -- if True: enable R_Suggests USE flag
+		"""
 		super ( IUSE, self ) . __init__ (
 			'IUSE',
 			ListValue ( use_flags, empty_value='${IUSE:-}' ),
@@ -41,6 +57,7 @@ class IUSE ( EbuildVar ):
 
 
 class R_SUGGESTS ( EbuildVar ):
+	"""A R_SUGGESTS="..." statement."""
 	def __init__ ( self, deps, **kw ):
 		super ( R_SUGGESTS, self ) . __init__ (
 			RSUGGESTS_NAME,
@@ -50,6 +67,7 @@ class R_SUGGESTS ( EbuildVar ):
 
 
 class DEPEND ( EbuildVar ):
+	"""A DEPEND="..." statement."""
 	def __init__ ( self, deps, **kw ):
 		super ( DEPEND, self ) . __init__ (
 			'DEPEND',
@@ -59,6 +77,7 @@ class DEPEND ( EbuildVar ):
 
 
 class RDEPEND ( EbuildVar ):
+	"""A RDEPEND="..." statement."""
 	def __init__ ( self, deps, using_suggests=False, **kw ):
 		super ( RDEPEND, self ) . __init__ (
 			'RDEPEND',
@@ -68,4 +87,5 @@ class RDEPEND ( EbuildVar ):
 		if using_suggests: self.enable_suggests()
 
 	def enable_suggests ( self ):
+		"""Adds the optional R_SUGGESTS dependencies to RDEPEND."""
 		self.value.add ( '%s? ( ${%s} )' % ( IUSE_SUGGESTS, RSUGGESTS_NAME ) )

diff --git a/roverlay/manifest/helpers.py b/roverlay/manifest/helpers.py
index 09f3296..5e2919c 100644
--- a/roverlay/manifest/helpers.py
+++ b/roverlay/manifest/helpers.py
@@ -77,8 +77,6 @@ class ExternalManifestCreation ( _ManifestCreation ):
 		)
 
 		output = ebuild_call.communicate()
-		# necessary? (probably not, FIXME/TODO)
-		ebuild_call.wait()
 
 		# log stdout?
 		#for line in util.pipe_lines ( output [0] ):

diff --git a/roverlay/metadata/__init__.py b/roverlay/metadata/__init__.py
index 074cce3..8d94325 100644
--- a/roverlay/metadata/__init__.py
+++ b/roverlay/metadata/__init__.py
@@ -13,7 +13,6 @@ class MetadataJob ( object ):
 		"""Initializes a MetadataJob.
 
 		arguments:
-		(((* package_info -- reserved for future usage)))
 		* logger       -- parent logger to use
 		"""
 		self.logger    = logger.getChild ( 'metadata' )

diff --git a/roverlay/metadata/abstractnodes.py b/roverlay/metadata/abstractnodes.py
index 50c9f56..f5a5c31 100644
--- a/roverlay/metadata/abstractnodes.py
+++ b/roverlay/metadata/abstractnodes.py
@@ -130,9 +130,9 @@ class MetadataNode ( _MetadataBasicNode ):
 
 	def _nodelist ( self ):
 		"""Returns a list of strings representing the child nodes."""
-		return list (
+		return tuple (
 			filter (
-				None,
+				lambda k: k is not None,
 				[ node.to_str() for node in self.nodes if node.active() ]
 			),
 		)
@@ -141,7 +141,6 @@ class MetadataNode ( _MetadataBasicNode ):
 	def _nodestr ( self ):
 		"""Returns a string representing all child nodes."""
 		self._sort_nodes()
-		# todo filter only None?
 		node_repr = self._nodelist()
 		if len ( node_repr ):
 			# add newlines before/after and indent after node_repr!

diff --git a/roverlay/metadata/nodes.py b/roverlay/metadata/nodes.py
index f35f8da..4d4d5fd 100644
--- a/roverlay/metadata/nodes.py
+++ b/roverlay/metadata/nodes.py
@@ -108,13 +108,12 @@ class DescriptionNode ( MetadataLeaf ):
 		arguments:
 		* description -- description text
 		* is_long     -- if this is a longdescription or a description node
-		* linewidth   -- max text line width, TODO/FIXME: is this ignored?
+		* linewidth   -- max text line width
 		"""
 		super ( DescriptionNode, self ) . __init__ (
 			'longdescription' if is_long else 'description',
 			value=description,
 		)
-		# self.value_format = "break lines after 80c, ..."
 
 		if not linewidth is None and linewidth > 0:
 			self.linewidth = linewidth
@@ -163,9 +162,8 @@ class UseFlagListNode ( MetadataNode ):
 		one UseFlag child node is active.
 		"""
 		# generator should stop after first True
-		# todo/fixme: could use super ( UseFlagListNode, self ).active() instead
-		# of self._enabled
-		return True in ( node.active() for node in self.nodes ) and self._enabled
+		return self._enabled and \
+			True in ( node.active() for node in self.nodes )
 	# --- end of active (...) ---
 
 	def _sort_nodes ( self ):

diff --git a/roverlay/overlay/__init__.py b/roverlay/overlay/__init__.py
index dadf998..0686ed8 100644
--- a/roverlay/overlay/__init__.py
+++ b/roverlay/overlay/__init__.py
@@ -1,4 +1,4 @@
-# R Overlay -- <comment TODO>
+# R Overlay -- overlay module
 # Copyright 2006-2012 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 
@@ -119,16 +119,15 @@ class Overlay ( object ):
 	def write ( self, **write_kw ):
 		"""Writes the overlay to its physical location (filesystem), including
 		metadata and Manifest files.
-		TODO include Manifest generation in package.py
 
 		arguments:
 		* **write_kw -- ignored! (keywords for package.PackageDir.write(...))
 
 		returns: None (implicit)
 
-		raises: !! TODO
+		raises: IOError
 
-		TODO/FIXME/DOC: This is not thread-safe, it's expected to be called
+		! TODO/FIXME/DOC: This is not thread-safe, it's expected to be called
 		when ebuild creation is done.
 		"""
 		# writing profiles/ here, rewriting categories/ later
@@ -244,7 +243,6 @@ class Overlay ( object ):
 
 	def _write_usedesc ( self ):
 		"""Writes profiles/use.desc."""
-		# TODO: config entry
 		use_desc = config.get (
 			'OVERLAY.use_desc',
 			fallback_value=DEFAULT_USE_DESC
@@ -278,7 +276,6 @@ class Overlay ( object ):
 
 
 			except Exception as e:
-				#self.logger.exception ( e ) TODO try-catch blocks
 				self.logger.critical ( "Cannot import eclass files!" )
 				raise
 	# --- end of _import_eclass (...) ---
@@ -293,7 +290,7 @@ class Overlay ( object ):
 
 		raises:
 		* Exception if no physical location assigned
-		* <TODO> passes IOError,...
+		* IOError
 		"""
 		if self.physical_location is None:
 			raise Exception ( "no directory assigned." )

diff --git a/roverlay/overlay/category.py b/roverlay/overlay/category.py
index 10e57c2..910f194 100644
--- a/roverlay/overlay/category.py
+++ b/roverlay/overlay/category.py
@@ -1,4 +1,4 @@
-# R Overlay -- <comment TODO>
+# R Overlay -- overlay module, portage category
 # Copyright 2006-2012 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 
@@ -41,7 +41,6 @@ class Category ( object ):
 
 		returns: None (implicit)
 		"""
-		# TODO make keys available
 		pkg_name = package_info ['name']
 
 		if not pkg_name in self._subdirs:

diff --git a/roverlay/overlay/package.py b/roverlay/overlay/package.py
index b571ad9..e77d4a2 100644
--- a/roverlay/overlay/package.py
+++ b/roverlay/overlay/package.py
@@ -1,4 +1,4 @@
-# R Overlay -- <comment TODO>
+# R Overlay -- overlay module, package dir (subdir of category)
 # Copyright 2006-2012 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 
@@ -61,7 +61,9 @@ class PackageDir ( object ):
 
 		returns: None (implicit)
 
-		raises: !! TODO
+		raises:
+		* Exception if no directory assigned
+		* IOError
 		"""
 		if self.physical_location is None:
 			raise Exception ( "cannot write - no directory assigned!" )
@@ -98,7 +100,6 @@ class PackageDir ( object ):
 				# chown 250.250
 
 				# this marks the package as 'written to fs'
-				# TODO update PackageInfo
 				p_info.set_writeable()
 				p_info ['ebuild_file'] = efile
 				p_info.set_readonly()
@@ -136,7 +137,8 @@ class PackageDir ( object ):
 
 		returns: None (implicit)
 
-		raises: !! TODO
+		raises:
+		* IOError
 		"""
 		self._lock.acquire()
 		self._regen_metadata()
@@ -206,7 +208,6 @@ class PackageDir ( object ):
 
 		raises: Exception when ebuild already exists.
 		"""
-		# !! p info key TODO
 		shortver = package_info ['ebuild_verstr']
 
 		def already_exists ( release=False ):
@@ -254,8 +255,8 @@ class PackageDir ( object ):
 
 		arguments:
 		* skip_if_existent -- do not create if metadata already exist
-		* use_all_packages -- TODO
-		* use_old_metadata -- TODO
+		* use_all_packages -- TODO in metadata
+		* use_old_metadata -- TODO in metadata
 		"""
 		if use_old_metadata or use_all_packages:
 				raise Exception ( "using >1 package for metadata.xml is TODO!" )
@@ -285,8 +286,9 @@ class PackageDir ( object ):
 
 		returns: None (implicit)
 
-		raises: !! TODO
+		raises:
 		* Exception if not physical
+		* Exception if no ebuild exists
 		"""
 		if self.physical_location is None:
 			raise Exception ( "no directory assigned." )

diff --git a/roverlay/rpackage/descriptionfields.py b/roverlay/rpackage/descriptionfields.py
index bccc3df..dcb0803 100644
--- a/roverlay/rpackage/descriptionfields.py
+++ b/roverlay/rpackage/descriptionfields.py
@@ -132,7 +132,9 @@ class DescriptionField ( object ):
 	# --- end of set_default_value (...) ---
 
 	def get_flags ( self ):
-		"""Returns the flags of this DescriptionField or an empty list (=no flags)."""
+		"""Returns the flags of this DescriptionField or
+		an empty list (=no flags).
+		"""
 		return self.flags
 
 	# --- end of get_flags (...) ---
@@ -146,17 +148,19 @@ class DescriptionField ( object ):
 	# --- end of get_allowed_values (...) ---
 
 	def matches ( self, field_identifier ):
-		"""Returns whether field_identifier equals the name of this DescriptionField.
+		"""Returns whether field_identifier equals the name of this field.
 
 		arguments:
 		* field_identifier --
 		"""
-		return bool ( self.name == field_identifier ) if field_identifier else False
-
+		if field_indentifier:
+			return bool ( self.name == field_identifier )
+		else:
+			return False
 	# --- end of matches (...) ---
 
 	def matches_alias ( self, field_identifier ):
-		"""Returns whether field_identifier equals any alias of this DescriptionField.
+		"""Returns whether field_identifier equals any alias of this field.
 
 		arguments:
 		* field_identifier --
@@ -215,8 +219,8 @@ class DescriptionField ( object ):
 
 
 class DescriptionFields ( object ):
-	"""DescriptionFields stores several instances of DescriptionField and provides
-	'search in all' methods such as get_fields_with_flag (<flag>).
+	"""DescriptionFields stores several instances of DescriptionField and
+	provides 'search in all' methods such as get_fields_with_flag (<flag>).
 	"""
 
 	def __init__ ( self ):
@@ -266,8 +270,8 @@ class DescriptionFields ( object ):
 	# --- end of get (...) ---
 
 	def find_field ( self, field_name ):
-		"""Determines the name of the DescriptionField to which field_name belongs
-		to. Returns the name of the matching field or None.
+		"""Determines the name of the DescriptionField to which field_name
+		belongs to. Returns the name of the matching field or None.
 
 		arguments:
 		* field_name --

diff --git a/roverlay/rpackage/descriptionreader.py b/roverlay/rpackage/descriptionreader.py
index e700907..c9daeb8 100644
--- a/roverlay/rpackage/descriptionreader.py
+++ b/roverlay/rpackage/descriptionreader.py
@@ -51,23 +51,29 @@ class DescriptionReader ( object ):
 
 		# insert default values
 		default_values = self.field_definition.get_fields_with_default_value()
+
 		for field_name in default_values.keys():
 			if not field_name in read_data:
 				read_data [field_name] = default_values [field_name]
 
 
 		# join values to a single string
-		for field_name in self.field_definition.get_fields_with_flag ( 'joinValues' ):
-
+		for field_name in \
+			self.field_definition.get_fields_with_flag ( 'joinValues' ) \
+		:
 			if field_name in read_data:
 				read_data [field_name] = ' ' . join ( read_data [field_name] )
 
 		# ensure that all mandatory fields are set
 		missing_fields = set ()
 
-		for field_name in self.field_definition.get_fields_with_flag ( 'mandatory' ):
+		for field_name in \
+			self.field_definition.get_fields_with_flag ( 'mandatory' ):
+
 			if field_name in read_data:
-				if read_data [field_name] is None or len ( read_data [field_name] ) < 1:
+				if read_data [field_name] is None or \
+					len ( read_data [field_name] ) < 1 \
+				:
 					missing_fields.add ( field_name )
 				#else: ok
 			else:
@@ -77,10 +83,14 @@ class DescriptionReader ( object ):
 		# check for fields that allow only certain values
 		unsuitable_fields = set()
 
-		restricted_fields = self.field_definition.get_fields_with_allowed_values()
+		restricted_fields = \
+			self.field_definition.get_fields_with_allowed_values()
+
 		for field_name in restricted_fields:
 			if field_name in read_data:
-				if not self.field_definition.get ( field_name ).value_allowed ( read_data [field_name] ):
+				if not self.field_definition.get ( field_name ) . value_allowed (
+					read_data [field_name]
+				):
 					unsuitable_fields.add ( field_name )
 
 		# summarize results
@@ -88,16 +98,23 @@ class DescriptionReader ( object ):
 		if not valid:
 			self.logger.info ( "Cannot use R package" ) # name?
 			if len ( missing_fields ):
-				self.logger.debug ( "The following mandatory description fields are missing: %s.", str ( missing_fields ) )
+				self.logger.debug (
+					"The following mandatory description fields are missing: %s."
+						% missing_fields
+				)
 			if len ( unsuitable_fields ):
-				self.logger.debug ( "The following fields have unsuitable values: %s.", str ( unsuitable_fields ) )
+				self.logger.debug (
+					"The following fields have unsuitable values: %s."
+						% unsuitable_fields
+				)
 
 		return valid
 
 	# --- end of _parse_read_data (...) ---
 
 	def run ( self ):
-		"""Reads a DESCRIPTION file and returns the read data if successful, else None.
+		"""Reads a DESCRIPTION file and returns the read data if successful,
+		else None.
 
 		arguments:
 		* file -- path to the tarball file (containing the description file)
@@ -117,11 +134,12 @@ class DescriptionReader ( object ):
 			"""Extracts relevant data from value_str and returns them as list.
 
 			arguments:
-			* value_str -- string that represents the (just read) values
-			* field_context -- field name the value belongs to; optional, defaults to None
+			* value_str     -- string that represents the (just read) values
+			* field_context -- field name the value belongs to;
+			                    optional, defaults to None
 
-			It's useful to set field_context 'cause several fields ('Depends') have
-			multiple values arranged in a list (dep0, dep1 [, depK]*).
+			It's useful to set field_context 'cause several fields ('Depends')
+			have multiple values arranged in a list (dep0, dep1 [, depK]*).
 			"""
 
 			svalue_str = value_str.strip()
@@ -134,20 +152,22 @@ class DescriptionReader ( object ):
 				# default return if no context given
 				return [ svalue_str ]
 
-			elif field_context in self.field_definition.get_fields_with_flag ( 'isList' ):
-					# split up this list (that is separated by commata and/or semicolons)
-					# *beware*/fixme: py3, filter returns filter object
-					return filter ( None, re.split (
-						config.get ( 'DESCRIPTION.list_split_regex' ),
-						svalue_str,
-						0
-					) )
-
-			elif field_context in self.field_definition.get_fields_with_flag ( 'isWhitespaceList' ):
-					# split up this list (that is separated whitespace)
-					return filter ( None, re.split ( '\s+', svalue_str, 0 ) )
-
-
+			elif field_context in \
+				self.field_definition.get_fields_with_flag ( 'isList' ) \
+			:
+				# split up this list (separated by commata and/or semicolons)
+				# *beware*/fixme: py3, filter returns filter object
+				return filter ( None, re.split (
+					config.get ( 'DESCRIPTION.list_split_regex' ),
+					svalue_str,
+					0
+				) )
+
+			elif field_context in \
+				self.field_definition.get_fields_with_flag ( 'isWhitespaceList' ) \
+			:
+				# split up this list (separated by whitespace)
+				return filter ( None, re.split ( '\s+', svalue_str, 0 ) )
 
 			# default return
 			return [ svalue_str ]
@@ -160,15 +180,15 @@ class DescriptionReader ( object ):
 			arguments:
 			* filepath -- file to read (str; path to tarball or file)
 			* pkg_name -- name of the package, in tarballs the description file
-							  is located in <pkg_name>/ and thus this argument is required.
-							  Defaults to '.', set to None to disable.
+							  is located in <pkg_name>/ and thus this argument
+							  is required. Defaults to '.', set to None to disable.
 
 			All exceptions are passed to the caller (TarError, IOErr, <custom>).
 			<filepath> can either be a tarball in which case the real DESCRIPTION
 			file is read (<pkg_name>/DESCRIPTION) or a normal file.
 			"""
 
-			self.logger.debug ( "Starting to read file '" + str ( filepath ) + "' ...\n" )
+			self.logger.debug ( "Starting to read file '%s' ...\n" % filepath )
 
 			if not ( isinstance ( filepath, str ) and filepath ):
 				raise Exception ( "bad usage" )
@@ -222,13 +242,15 @@ class DescriptionReader ( object ):
 
 		field_context = None
 
+		comment_chars = config.get ( 'DESCRIPTION.comment_chars', '#' )
+
 		for line in desc_lines:
 			field_context_ref = None
 
 			# using s(tripped)line whenever whitespace doesn't matter
 			sline = line.lstrip()
 
-			if (not sline) or (line [0] == config.get ( 'DESCRIPTION.comment_char' ) ):
+			if not sline or line [0] in comment_chars:
 				# empty line or comment
 				pass
 
@@ -248,15 +270,21 @@ class DescriptionReader ( object ):
 				# line introduces a new field context, forget last one
 				field_context = None
 
-				line_components = sline.partition ( config.get ( 'DESCRIPTION.field_separator' ) )
+				line_components = sline.partition (
+					config.get ( 'DESCRIPTION.field_separator' )
+				)
 
 				if line_components [1]:
 					# line contains a field separator, set field context
-					field_context_ref = self.field_definition.get ( line_components [0] )
+					field_context_ref = self.field_definition.get (
+						line_components [0]
+					)
 
 					if field_context_ref is None:
 						# useless line, skip
-						self.logger.info ( "Skipped a description field: '%s'.", line_components [0] )
+						self.logger.info (
+							"Skipped a description field: '%s'.", line_components [0]
+						)
 					elif field_context_ref.has_flag ( 'ignore' ):
 						# field ignored
 						self.logger.debug ( "Ignored field '%s'.", field_context )
@@ -265,31 +293,38 @@ class DescriptionReader ( object ):
 						field_context = field_context_ref.get_name()
 
 						if not field_context:
-							raise Exception ( "Field name is not valid! This should've already been catched in DescriptionField..." )
+							raise Exception (
+								'Field name is not valid! This should\'ve '
+								'already been catched in DescriptionField...'
+							)
 
 						# create a new empty list for this field_context
 						read_data [field_context] = []
 
-						# add values to read_data
-						#  no need to check line_components [2] 'cause [1] was a true str
-						for val in make_values ( line_components [2], field_context ):
+						# add values to read_data, no need to check
+						#  line_components [2] 'cause [1] was a true str
+						for val in \
+							make_values ( line_components [2], field_context ) \
+						:
 							read_data [field_context] . append ( val )
 
-
-
 				else:
 					# reaching this branch means that
 					#  (a) line has no leading whitespace
 					#  (b) line has no separator (:)
 					# this should not occur in description files (bad syntax?)
-					self.logger.warning ( "Unexpected line in description file: '%s'.", line_components [0] )
+					self.logger.warning (
+						"Unexpected line in description file: '%s'."
+							% line_components [0]
+					)
 
 		# -- end for --
 
 		if self._parse_read_data ( read_data ):
-			self.logger.debug ( "Successfully read file '%s' with data = %s.",
-										self.fileinfo ['package_file'], str ( read_data )
-									)
+			self.logger.debug (
+				"Successfully read file '%s' with data = %s."
+					% ( self.fileinfo ['package_file'], read_data )
+			)
 			self.desc_data = read_data
 
 		# get_desc() is preferred, but this method returns the desc data, too



^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2012-06-22 18:14 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-06-22 18:13 [gentoo-commits] proj/R_overlay:master commit in: roverlay/depres/, roverlay/config/, roverlay/, roverlay/rpackage/, André Erdmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox