Commits

Michał Górny committed b9fb58a Merge with conflicts

Merge branch 'master' into 0.2.x

Conflicts:
gentoopm/basepm/metadata.py
gentoopm/basepm/pkg.py
gentoopm/paludispm/pkg.py
gentoopm/pkgcorepm/pkg.py
gentoopm/portagepm/pkg.py

Comments (0)

Files changed (46)

gentoopm/__init__.py

 # (c) 2011 Michał Górny <mgorny@gentoo.org>
 # Released under the terms of the 2-clause BSD license.
 
-PV = '0.1.4'
+PV = '0.1.5'
 
 """
 The package version.
 	@raise Exception: No package manager could be imported.
 	"""
 
-	from gentoopm.preferences import get_preferred_pms
-	from gentoopm.submodules import get_any_pm
+	from .preferences import get_preferred_pms
+	from .submodules import get_any_pm
 
 	return get_any_pm(get_preferred_pms())

gentoopm/basepm/__init__.py

 
 from abc import abstractmethod, abstractproperty
 
-from gentoopm.basepm.stack import PMRepoStackWrapper
-from gentoopm.util import ABCObject
+from ..util import ABCObject
+
+from .stack import PMRepoStackWrapper
 
 class PackageManager(ABCObject):
 	"""
 		"""
 		pass
 
+	@abstractproperty
+	def version(self):
+		"""
+		Return the PM version as a simple string.
+
+		@type: string
+		"""
+		pass
+
 	@abstractmethod
 	def reload_config(self):
 		"""

gentoopm/basepm/atom.py

 
 from abc import abstractmethod, abstractproperty
 
-from gentoopm.util import ABCObject, StringCompat, StringifiedComparisons, \
+from ..util import ABCObject, StringCompat, StringifiedComparisons, \
 		FillMissingComparisons
 
 class PMPackageKey(ABCObject, StringCompat, FillMissingComparisons):

gentoopm/basepm/config.py

 
 from abc import abstractproperty
 
-from gentoopm.util import ABCObject
+from ..util import ABCObject
 
 class PMConfig(ABCObject):
 	@abstractproperty

gentoopm/basepm/contents.py

 import os.path
 from abc import abstractmethod, abstractproperty
 
-from gentoopm.util import ABCObject, StringCompat
+from ..util import ABCObject, StringCompat
 
 class PMContentObj(StringCompat):
 	def __init__(self, path):

gentoopm/basepm/depend.py

 
 from abc import abstractmethod, abstractproperty
 
-from gentoopm.util import ABCObject, StringCompat
+from ..util import ABCObject, StringCompat
 
 class PMRequiredUseAtom(StringCompat):
 	"""

gentoopm/basepm/environ.py

 
 import bz2
 
-from gentoopm.bash import get_any_bashparser
+from ..bash import get_any_bashparser
 
 def _load_bp(bp, path):
 	"""

gentoopm/basepm/filter.py

 # Released under the terms of the 2-clause BSD license.
 
 from abc import abstractmethod
+from operator import attrgetter
+import itertools
 
-from gentoopm.util import ABCObject, FillMissingNotEqual
+from ..util import ABCObject, FillMissingNotEqual
 
 class PMPackageMatcher(ABCObject):
 	"""
 		@rtype: bool
 		"""
 		pass
+
+class SmartAttrGetter(object):
+	"""
+	A wrapper on attrgetter, supporting dots replaced by underscores. Uses the
+	first package matched to distinguish between real underscores and dots.
+	"""
+
+	def __init__(self, key):
+		self._k = key
+		self._getter = None
+
+	def __call__(self, obj):
+		if self._getter is not None:
+			return self._getter(obj)
+
+		def get_variants(args):
+			prev = None
+			for a in args:
+				if prev is not None:
+					yield ('%s_' % prev, '%s.' % prev)
+				prev = a
+			else:
+				yield (prev,)
+
+		variants = itertools.product(*get_variants(self._k.split('_')))
+		for v in variants:
+			self._getter = attrgetter(''.join(v))
+			try:
+				return self._getter(obj)
+			except AttributeError:
+				pass
+		else:
+			raise KeyError('Invalid keyword argument: %s' % self._k)
+
+class PMTransformedKeywordFilter(PMPackageMatcher):
+	_map = {
+		'key_category': 'key.category',
+		'key_package': 'key.package',
+		'key_state': 'key.state',
+		'description_short': 'description.short',
+		'description_long': 'description.long'
+	}
+
+	def __new__(self, key, val):
+		from ..filters import AttributeMatch
+		if key in self._map:
+			key = self._map[key]
+		return AttributeMatch(key, val)
+
+def transform_keyword_filters(kwargs):
+	"""
+	Transform a number of keyword filters into positional args.
+
+	@param kwargs: keyword arguments, as passed to L{PMPackageSet.filter()}
+	@type kwargs: dict
+	@return: positional arguments representing the keyword filters
+	@rtype: tuple
+	"""
+
+	return tuple([PMTransformedKeywordFilter(k, v)
+			for k, v in kwargs.items()])

gentoopm/basepm/pkg.py

 import os.path
 from abc import abstractmethod, abstractproperty
 
-from gentoopm.basepm.atom import PMAtom, PMPackageKey
-from gentoopm.basepm.environ import PMPackageEnvironment
-from gentoopm.util import ABCObject, FillMissingComparisons, StringCompat, \
-		EnumTuple
+from ..util import ABCObject, FillMissingComparisons, StringCompat, EnumTuple
+
+from .atom import PMAtom, PMPackageKey
+from .environ import PMPackageEnvironment
 
 PMPackageState = EnumTuple('PMPackageState',
 		'installable',
 	in the package tree.
 	"""
 
-	def _matches(self, *args, **kwargs):
+	def _matches(self, *args):
 		"""
 		Check whether the package matches passed filters. Please note that this
 		method may not be called at all if PM is capable of a more efficient
 			else:
 				raise ValueError('Incorrect positional argument: %s' % f)
 
-		for k, m in kwargs.items():
-			raise KeyError('Unmatched keyword argument: %s' % k)
-
 		return True
 
 	@abstractproperty

gentoopm/basepm/pkgset.py

 
 from abc import abstractmethod
 
-from gentoopm.exceptions import EmptyPackageSetError, AmbiguousPackageSetError
-from gentoopm.util import ABCObject, BoolCompat
+from .filter import transform_keyword_filters
+
+from ..exceptions import EmptyPackageSetError, AmbiguousPackageSetError
+from ..util import ABCObject, BoolCompat
 
 class PMPackageSet(ABCObject, BoolCompat):
 	""" A set of packages. """
 		Filter the packages based on arguments. Return a filtered package set.
 
 		The positional arguments can provide a number of L{PMPackageMatcher}s
-		and/or a L{PMAtom} instance. The keyword arguments match metadata keys
-		using '==' comparison with passed string (or L{PMKeywordMatcher}s).
+		(which are basically lambdas with a L{PMPackage} instance argument)
+		and/or a L{PMAtom} instance.
+
+		The keyword arguments match metadata keys using C{==} comparison with
+		the passed string (or L{PMKeywordMatcher}s). Keys are supposed to be
+		L{PMPackage} property names in Python; dots can be replaced by
+		underscores (e.g. C{description_short}) or passed using C{**} operator.
 
 		Multiple filters will be AND-ed together. Same applies for .filter()
 		called multiple times. You should, however, avoid passing multiple
 class PMFilteredPackageSet(PMPackageSet):
 	def __init__(self, src, args, kwargs):
 		self._src = src
-		self._args = args
-		self._kwargs = kwargs
+		self._args = args + transform_keyword_filters(kwargs)
 
 	def __iter__(self):
 		for el in self._src:
-			if el._matches(*self._args, **self._kwargs):
+			if el._matches(*self._args):
 				yield el
 
 class PMSortedPackageSet(PMPackageSet):

gentoopm/basepm/repo.py

 import os.path
 from abc import abstractmethod, abstractproperty
 
-from gentoopm.basepm.pkgset import PMPackageSet
-from gentoopm.util import ABCObject, FillMissingComparisons
+from ..util import ABCObject, FillMissingComparisons
+
+from .pkgset import PMPackageSet
 
 class PMRepositoryDict(ABCObject):
 	"""

gentoopm/basepm/stack.py

 # (c) 2011 Michał Górny <mgorny@gentoo.org>
 # Released under the terms of the 2-clause BSD license.
 
-from gentoopm.basepm.repo import PMRepository
-from gentoopm.basepm.pkgset import PMPackageSet
+from .repo import PMRepository
+from .pkgset import PMPackageSet
 
 class PMRepoStackWrapper(PMRepository):
 	"""

gentoopm/bash/__init__.py

 
 from abc import abstractmethod
 
-from gentoopm.util import ABCObject
+from ..util import ABCObject
 
 class BashParser(ABCObject):
 	"""

gentoopm/bash/bashserver.py

 
 import shutil, subprocess, tempfile
 
-from gentoopm.bash import BashParser
-from gentoopm.exceptions import InvalidBashCodeError
+from ..exceptions import InvalidBashCodeError
+
+from . import BashParser
 
 _bash_script = '''
 while

gentoopm/filters.py

+#!/usr/bin/python
+#	vim:fileencoding=utf-8
+# (c) 2011 Michał Górny <mgorny@gentoo.org>
+# Released under the terms of the 2-clause BSD license.
+
+from operator import attrgetter
+
+from .basepm.filter import PMPackageMatcher
+
+class AttributeMatch(PMPackageMatcher):
+	"""
+	A filter matching package attributes with values.
+	"""
+
+	def __init__(self, key, val):
+		self._getter = attrgetter(key)
+		self._val = val
+
+	def __call__(self, pkg):
+		return self._val == self._getter(pkg)

gentoopm/matchers.py

+#!/usr/bin/python
+#	vim:fileencoding=utf-8
+# (c) 2011 Michał Górny <mgorny@gentoo.org>
+# Released under the terms of the 2-clause BSD license.
+
+from .basepm.filter import PMKeywordMatcher
+
+import re
+
+class RegExp(PMKeywordMatcher):
+	"""
+	A keyword attribute matcher using a regular expression.
+	"""
+
+	def __init__(self, regexp):
+		"""
+		Instantiate the regexp matcher.
+
+		@param re: a regular expression to match values against
+		@type re: string/compiled regexp
+		"""
+		if not hasattr(regexp, 'match'):
+			regexp = re.compile(regexp)
+		self._re = regexp
+
+	def __eq__(self, val):
+		return bool(self._re.match(str(val)))
+
+class Contains(PMKeywordMatcher):
+	"""
+	A keyword attribute matcher checking for list membership.
+	"""
+
+	def __init__(self, elem):
+		self._elem = elem
+
+	def __eq__(self, val):
+		if isinstance(self._elem, str):
+			return self._elem in val
+		else:
+			for e in val:
+				if self._elem == e:
+					return True
+			return False

gentoopm/paludispm/__init__.py

 except (NameError, AttributeError):
 	raise ImportError('paludis version too old (at least 0.64.2 required)')
 
-from gentoopm.basepm import PackageManager
-from gentoopm.paludispm.atom import PaludisAtom
-from gentoopm.paludispm.config import PaludisConfig
-from gentoopm.paludispm.repo import PaludisRepoDict, PaludisInstalledRepo, \
-		PaludisStackRepo
+from ..basepm import PackageManager
+
+from .atom import PaludisAtom
+from .config import PaludisConfig
+from .repo import PaludisRepoDict, PaludisInstalledRepo, PaludisStackRepo
 
 class PaludisPM(PackageManager):
 	name = 'paludis'
 
+	@property
+	def version(self):
+		return paludis.VERSION
+
 	def reload_config(self):
 		self._env = paludis.EnvironmentFactory.instance.create('')
 

gentoopm/paludispm/atom.py

 
 import paludis, re
 
-from gentoopm.basepm.atom import PMAtom, PMPackageKey, PMPackageVersion, \
+from ..basepm.atom import PMAtom, PMPackageKey, PMPackageVersion, \
 		PMIncompletePackageKey
-from gentoopm.exceptions import InvalidAtomStringError
+from ..exceptions import InvalidAtomStringError
 
 _category_wildcard_re = re.compile(r'\w')
 

gentoopm/paludispm/config.py

 # (c) 2011 Michał Górny <mgorny@gentoo.org>
 # Released under the terms of the 2-clause BSD license.
 
-from gentoopm.basepm.config import PMConfig
+from ..basepm.config import PMConfig
 
 class PaludisConfig(PMConfig):
 	def __init__(self, env):

gentoopm/paludispm/contents.py

 # (c) 2011 Michał Górny <mgorny@gentoo.org>
 # Released under the terms of the 2-clause BSD license.
 
-from gentoopm.basepm.contents import PMPackageContents, \
-		PMContentObj
+from ..basepm.contents import PMPackageContents, PMContentObj
 
 class PaludisPackageContents(PMPackageContents):
 	def __init__(self, cont):

gentoopm/paludispm/depend.py

 import paludis, re
 from collections import namedtuple
 
-from gentoopm.basepm.depend import PMPackageDepSet, PMConditionalDep, \
+from ..basepm.depend import PMPackageDepSet, PMConditionalDep, \
 	PMAnyOfDep, PMAllOfDep, PMExactlyOneOfDep, PMBaseDep
-from gentoopm.paludispm.atom import PaludisAtom
+
+from .atom import PaludisAtom
 
 _block_re = re.compile('^!*')
 

gentoopm/paludispm/pkg.py

 
 import paludis
 
-from gentoopm.basepm.depend import PMRequiredUseAtom
-from gentoopm.basepm.pkg import PMPackage, PMPackageDescription, \
+from ..basepm.depend import PMRequiredUseAtom
+from ..basepm.pkg import PMPackage, PMPackageDescription, \
 		PMInstallablePackage, PMInstalledPackage, PMBoundPackageKey, \
 		PMPackageState, PMUseFlag
-from gentoopm.paludispm.atom import PaludisAtom, \
-		PaludisPackageKey, PaludisPackageVersion
-from gentoopm.paludispm.contents import PaludisPackageContents
-from gentoopm.paludispm.depend import PaludisPackageDepSet
-from gentoopm.util import SpaceSepFrozenSet, SpaceSepTuple
+from ..util import SpaceSepFrozenSet, SpaceSepTuple
+
+from .atom import PaludisAtom, PaludisPackageKey, PaludisPackageVersion
+from .contents import PaludisPackageContents
+from .depend import PaludisPackageDepSet
 
 class PaludisBoundPackageKey(PaludisPackageKey, PMBoundPackageKey):
 	def __init__(self, key, pkg):

gentoopm/paludispm/pkgset.py

 # (c) 2011 Michał Górny <mgorny@gentoo.org>
 # Released under the terms of the 2-clause BSD license.
 
-from gentoopm.basepm.pkgset import PMPackageSet, PMFilteredPackageSet
-from gentoopm.exceptions import EmptyPackageSetError, AmbiguousPackageSetError
-from gentoopm.paludispm.atom import PaludisAtom
+from ..basepm.pkgset import PMPackageSet, PMFilteredPackageSet
+from ..exceptions import EmptyPackageSetError, AmbiguousPackageSetError
+
+from .atom import PaludisAtom
 
 class PaludisPackageSet(object):
 	def __init__(self, env):

gentoopm/paludispm/repo.py

 
 import paludis
 
-from gentoopm.basepm.repo import PMRepository, PMRepositoryDict, \
-		PMEbuildRepository
-from gentoopm.paludispm.atom import PaludisAtom
-from gentoopm.paludispm.pkg import PaludisInstallableID, PaludisInstalledID
-from gentoopm.paludispm.pkgset import PaludisPackageSet
+from ..basepm.repo import PMRepository, PMRepositoryDict, PMEbuildRepository
+
+from .atom import PaludisAtom
+from .pkg import PaludisInstallableID, PaludisInstalledID
+from .pkgset import PaludisPackageSet
 
 class PaludisRepoDict(PMRepositoryDict):
 	def __iter__(self):

gentoopm/pkgcorepm/__init__.py

 # Released under the terms of the 2-clause BSD license.
 
 from pkgcore.config import load_config
+from pkgcore.const import VERSION
 
-from gentoopm.basepm import PackageManager
-from gentoopm.pkgcorepm.atom import PkgCoreAtom
-from gentoopm.pkgcorepm.config import PkgCoreConfig
-from gentoopm.pkgcorepm.repo import PkgCoreRepoDict, \
-		PkgCoreInstalledRepo
+from ..basepm import PackageManager
+
+from .atom import PkgCoreAtom
+from .config import PkgCoreConfig
+from .repo import PkgCoreRepoDict, PkgCoreInstalledRepo
 
 class PkgCorePM(PackageManager):
 	name = 'pkgcore'
 
+	@property
+	def version(self):
+		return VERSION
+
 	def reload_config(self):
 		c = load_config()
 		self._domain = c.get_default('domain')

gentoopm/pkgcorepm/atom.py

 from pkgcore.restrictions.boolean import AndRestriction
 from pkgcore.util.parserestrict import parse_match, ParseError
 
-from gentoopm.basepm.atom import PMAtom, PMPackageKey, PMPackageVersion, \
+from ..basepm.atom import PMAtom, PMPackageKey, PMPackageVersion, \
 		PMIncompletePackageKey
-from gentoopm.exceptions import InvalidAtomStringError
+from ..exceptions import InvalidAtomStringError
 
 def _find_res(res, cls):
 	if isinstance(res, AndRestriction):

gentoopm/pkgcorepm/config.py

 
 import pkgcore.os_data
 
-from gentoopm.basepm.config import PMConfig
+from ..basepm.config import PMConfig
 
 class PkgCoreConfig(PMConfig):
 	def __init__(self, domain):

gentoopm/pkgcorepm/contents.py

 # (c) 2011 Michał Górny <mgorny@gentoo.org>
 # Released under the terms of the 2-clause BSD license.
 
-from gentoopm.basepm.contents import PMPackageContents, \
+from ..basepm.contents import PMPackageContents, \
 		PMContentObj
 
 class PkgCorePackageContents(PMPackageContents):

gentoopm/pkgcorepm/depend.py

 from pkgcore.restrictions.packages import Conditional
 from pkgcore.restrictions.values import ContainmentMatch
 
-from gentoopm.basepm.depend import PMPackageDepSet, PMConditionalDep, \
+from ..basepm.depend import PMPackageDepSet, PMConditionalDep, \
 	PMAnyOfDep, PMAllOfDep, PMExactlyOneOfDep, PMBaseDep, PMRequiredUseAtom
-from gentoopm.pkgcorepm.atom import PkgCoreAtom
+
+from .atom import PkgCoreAtom
 
 class PkgCoreBaseDep(PMBaseDep):
 	def __init__(self, deps, pkg):

gentoopm/pkgcorepm/filter.py

 
 import pkgcore.restrictions.boolean as br
 
-from gentoopm.pkgcorepm.atom import PkgCoreAtom
-from gentoopm.pkgcorepm.pkg import PkgCorePackage
+from .atom import PkgCoreAtom
+from .pkg import PkgCorePackage
 
 def transform_filters(args, kwargs):
 	"""

gentoopm/pkgcorepm/pkg.py

 # (c) 2011 Michał Górny <mgorny@gentoo.org>
 # Released under the terms of the 2-clause BSD license.
 
-from gentoopm.basepm.pkg import PMPackage, PMPackageDescription, \
+from ..basepm.pkg import PMPackage, PMPackageDescription, \
 		PMInstalledPackage, PMInstallablePackage, PMBoundPackageKey, \
 		PMPackageState, PMUseFlag
-from gentoopm.basepm.pkgset import PMPackageSet, PMFilteredPackageSet
-from gentoopm.pkgcorepm.atom import PkgCoreAtom, PkgCorePackageKey
-from gentoopm.pkgcorepm.contents import PkgCorePackageContents
-from gentoopm.pkgcorepm.depend import PkgCorePackageDepSet
-from gentoopm.util import SpaceSepTuple, SpaceSepFrozenSet
+from ..basepm.pkgset import PMPackageSet, PMFilteredPackageSet
+from ..util import SpaceSepTuple, SpaceSepFrozenSet
+
+from .atom import PkgCoreAtom, PkgCorePackageKey
+from .contents import PkgCorePackageContents
+from .depend import PkgCorePackageDepSet
 
 class PkgCorePackageSet(PMPackageSet):
 	def filter(self, *args, **kwargs):

gentoopm/pkgcorepm/repo.py

 
 import pkgcore.restrictions.boolean as br
 
-from gentoopm.basepm.repo import PMRepository, PMRepositoryDict, \
+from ..basepm.repo import PMRepository, PMRepositoryDict, \
 		PMEbuildRepository
-from gentoopm.pkgcorepm.pkg import PkgCorePackageSet, PkgCoreFilteredPackageSet, \
+from ..util import FillMissingComparisons
+
+from .pkg import PkgCorePackageSet, PkgCoreFilteredPackageSet, \
 		PkgCoreInstallablePackage, PkgCoreInstalledPackage
-from gentoopm.pkgcorepm.filter import transform_filters
-from gentoopm.util import FillMissingComparisons
+from .filter import transform_filters
 
 class PkgCoreRepoDict(PMRepositoryDict):
 	def __iter__(self):

gentoopm/portagepm/__init__.py

 # Released under the terms of the 2-clause BSD license.
 
 import os
-from portage import create_trees
+from portage import create_trees, VERSION
 
-from gentoopm.basepm import PackageManager
-from gentoopm.portagepm.atom import PortageAtom
-from gentoopm.portagepm.config import PortageConfig
-from gentoopm.portagepm.repo import PortageRepoDict, VDBRepository
+from ..basepm import PackageManager
+
+from .atom import PortageAtom
+from .config import PortageConfig
+from .repo import PortageRepoDict, VDBRepository
 
 class PortagePM(PackageManager):
 	name = 'portage'
 
+	@property
+	def version(self):
+		return VERSION
+
 	def reload_config(self):
 		# Similarly to emerge, care for PORTAGE_CONFIGROOT and ROOT.
 		trees = create_trees(

gentoopm/portagepm/atom.py

 from portage.dep import match_from_list
 from portage.versions import catsplit, pkgsplit, cpv_getversion, vercmp
 
-from gentoopm.basepm.atom import PMAtom, PMPackageKey, PMPackageVersion, \
+from ..basepm.atom import PMAtom, PMPackageKey, PMPackageVersion, \
 		PMIncompletePackageKey
-from gentoopm.exceptions import InvalidAtomStringError
+from ..exceptions import InvalidAtomStringError
 
 class PortagePackageKey(PMPackageKey):
 	def __init__(self, cp):

gentoopm/portagepm/config.py

 
 import portage.data
 
-from gentoopm.basepm.config import PMConfig
+from ..basepm.config import PMConfig
 
 class PortageConfig(PMConfig):
 	def __init__(self, settings):

gentoopm/portagepm/contents.py

 # (c) 2011 Michał Górny <mgorny@gentoo.org>
 # Released under the terms of the 2-clause BSD license.
 
-from gentoopm.basepm.contents import PMPackageContents, \
-		PMContentObj
+from ..basepm.contents import PMPackageContents, PMContentObj
 
 class PortagePackageContents(PMPackageContents):
 	def __init__(self, dblink):

gentoopm/portagepm/depend.py

 from collections import namedtuple
 from portage.dep import paren_reduce, use_reduce
 
-from gentoopm.basepm.depend import PMPackageDepSet, PMConditionalDep, \
+from ..basepm.depend import PMPackageDepSet, PMConditionalDep, \
 	PMAnyOfDep, PMAllOfDep, PMExactlyOneOfDep, PMBaseDep
 
 class PortageBaseDep(PMBaseDep):

gentoopm/portagepm/pkg.py

 
 from portage.versions import cpv_getkey, cpv_getversion, vercmp
 
-from gentoopm.basepm.depend import PMRequiredUseAtom
-from gentoopm.basepm.pkg import PMPackage, PMPackageDescription, \
+from ..basepm.depend import PMRequiredUseAtom
+from ..basepm.pkg import PMPackage, PMPackageDescription, \
 		PMInstalledPackage, PMInstallablePackage, PMBoundPackageKey, \
 		PMPackageState, PMUseFlag
-from gentoopm.basepm.pkgset import PMPackageSet, PMFilteredPackageSet
-from gentoopm.portagepm.atom import PortageAtom, CompletePortageAtom, \
+from ..basepm.pkgset import PMPackageSet, PMFilteredPackageSet
+from ..util import SpaceSepTuple, SpaceSepFrozenSet
+
+from .atom import PortageAtom, CompletePortageAtom, \
 		PortagePackageKey, PortagePackageVersion, _get_atom
-from gentoopm.portagepm.contents import PortagePackageContents
-from gentoopm.portagepm.depend import PortagePackageDepSet
-from gentoopm.util import SpaceSepTuple, SpaceSepFrozenSet
+from .contents import PortagePackageContents
+from .depend import PortagePackageDepSet
 
 class PortagePackageSet(PMPackageSet):
 	def filter(self, *args, **kwargs):

gentoopm/portagepm/repo.py

 import portage.exception as pe
 from portage.versions import catsplit
 
-from gentoopm.basepm.repo import PMRepositoryDict, PMEbuildRepository, \
-		PMRepository
-from gentoopm.portagepm.atom import PortageAtom, CompletePortageAtom
-from gentoopm.portagepm.pkg import PortageCPV, PortageVDBCPV, PortagePackageSet, \
+from ..basepm.repo import PMRepositoryDict, PMEbuildRepository, PMRepository
+from ..util import FillMissingComparisons
+
+from .atom import PortageAtom, CompletePortageAtom
+from .pkg import PortageCPV, PortageVDBCPV, PortagePackageSet, \
 		PortageFilteredPackageSet
-from gentoopm.util import FillMissingComparisons
 
 class PortageRepoDict(PMRepositoryDict):
 	def __iter__(self):
 				repo_name = self._dbapi.repositories.get_name_for_location(key)
 			else:
 				repo_name = key
-			r = self._dbapi.repositories[repo_name]
+			try:
+				r = self._dbapi.repositories[repo_name]
+			except TypeError: # older portage doesn't have __getitem__() here
+				for r in self._dbapi.repositories:
+					if r.name == repo_name:
+						break
+				else:
+					raise KeyError(repo_name)
 		except KeyError:
 			raise KeyError('No repository matched key %s' % key)
 		else:

gentoopm/querycli.py

 import argparse, os.path
 from abc import abstractmethod
 
-from gentoopm import get_package_manager
-from gentoopm.util import ABCObject
+from . import get_package_manager
+from .util import ABCObject
 
 def _reponame(val):
 	"""
 				return 1
 			print(r.path)
 
+	class shell(PMQueryCommand):
+		"""
+		Run a Python shell with current PM selected.
+		"""
+		def __call__(self, pm, args):
+			welc = "The %s PM is now available as 'pm' object." % pm.name
+			kwargs = {}
+
+			try:
+				from IPython import embed
+			except ImportError:
+				try:
+					from IPython.Shell import IPShellEmbed
+				except ImportError:
+					print('For better user experience, install IPython.')
+					from code import InteractiveConsole
+					embed = InteractiveConsole({'pm': pm}).interact
+					kwargs['banner'] = welc
+				else:
+					embed = IPShellEmbed()
+					embed.set_banner(embed.IP.BANNER + '\n\n' + welc)
+			else:
+				kwargs['banner2'] = welc
+
+			embed(**kwargs)
+
 	def __iter__(self):
 		for k in dir(self):
 			if k.startswith('_'):

gentoopm/submodules.py

 # Released under the terms of the 2-clause BSD license.
 
 _supported_pms = {
-	'paludis': ('gentoopm.paludispm', 'PaludisPM'),
-	'pkgcore': ('gentoopm.pkgcorepm', 'PkgCorePM'),
-	'portage': ('gentoopm.portagepm', 'PortagePM')
+	'paludis': ('paludispm', 'PaludisPM'),
+	'pkgcore': ('pkgcorepm', 'PkgCorePM'),
+	'portage': ('portagepm', 'PortagePM')
 }
 
 def get_pm(pm_name):
 	"""
 
 	modname, clsname = _supported_pms[pm_name]
-	mod = __import__(modname, fromlist=[clsname], level=-1)
+	mod = __import__(modname, fromlist=[clsname], globals=globals(), level=1)
 	return getattr(mod, clsname)()
 
 def get_any_pm(pm_list):

gentoopm/tests/atom.py

 # (c) 2011 Michał Górny <mgorny@gentoo.org>
 # Released under the terms of the 2-clause BSD license.
 
-from gentoopm.exceptions import InvalidAtomStringError, AmbiguousPackageSetError
-from gentoopm.tests import PMTestCase, PackageNames
+from ..exceptions import InvalidAtomStringError, AmbiguousPackageSetError
+
+from . import PMTestCase, PackageNames
 
 class UserSpecifiedAtomTestCase(PMTestCase):
 	def setUp(self):

gentoopm/tests/config.py

 # (c) 2011 Michał Górny <mgorny@gentoo.org>
 # Released under the terms of the 2-clause BSD license.
 
-from gentoopm.tests import PMTestCase
+from . import PMTestCase
 
 class ConfigTestCase(PMTestCase):
 	def setUp(self):

gentoopm/tests/pkg.py

 
 import os.path
 
-from gentoopm.tests import PMTestCase, PackageNames
+from . import PMTestCase, PackageNames
 
 class PackagesTestCase(PMTestCase):
 	def setUp(self):

gentoopm/tests/psets.py

 # (c) 2011 Michał Górny <mgorny@gentoo.org>
 # Released under the terms of the 2-clause BSD license.
 
-from gentoopm.exceptions import AmbiguousPackageSetError, EmptyPackageSetError
-from gentoopm.tests import PMTestCase, PackageNames
-from gentoopm.util import BoolCompat
+from ..exceptions import AmbiguousPackageSetError, EmptyPackageSetError
+from ..util import BoolCompat
+
+from . import PMTestCase, PackageNames
 
 class IterChecker(BoolCompat):
 	def __init__(self, iterable):

gentoopm/tests/repo.py

 # (c) 2011 Michał Górny <mgorny@gentoo.org>
 # Released under the terms of the 2-clause BSD license.
 
-from gentoopm.tests import PMTestCase, PackageNames
+from . import PMTestCase, PackageNames
 
 class RepositoriesTestCase(PMTestCase):
 	def setUp(self):