aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Piotr Jaroszyński <peper@gentoo.org> 2007-08-17 22:03:04 +0000
committerAvatar Piotr Jaroszyński <peper@gentoo.org> 2007-08-17 22:03:04 +0000
commit9aa45a385b95c196fd4cc658be5be1ae700f7ba9 (patch)
treee5faa0a0226a69103e606086e9eab6a0848eccc0
parent20b595a9d0f776bd4f43b0ed922d69d54bf17398 (diff)
downloadpaludis-9aa45a385b95c196fd4cc658be5be1ae700f7ba9.tar.gz
paludis-9aa45a385b95c196fd4cc658be5be1ae700f7ba9.tar.xz
(python) Allow subclassing of Environment, Masks and MetadataKeys.
-rw-r--r--paludis/dep_list/dep_list.cc2
-rw-r--r--paludis/package_id.cc4
-rw-r--r--paludis/package_id.hh2
-rw-r--r--python/Makefile.am20
-rw-r--r--python/contents.cc4
-rw-r--r--python/dep_spec.cc8
-rwxr-xr-xpython/dep_spec_TEST.py2
-rw-r--r--python/environment.cc457
-rwxr-xr-xpython/environment_TEST.py119
-rw-r--r--python/fs_entry.cc11
-rw-r--r--python/mask.cc362
-rwxr-xr-xpython/mask_TEST.py100
-rw-r--r--python/metadata_key.cc512
-rw-r--r--python/metadata_key.hh55
-rwxr-xr-xpython/metadata_key_TEST.py219
-rw-r--r--python/name.cc15
-rw-r--r--python/package_id.cc16
-rw-r--r--python/query.cc7
-rwxr-xr-xpython/query_TEST.py3
-rw-r--r--python/repository.cc11
-rw-r--r--python/subclassing_test.cc220
-rw-r--r--src/clients/adjutrix/what_needs_keywording.cc2
-rw-r--r--src/clients/contrarius/install.cc2
-rw-r--r--src/clients/gtkpaludis/libgtkpaludis/versions_list_model.cc2
-rw-r--r--src/clients/paludis/install.cc2
-rw-r--r--src/clients/paludis/report.cc2
-rw-r--r--src/output/console_install_task.cc2
-rw-r--r--src/output/console_query_task.cc4
28 files changed, 1795 insertions, 370 deletions
diff --git a/paludis/dep_list/dep_list.cc b/paludis/dep_list/dep_list.cc
index 0605ad1..74f5864 100644
--- a/paludis/dep_list/dep_list.cc
+++ b/paludis/dep_list/dep_list.cc
@@ -411,7 +411,7 @@ DepList::AddVisitor::visit_leaf(const PackageDepSpec & a)
bool local_success(false);
for (DepListOverrideMasksFunctions::Iterator o(d->_imp->opts->override_masks->begin()),
o_end(next(of)) ; o != o_end ; ++o)
- if ((*o)(**p, *m))
+ if ((*o)(**p, **m))
local_success = true;
success &= local_success;
diff --git a/paludis/package_id.cc b/paludis/package_id.cc
index 810712d..0707b7f 100644
--- a/paludis/package_id.cc
+++ b/paludis/package_id.cc
@@ -100,14 +100,14 @@ PackageID::MasksIterator
PackageID::begin_masks() const
{
need_masks_added();
- return MasksIterator(indirect_iterator(_imp->masks.begin()));
+ return MasksIterator(_imp->masks.begin());
}
PackageID::MasksIterator
PackageID::end_masks() const
{
need_masks_added();
- return MasksIterator(indirect_iterator(_imp->masks.end()));
+ return MasksIterator(_imp->masks.end());
}
bool
diff --git a/paludis/package_id.hh b/paludis/package_id.hh
index 756c834..83c7e85 100644
--- a/paludis/package_id.hh
+++ b/paludis/package_id.hh
@@ -113,7 +113,7 @@ namespace paludis
///\name Masks
///\{
- typedef libwrapiter::ForwardIterator<PackageID, const Mask> MasksIterator;
+ typedef libwrapiter::ForwardIterator<PackageID, tr1::shared_ptr<const Mask> > MasksIterator;
MasksIterator begin_masks() const PALUDIS_ATTRIBUTE((warn_unused_result));
MasksIterator end_masks() const PALUDIS_ATTRIBUTE((warn_unused_result));
bool masked() const PALUDIS_ATTRIBUTE((warn_unused_result));
diff --git a/python/Makefile.am b/python/Makefile.am
index e0fd749..b4d379b 100644
--- a/python/Makefile.am
+++ b/python/Makefile.am
@@ -56,7 +56,7 @@ IF_PYTHON_SOURCES = \
exception.hh exception.cc \
fs_entry.cc \
mask.cc \
- metadata_key.hh metadata_key.cc \
+ metadata_key.cc \
mutex.hh mutex.cc \
name.cc \
log.cc \
@@ -119,6 +119,11 @@ lib_LTLIBRARIES = libpaludispython.la
libpaludispython_la_CXXFLAGS = $(AM_CXXFLAGS) -I. -I@PYTHON_INCLUDE_DIR@
libpaludispython_la_LDFLAGS = @BOOST_PYTHON_LIB@
+noinst_LTLIBRARIES = libsubclassingtest.la
+
+libsubclassingtest_la_CXXFLAGS = $(AM_CXXFLAGS) -I. -I@PYTHON_INCLUDE_DIR@
+libsubclassingtest_la_LDFLAGS = @BOOST_PYTHON_LIB@ -rpath /nowhere
+
paludis_python_so.o : paludis_python_so.cc
if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) \
$(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(AM_CXXFLAGS) -I$(PYTHON_INCLUDE_DIR) -c \
@@ -150,7 +155,10 @@ libpaludispython_la_LIBADD = \
$(top_builddir)/paludis/environments/test/libpaludistestenvironment.la \
$(top_builddir)/paludis/environments/libpaludisenvironments.la
-check_DATA = .libs/paludis.so
+libsubclassingtest_la_SOURCES = subclassing_test.cc
+libsubclassingtest_la_LIBADD = $(libpaludispython_la_LIBADD)
+
+check_DATA = .libs/paludis.so subclassing_test.so
pythonlibdir = @PYTHON_INSTALL_DIR@
pythonlib_DATA = paludis.so
@@ -173,6 +181,14 @@ paludis.so : libpaludispython.la paludis_python_so.o
.libs/paludis_python_so.o \
-L$(top_builddir)/python/.libs -lpaludispython
+subclassing_test.so : libsubclassingtest.la
+ $(CXX) -fPIC -shared $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) \
+ -I@PYTHON_INCLUDE_DIR@ @BOOST_PYTHON_LIB@ $(PTHREAD_LIBS) \
+ -o $@ \
+ -L$(top_builddir)/python/.libs -lsubclassingtest
+
endif
built-sources : $(BUILT_SOURCES)
diff --git a/python/contents.cc b/python/contents.cc
index 20206a7..f63f2cb 100644
--- a/python/contents.cc
+++ b/python/contents.cc
@@ -134,8 +134,8 @@ void expose_contents()
/**
* Contents
*/
- register_shared_ptrs_to_python<Contents>();
- bp::class_<Contents, boost::noncopyable>
+ register_shared_ptrs_to_python<Contents>(rsp_const);
+ bp::class_<Contents, tr1::shared_ptr<Contents>, boost::noncopyable>
(
"Contents",
"Iterable of ContentsEntry.\n"
diff --git a/python/dep_spec.cc b/python/dep_spec.cc
index c2d6459..38f2b8f 100644
--- a/python/dep_spec.cc
+++ b/python/dep_spec.cc
@@ -1173,6 +1173,8 @@ void expose_dep_spec()
"Iterable class for dependency specs that have a number of child dependency specs.",
bp::no_init
)
+ .def("add_child", &PythonCompositeDepSpec::add_child)
+
.def("__iter__", bp::range(&PythonCompositeDepSpec::begin, &PythonCompositeDepSpec::end))
;
@@ -1183,7 +1185,7 @@ void expose_dep_spec()
(
"AnyDepSpec",
"Represents a \"|| ( )\" dependency block.",
- bp::no_init
+ bp::init<>("__init__()")
);
/**
@@ -1193,7 +1195,7 @@ void expose_dep_spec()
(
"AllDepSpec",
"Represents a ( first second third ) or top level group of dependency specs.",
- bp::no_init
+ bp::init<>("__init__()")
);
/**
@@ -1203,7 +1205,7 @@ void expose_dep_spec()
(
"UseDepSpec",
"Represents a use? ( ) dependency spec.",
- bp::no_init
+ bp::init<const UseFlagName &, bool>("__init__(UseFlagName, inverse_bool)")
)
.add_property("flag", &UseDepSpec::flag,
"[ro] UseFlagName\n"
diff --git a/python/dep_spec_TEST.py b/python/dep_spec_TEST.py
index 232159f..053cbe5 100755
--- a/python/dep_spec_TEST.py
+++ b/python/dep_spec_TEST.py
@@ -32,8 +32,6 @@ class TestCase_1_DepSpecs(unittest.TestCase):
def test_02_create_error(self):
self.assertRaises(Exception, DepSpec)
- self.assertRaises(Exception, AllDepSpec)
- self.assertRaises(Exception, AnyDepSpec)
self.assertRaises(Exception, StringDepSpec)
self.assertRaises(BadVersionOperatorError, PackageDepSpec, "<>foo/bar", PackageDepSpecParseMode.PERMISSIVE)
self.assertRaises(PackageDepSpecError, PackageDepSpec, "=foo/bar", PackageDepSpecParseMode.PERMISSIVE)
diff --git a/python/environment.cc b/python/environment.cc
index 18f77fd..4632674 100644
--- a/python/environment.cc
+++ b/python/environment.cc
@@ -19,6 +19,7 @@
#include <python/paludis_python.hh>
#include <python/exception.hh>
+#include <python/iterable.hh>
#include <paludis/environment.hh>
#include <paludis/environments/environment_maker.hh>
@@ -27,12 +28,323 @@
#include <paludis/environments/paludis/paludis_config.hh>
#include <paludis/environments/no_config/no_config_environment.hh>
#include <paludis/environments/test/test_environment.hh>
+#include <paludis/hook.hh>
#include <paludis/package_id.hh>
using namespace paludis;
using namespace paludis::python;
namespace bp = boost::python;
+class EnvironmentImplementationWrapper :
+ public EnvironmentImplementation,
+ public bp::wrapper<EnvironmentImplementation>
+{
+ private:
+ tr1::shared_ptr<PackageDatabase> _db;
+
+ protected:
+ virtual tr1::shared_ptr<SetSpecTree::ConstItem> local_set(const SetName & s) const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ return tr1::shared_ptr<SetSpecTree::ConstItem>();
+ }
+
+ public:
+ EnvironmentImplementationWrapper() :
+ _db(new PackageDatabase(this))
+ {
+ }
+
+ virtual bool query_use(const UseFlagName & u, const PackageID & p) const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("query_use"))
+ return f(boost::cref(u), boost::cref(p));
+ return EnvironmentImplementation::query_use(u, p);
+ }
+
+ bool default_query_use(const UseFlagName & u, const PackageID & p) const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ return EnvironmentImplementation::query_use(u, p);
+ }
+
+ virtual tr1::shared_ptr<const UseFlagNameSet> known_use_expand_names(
+ const UseFlagName & u, const PackageID & p) const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("known_use_expand_names"))
+ return f(boost::cref(u), boost::cref(p));
+ else
+ throw PythonMethodNotImplemented("EnvironmentImplementation", "known_use_expand_names");
+ }
+
+ virtual bool accept_license(const std::string & s, const PackageID & p) const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("accept_license"))
+ return f(s, boost::cref(p));
+ else
+ throw PythonMethodNotImplemented("EnvironmentImplementation", "accept_license");
+ }
+
+ virtual bool accept_keywords(tr1::shared_ptr<const KeywordNameSet> k, const PackageID & p) const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("accept_keywords"))
+ return f(k, boost::cref(p));
+ else
+ throw PythonMethodNotImplemented("EnvironmentImplementation", "accept_keywords");
+ }
+
+ virtual const tr1::shared_ptr<const Mask> mask_for_breakage(const PackageID & p) const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("mask_for_breakage"))
+ return f(boost::cref(p));
+ else
+ throw PythonMethodNotImplemented("EnvironmentImplementation", "mask_for_breakage");
+ }
+
+ virtual const tr1::shared_ptr<const Mask> mask_for_user(const PackageID & p) const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("mask_for_user"))
+ return f(boost::cref(p));
+ else
+ throw PythonMethodNotImplemented("EnvironmentImplementation", "mask_for_user");
+ }
+
+ virtual bool unmasked_by_user(const PackageID & p) const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("unmasked_by_user"))
+ return f(boost::cref(p));
+ else
+ throw PythonMethodNotImplemented("EnvironmentImplementation", "unmasked_by_user");
+ }
+
+ virtual tr1::shared_ptr<PackageDatabase> package_database()
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ return _db;
+ }
+
+ virtual tr1::shared_ptr<const PackageDatabase> package_database() const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ return _db;
+ }
+
+ virtual tr1::shared_ptr<const FSEntrySequence> bashrc_files() const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("bashrc_files"))
+ return f();
+ return EnvironmentImplementation::bashrc_files();
+ }
+
+ tr1::shared_ptr<const FSEntrySequence> default_bashrc_files() const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ return EnvironmentImplementation::bashrc_files();
+ }
+
+ virtual tr1::shared_ptr<const FSEntrySequence> syncers_dirs() const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("syncers_dirs"))
+ return f();
+ return EnvironmentImplementation::syncers_dirs();
+ }
+
+ tr1::shared_ptr<const FSEntrySequence> default_syncers_dirs() const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ return EnvironmentImplementation::syncers_dirs();
+ }
+
+ virtual tr1::shared_ptr<const FSEntrySequence> fetchers_dirs() const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("fetchers_dirs"))
+ return f();
+ return EnvironmentImplementation::fetchers_dirs();
+ }
+
+ tr1::shared_ptr<const FSEntrySequence> default_fetchers_dirs() const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ return EnvironmentImplementation::fetchers_dirs();
+ }
+
+ virtual tr1::shared_ptr<const FSEntrySequence> hook_dirs() const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("hook_dirs"))
+ return f();
+ else
+ throw PythonMethodNotImplemented("EnvironmentImplementation", "hook_dirs");
+ }
+
+ virtual std::string paludis_command() const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("paludis_command"))
+ return f();
+ else
+ throw PythonMethodNotImplemented("EnvironmentImplementation", "paludis_command");
+ }
+
+ virtual void set_paludis_command(const std::string & s)
+ {
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("set_paludis_command"))
+ f(s);
+ else
+ throw PythonMethodNotImplemented("EnvironmentImplementation", "set_paludis_command");
+ }
+
+ virtual const FSEntry root() const
+ {
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("root"))
+ return f();
+ else
+ throw PythonMethodNotImplemented("EnvironmentImplementation", "root");
+ }
+
+ virtual uid_t reduced_uid() const
+ {
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("reduced_uid"))
+ return f();
+ else
+ throw PythonMethodNotImplemented("EnvironmentImplementation", "reduced_uid");
+ }
+
+ virtual gid_t reduced_gid() const
+ {
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("reduced_gid"))
+ return f();
+ else
+ throw PythonMethodNotImplemented("EnvironmentImplementation", "reduced_gid");
+ }
+
+
+ virtual tr1::shared_ptr<const MirrorsSequence> mirrors(const std::string & s) const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("mirrors"))
+ return f(s);
+ else
+ throw PythonMethodNotImplemented("EnvironmentImplementation", "mirrors");
+ }
+
+ virtual tr1::shared_ptr<const SetNameSet> set_names() const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("set_names"))
+ return f();
+ return EnvironmentImplementation::set_names();
+ }
+
+ tr1::shared_ptr<const SetNameSet> default_set_names() const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ return EnvironmentImplementation::set_names();
+ }
+
+ virtual tr1::shared_ptr<SetSpecTree::ConstItem> set(const SetName & s) const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("set"))
+ return f(boost::cref(s));
+ return EnvironmentImplementation::set(s);
+ }
+
+ tr1::shared_ptr<SetSpecTree::ConstItem> default_set(const SetName & s) const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ return EnvironmentImplementation::set(s);
+ }
+
+ virtual tr1::shared_ptr<const DestinationsSet> default_destinations() const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("default_destinations"))
+ return f();
+ return EnvironmentImplementation::default_destinations();
+ }
+
+ tr1::shared_ptr<const DestinationsSet> default_default_destinations() const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ return EnvironmentImplementation::default_destinations();
+ }
+
+ // FIXME - Hooks are not exposed
+ virtual HookResult perform_hook(const Hook & h) const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ return HookResult(0, "");
+ }
+
+ virtual std::string default_distribution() const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("default_distribution"))
+ return f();
+ return EnvironmentImplementation::default_distribution();
+ }
+
+ std::string default_default_distribution() const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ return EnvironmentImplementation::default_distribution();
+ }
+
+};
+
struct NoConfigEnvironmentWrapper :
NoConfigEnvironment
{
@@ -67,6 +379,16 @@ void expose_environment()
"Thrown if the config directory cannot be found by PaludisConfig.");
/**
+ * StringIterable
+ */
+ class_iterable<Sequence<std::string> >
+ (
+ "StringIterable",
+ "Iterable of string",
+ true
+ );
+
+ /**
* EnvironmentMaker
*/
bp::class_<EnvironmentMaker, boost::noncopyable>
@@ -131,6 +453,140 @@ void expose_environment()
;
/**
+ * EnvironmentImplementation
+ */
+ typedef EnvironmentImplementation EnvImp;
+ typedef EnvironmentImplementationWrapper EnvImpW;
+ bp::class_<EnvironmentImplementationWrapper, tr1::shared_ptr<EnvironmentImplementationWrapper>,
+ bp::bases<Environment>, boost::noncopyable>
+ (
+ "EnvironmentImplementation",
+ "Represents a working environment, which contains an available packages database\n"
+ "and provides various methods for querying package visibility and options.\n"
+ "This class can be subclassed in Python.",
+ bp::init<>()
+ )
+ //FIXME - local_set is protected
+ //.def("local_set", bp::pure_virtual(&EnvImp::local_set))
+
+ .def("query_use", &EnvImp::query_use, &EnvImpW::default_query_use,
+ "query_use(UseFlagName, PackageID) -> bool\n"
+ "Is a particular use flag enabled for a particular package?"
+ )
+
+ .def("known_use_expand_names", bp::pure_virtual(&EnvImp::known_use_expand_names),
+ "known_use_expand_names(UseFlagName, PackageID) -> UseFlagNameIterable\n"
+ "Return a collection of known use flag names for a particular package that start\n"
+ "with a particular use expand prefix.\n\n"
+ "It is up to subclasses to decide whether to return all known use flags with\n"
+ "the specified prefix or merely all enabled use flags. It is not safe to assume\n"
+ "that all flags in the returned value will be enabled for the specified package."
+ )
+
+ .def("accept_license", bp::pure_virtual(&EnvImp::accept_license),
+ "accept_license(str, PackageID) -> bool\n"
+ "Do we accept a particular license for a particular package?"
+ )
+
+ .def("accept_keywords", bp::pure_virtual(&EnvImp::accept_keywords),
+ "accept_keywords(KeywordsNameIterable, PackageID)\n"
+ "Do we accept any of the specified keywords for a particular package?\n\n"
+ "If the collection includes \"*\", should return true."
+ )
+
+ .def("mask_for_breakage", bp::pure_virtual(&EnvImp::mask_for_breakage),
+ "mask_for_breakage(PackageID) -> Mask\n"
+ "Do we have a 'breaks' mask for a particular package?\n\n"
+ "Returns None if no."
+ )
+
+ .def("mask_for_user", bp::pure_virtual(&EnvImp::mask_for_user),
+ "mask_for_user(PackageID) -> Mask\n"
+ "Do we have a 'user' mask for a particular package?\n\n"
+ "Returns None if no."
+ )
+
+ .def("unmasked_by_user", bp::pure_virtual(&EnvImp::unmasked_by_user),
+ "unmasked_by_user(PackageID) -> bool\n"
+ "Do we have a user unmask for a particular package?\n\n"
+ "This is only applied to repository and profile style masks, not\n"
+ "keywords, licences etc. If true, user_mask shouldn't be used."
+ )
+
+ .def("bashrc_files", &EnvImp::bashrc_files, &EnvImpW::default_bashrc_files,
+ "bashrc_files() -> list of paths\n"
+ "Return a collection of bashrc files to be used by the various components\n"
+ "that are implemented in bash."
+ )
+
+ .def("syncers_dirs", &EnvImp::syncers_dirs, &EnvImpW::default_syncers_dirs,
+ "syncers_dirs() -> list of paths\n"
+ "Return directories to search for syncer scripts."
+ )
+
+ .def("fetchers_dirs", &EnvImp::fetchers_dirs, &EnvImpW::default_fetchers_dirs,
+ "fetchers_dirs() -> list of paths\n"
+ "Return directories to search for fetcher scripts."
+ )
+
+ .def("hook_dirs", bp::pure_virtual(&EnvImp::hook_dirs),
+ "hook_dirs() -> list of paths\n"
+ "Return directories to search for hooks."
+ )
+
+ .def("paludis_command", bp::pure_virtual(&EnvImp::paludis_command),
+ "paludis_command() -> str\n"
+ "Return the command used to launch paludis (the client)."
+ )
+
+ .def("set_paludis_command", bp::pure_virtual(&EnvImp::set_paludis_command),
+ "set_paludis_command(str)\n"
+ "Change the command used to launch paludis (the client)."
+ )
+
+ .def("root", bp::pure_virtual(&EnvImp::root),
+ "root() -> path\n"
+ "Our root location for installs."
+ )
+
+ .def("reduced_uid", bp::pure_virtual(&EnvImp::reduced_uid),
+ "reduced_uid() -> int\n"
+ "User id to use when reduced privs are permissible."
+ )
+
+ .def("reduced_gid", bp::pure_virtual(&EnvImp::reduced_gid),
+ "reduced_gid() -> int\n"
+ "Group id to use when reduced privs are permissible."
+ )
+
+ .def("mirrors", bp::pure_virtual(&EnvImp::mirrors),
+ "mirrors(str) -> list of str\n"
+ "Return the mirror URI prefixes for a named mirror."
+ )
+
+ .def("set_names", &EnvImp::set_names, &EnvImpW::default_set_names,
+ "set_names() -> list of SetName\n"
+ "Return all known named sets."
+ )
+
+ .def("set", &EnvImp::set, &EnvImpW::default_set,
+ "set(SetName) -> CompositeDepSpec\n"
+ "Return a named set.\n\n"
+ "If the named set is not known, returns None."
+ )
+
+ .def("default_destinations", &EnvImp::default_destinations, &EnvImpW::default_default_destinations,
+ "default_destinations() -> list of Repository\n"
+ "Default destination candidates for installing packages."
+ )
+
+ .def("default_distribution", &EnvImp::default_distribution, &EnvImpW::default_default_distribution,
+ "default_distribution() -> str\n"
+ "NEED_DOC"
+ )
+ ;
+
+ /**
* AdaptedEnvironment
*/
bp::class_<AdaptedEnvironment, bp::bases<Environment>, boost::noncopyable>
@@ -210,5 +666,4 @@ void expose_environment()
"control all the options rather than reading them from configuration files.",
bp::init<>("__init__()")
);
-
}
diff --git a/python/environment_TEST.py b/python/environment_TEST.py
index de57e3c..7f4ea49 100755
--- a/python/environment_TEST.py
+++ b/python/environment_TEST.py
@@ -26,15 +26,16 @@ slaverepo = os.path.join(os.getcwd(), "environment_TEST_dir/slaverepo")
os.environ["PALUDIS_HOME"] = ph
from paludis import *
+from subclassing_test import *
+
import unittest
Log.instance.log_level = LogLevel.WARNING
class TestCase_01_Environments(unittest.TestCase):
def setUp(self):
- global e, nce
- e = EnvironmentMaker.instance.make_from_spec("")
- nce = NoConfigEnvironment(repo)
+ self.e = EnvironmentMaker.instance.make_from_spec("")
+ self.nce = NoConfigEnvironment(repo)
def test_01_create(self):
NoConfigEnvironment(repo)
@@ -51,49 +52,49 @@ class TestCase_01_Environments(unittest.TestCase):
self.assert_(isinstance(NoConfigEnvironment(repo), Environment))
def test_04_query_use(self):
- pid = iter(e.package_database.query(Query.Matches(
+ pid = iter(self.e.package_database.query(Query.Matches(
PackageDepSpec("=foo/bar-1.0", PackageDepSpecParseMode.PERMISSIVE)),
QueryOrder.REQUIRE_EXACTLY_ONE)).next()
- self.assert_(e.query_use("enabled", pid))
- self.assert_(not e.query_use("not_enabled", pid))
- self.assert_(e.query_use("sometimes_enabled", pid))
+ self.assert_(self.e.query_use("enabled", pid))
+ self.assert_(not self.e.query_use("not_enabled", pid))
+ self.assert_(self.e.query_use("sometimes_enabled", pid))
- self.assert_(not nce.query_use("foo", pid))
+ self.assert_(not self.nce.query_use("foo", pid))
def test_06_package_database(self):
- self.assert_(isinstance(e.package_database, PackageDatabase))
- self.assert_(isinstance(nce.package_database, PackageDatabase))
+ self.assert_(isinstance(self.e.package_database, PackageDatabase))
+ self.assert_(isinstance(self.nce.package_database, PackageDatabase))
def test_07_sets(self):
- self.assert_(isinstance(e.set("everything"), AllDepSpec))
- self.assert_(isinstance(nce.set("everything"), AllDepSpec))
+ self.assert_(isinstance(self.e.set("everything"), AllDepSpec))
+ self.assert_(isinstance(self.nce.set("everything"), AllDepSpec))
- self.assert_(isinstance(e.set_names, SetNameIterable))
- self.assert_(isinstance(nce.set_names, SetNameIterable))
+ self.assert_(isinstance(self.e.set_names, SetNameIterable))
+ self.assert_(isinstance(self.nce.set_names, SetNameIterable))
def test_08_repositories(self):
nce2 = NoConfigEnvironment(repo, master_repository_dir=slaverepo)
- self.assert_(isinstance(nce.main_repository, Repository))
- self.assertEquals(nce.master_repository, None)
+ self.assert_(isinstance(self.nce.main_repository, Repository))
+ self.assertEquals(self.nce.master_repository, None)
self.assert_(isinstance(nce2.main_repository, Repository))
self.assert_(isinstance(nce2.master_repository, Repository))
def test_09_root(self):
- self.assert_(isinstance(e.root, str))
- self.assert_(isinstance(nce.root, str))
+ self.assert_(isinstance(self.e.root, str))
+ self.assert_(isinstance(self.nce.root, str))
def test_10_default_destinations(self):
- self.assert_(isinstance(e.default_destinations, DestinationsIterable))
- self.assert_(isinstance(nce.default_destinations, DestinationsIterable))
+ self.assert_(isinstance(self.e.default_destinations, DestinationsIterable))
+ self.assert_(isinstance(self.nce.default_destinations, DestinationsIterable))
def test_11_set_accept_unstable(self):
- nce.accept_unstable = True
- self.assertRaises(AttributeError, lambda: nce.accept_unstable)
+ self.nce.accept_unstable = True
+ self.assertRaises(AttributeError, lambda: self.nce.accept_unstable)
def test_12_config_dir(self):
- self.assert_(isinstance(e.config_dir, str))
+ self.assert_(isinstance(self.e.config_dir, str))
class TestCase_02_AdaptedEnvironment(unittest.TestCase):
def test_01_create(self):
@@ -138,5 +139,77 @@ class TestCase_03_TestEnvironment(unittest.TestCase):
def test_01_create(self):
env = TestEnvironment()
+class TestCase_04_Environment_subclassingd(unittest.TestCase):
+ class SubEnv(EnvironmentImplementation):
+ def __init__(self):
+ EnvironmentImplementation.__init__(self)
+
+ def query_use(self, use, pid):
+ return EnvironmentImplementation.query_use(self, use, pid)
+
+ def known_use_expand_names(self, use, pid):
+ return [UseFlagName("a"), "u"]
+
+ def accept_license(self, l, pid):
+ return False
+
+ def accept_keywords(self, kns, pid):
+ return False
+
+ def mask_for_breakage(self, pid):
+ return UserMask()
+
+ def mask_for_user(self, pid):
+ return UserMask()
+
+ def unmasked_by_user(self, pid):
+ return False
+
+ def bashrc_files(self):
+ return ["/path"]
+
+ def syncers_dirs(self):
+ return ["/path"]
+
+ def fetchers_dirs(self):
+ return ["/path"]
+
+ def hook_dirs(self):
+ return ["/path"]
+
+ def paludis_command(self):
+ return "paludis"
+
+ def set_paludis_command(self, s):
+ pass
+
+ def root(self):
+ return "/"
+
+ def reduced_uid(self):
+ return 0
+
+ def reduced_gid(self):
+ return 0
+
+ def mirrors(self, mirror):
+ return ["mirror"]
+
+ def set_names(self):
+ return ["set"]
+
+ def set(self, set):
+ return AllDepSpec()
+
+ def default_destinations(self):
+ e = EnvironmentMaker.instance.make_from_spec("")
+ return [x for x in e.package_database.repositories]
+
+ def default_distribution(self):
+ return EnvironmentImplementation.default_distribution(self)
+
+ def test_01_environment_implementation(self):
+ test_env(self.SubEnv())
+
if __name__ == "__main__":
unittest.main()
diff --git a/python/fs_entry.cc b/python/fs_entry.cc
index 309d45d..b2e28dc 100644
--- a/python/fs_entry.cc
+++ b/python/fs_entry.cc
@@ -19,6 +19,7 @@
#include <python/paludis_python.hh>
#include <python/exception.hh>
+#include <python/iterable.hh>
#include <paludis/util/fs_entry.hh>
@@ -40,4 +41,14 @@ void expose_fs_entry()
*/
bp::implicitly_convertible<std::string, FSEntry>();
bp::to_python_converter<FSEntry, to_string<FSEntry> >();
+
+ /**
+ * FSEntryIterable
+ */
+ class_iterable<FSEntrySequence>
+ (
+ "FSEntryIterable",
+ "Iterable of FSEntry",
+ true
+ );
}
diff --git a/python/mask.cc b/python/mask.cc
index 0804745..1d0f168 100644
--- a/python/mask.cc
+++ b/python/mask.cc
@@ -20,8 +20,6 @@
#include <python/paludis_python.hh>
#include <python/iterable.hh>
-#include <python/metadata_key.hh>
-
#include <paludis/mask.hh>
#include <paludis/util/visitor-impl.hh>
@@ -29,72 +27,248 @@ using namespace paludis;
using namespace paludis::python;
namespace bp = boost::python;
-struct MaskToPython :
- ConstVisitor<MaskVisitorTypes>
+class MaskSptrToPythonVisitor :
+ public ConstVisitor<MaskVisitorTypes>
{
- bp::object value;
+ private:
+ const tr1::shared_ptr<const Mask> & _m_ptr;
+
+ public:
+ bp::object obj;
+
+ MaskSptrToPythonVisitor(const tr1::shared_ptr<const Mask> & m_ptr) :
+ _m_ptr(m_ptr)
+ {
+ }
+
+ void visit(const UserMask & m)
+ {
+ obj = bp::object(tr1::static_pointer_cast<const UserMask>(_m_ptr));
+ }
+
+ void visit(const UnacceptedMask & m)
+ {
+ obj = bp::object(tr1::static_pointer_cast<const UnacceptedMask>(_m_ptr));
+ }
+
+ void visit(const RepositoryMask & m)
+ {
+ obj = bp::object(tr1::static_pointer_cast<const RepositoryMask>(_m_ptr));
+ }
+
+ void visit(const UnsupportedMask & m)
+ {
+ obj = bp::object(tr1::static_pointer_cast<const UnsupportedMask>(_m_ptr));
+ }
- void visit(const UserMask & m)
+ void visit(const AssociationMask & m)
+ {
+ obj = bp::object(tr1::static_pointer_cast<const AssociationMask>(_m_ptr));
+ }
+};
+
+struct MaskSptrToPython
+{
+ MaskSptrToPython()
{
- value = bp::object(bp::ptr(&m));
+ bp::to_python_converter<tr1::shared_ptr<const Mask>, MaskSptrToPython>();
}
- void visit(const UnacceptedMask & m)
+ static PyObject *
+ convert(const tr1::shared_ptr<const Mask> & m)
{
- value = bp::object(bp::ptr(&m));
+ MaskSptrToPythonVisitor v(m);
+ m->accept(v);
+ return bp::incref(v.obj.ptr());
}
+};
- void visit(const RepositoryMask & m)
+struct MaskWrapper :
+ Mask,
+ bp::wrapper<Mask>
+{
+ virtual const char key() const
{
- value = bp::object(bp::ptr(&m));
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("key"))
+ return f();
+ else
+ throw PythonMethodNotImplemented("Mask", "key");
}
- void visit(const UnsupportedMask & m)
+ virtual const std::string description() const
{
- value = bp::object(bp::ptr(&m));
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("description"))
+ return f();
+ else
+ throw PythonMethodNotImplemented("Mask", "description");
}
+};
- void visit(const AssociationMask & m)
+struct UserMaskWrapper :
+ UserMask,
+ bp::wrapper<UserMask>
+{
+ virtual const char key() const
{
- value = bp::object(bp::ptr(&m));
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("key"))
+ return f();
+ else
+ throw PythonMethodNotImplemented("UserMask", "key");
+ }
+
+ virtual const std::string description() const
+ {
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("description"))
+ return f();
+ else
+ throw PythonMethodNotImplemented("UserMask", "description");
}
};
-struct mask_to_python
+struct UnacceptedMaskWrapper :
+ UnacceptedMask,
+ bp::wrapper<UnacceptedMask>
{
- static PyObject *
- convert(const Mask & m)
+ virtual const tr1::shared_ptr<const MetadataKey> unaccepted_key() const
{
- MaskToPython v;
- m.accept(v);
- return bp::incref(v.value.ptr());
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("unaccepted_key"))
+ return f();
+ else
+ throw PythonMethodNotImplemented("UnacceptedMask", "unaccepted_key");
+ }
+
+ virtual const char key() const
+ {
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("key"))
+ return f();
+ else
+ throw PythonMethodNotImplemented("UnacceptedMask", "key");
+ }
+
+ virtual const std::string description() const
+ {
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("description"))
+ return f();
+ else
+ throw PythonMethodNotImplemented("UnacceptedMask", "description");
}
};
-void register_mask_to_python()
+struct RepositoryMaskWrapper :
+ RepositoryMask,
+ bp::wrapper<RepositoryMask>
{
- bp::to_python_converter<Mask, mask_to_python>();
-}
+ virtual const tr1::shared_ptr<const MetadataKey> mask_key() const
+ {
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("mask_key"))
+ return f();
+ else
+ throw PythonMethodNotImplemented("RepositoryMask", "mask_key");
+ }
+
+ virtual const char key() const
+ {
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("key"))
+ return f();
+ else
+ throw PythonMethodNotImplemented("RepositoryMask", "key");
+ }
-struct UnacceptedMaskWrapper
+ virtual const std::string description() const
+ {
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("description"))
+ return f();
+ else
+ throw PythonMethodNotImplemented("RepositoryMask", "description");
+ }
+};
+struct UnsupportedMaskWrapper :
+ UnsupportedMask,
+ bp::wrapper<UnsupportedMask>
{
- static PyObject *
- unaccepted_key(const UnacceptedMask & self)
+ virtual const std::string explanation() const
+ {
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("explanation"))
+ return f();
+ else
+ throw PythonMethodNotImplemented("UnsupportedMask", "explanation");
+ }
+
+ virtual const char key() const
+ {
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("key"))
+ return f();
+ else
+ throw PythonMethodNotImplemented("UnsupportedMask", "key");
+ }
+
+ virtual const std::string description() const
{
- MetadataKeyToPython v;
- self.unaccepted_key()->accept(v);
- return bp::incref(v.value.ptr());
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("description"))
+ return f();
+ else
+ throw PythonMethodNotImplemented("UnsupportedMask", "description");
}
};
-struct RepositoryMaskWrapper
+struct AssociationMaskWrapper :
+ AssociationMask,
+ bp::wrapper<AssociationMask>
{
- static PyObject *
- mask_key(const RepositoryMask & self)
+ virtual const tr1::shared_ptr<const PackageID> associated_package() const
+ {
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("associated_package"))
+ return f();
+ else
+ throw PythonMethodNotImplemented("AssociationMask", "associated_package");
+ }
+
+ virtual const char key() const
+ {
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("key"))
+ return f();
+ else
+ throw PythonMethodNotImplemented("AssociationMask", "key");
+ }
+
+ virtual const std::string description() const
{
- MetadataKeyToPython v;
- self.mask_key()->accept(v);
- return bp::incref(v.value.ptr());
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("description"))
+ return f();
+ else
+ throw PythonMethodNotImplemented("AssociationMask", "description");
}
};
@@ -104,17 +278,14 @@ void expose_mask()
/**
* RepositoryMaskInfo
*/
- class_iterable<Sequence<std::string> >
- (
- "StringIterable",
- "Iterable of string"
- );
- register_shared_ptrs_to_python<RepositoryMaskInfo>();
- bp::class_<RepositoryMaskInfo>
+ register_shared_ptrs_to_python<RepositoryMaskInfo>(rsp_const);
+ bp::class_<RepositoryMaskInfo, tr1::shared_ptr<RepositoryMaskInfo> >
(
"RepositoryMaskInfo",
"Information about a RepositoryMask.",
- bp::no_init
+ bp::init<const FSEntry &, const tr1::shared_ptr<const Sequence<std::string> > &>(
+ "__init__(path_str, list of string)"
+ )
)
.add_property("mask_file", bp::make_getter(&RepositoryMaskInfo::mask_file,
bp::return_value_policy<bp::return_by_value>()),
@@ -132,20 +303,20 @@ void expose_mask()
/**
* Mask
*/
- register_mask_to_python();
- bp::class_<Mask, boost::noncopyable>
+ MaskSptrToPython();
+ bp::class_<MaskWrapper, boost::noncopyable>
(
"Mask",
"NEED_DOC",
bp::no_init
)
- .add_property("key", &Mask::key,
- "[ro] str\n"
+ .def("key", bp::pure_virtual(&Mask::key),
+ "key() -> string\n"
"NEED_DOC"
)
- .add_property("description", &Mask::description,
- "[ro] str\n"
+ .def("description", bp::pure_virtual(&Mask::description),
+ "description() -> string\n"
"NEED_DOC"
)
;
@@ -153,53 +324,105 @@ void expose_mask()
/**
* UserMask
*/
- bp::class_<UserMask, bp::bases<Mask>, boost::noncopyable>
+ bp::register_ptr_to_python<tr1::shared_ptr<const UserMask> >();
+ bp::implicitly_convertible<tr1::shared_ptr<const UserMaskWrapper>, tr1::shared_ptr<const Mask> >();
+ bp::class_<UserMaskWrapper, tr1::shared_ptr<const UserMaskWrapper>,
+ bp::bases<Mask>, boost::noncopyable>
(
"UserMask",
"NEED_DOC",
- bp::no_init
- );
+ bp::init<>()
+ )
+ .def("key", bp::pure_virtual(&Mask::key),
+ "[ro] str\n"
+ "NEED_DOC"
+ )
+
+ .def("description", bp::pure_virtual(&Mask::description),
+ "[ro] str\n"
+ "NEED_DOC"
+ )
+ ;
/**
* UnacceptedMask
*/
- bp::class_<UnacceptedMask, bp::bases<Mask>, boost::noncopyable>
+ bp::register_ptr_to_python<tr1::shared_ptr<const UnacceptedMask> >();
+ bp::implicitly_convertible<tr1::shared_ptr<const UnacceptedMaskWrapper>, tr1::shared_ptr<const Mask> >();
+ bp::class_<UnacceptedMaskWrapper, tr1::shared_ptr<const UnacceptedMaskWrapper>,
+ bp::bases<Mask>, boost::noncopyable>
(
"UnacceptedMask",
"NEED_DOC",
- bp::no_init
+ bp::init<>()
)
- .add_property("unaccepted_key", &UnacceptedMaskWrapper::unaccepted_key,
+ .def("unaccepted_key", bp::pure_virtual(&UnacceptedMask::unaccepted_key),
"[ro] MetadataKey\n"
"NEED_DOC"
)
+
+ .def("key", bp::pure_virtual(&Mask::key),
+ "[ro] str\n"
+ "NEED_DOC"
+ )
+
+ .def("description", bp::pure_virtual(&Mask::description),
+ "[ro] str\n"
+ "NEED_DOC"
+ )
;
/**
* RepositoryMask
*/
- bp::class_<RepositoryMask, bp::bases<Mask>, boost::noncopyable>
+ bp::register_ptr_to_python<tr1::shared_ptr<const RepositoryMask> >();
+ bp::implicitly_convertible<tr1::shared_ptr<const RepositoryMaskWrapper>, tr1::shared_ptr<const Mask> >();
+ bp::class_<RepositoryMaskWrapper, tr1::shared_ptr<const RepositoryMaskWrapper>,
+ bp::bases<Mask>, boost::noncopyable>
(
"RepositoryMask",
"NEED_DOC",
- bp::no_init
+ bp::init<>()
)
- .add_property("mask_key", &RepositoryMaskWrapper::mask_key,
+ .def("mask_key", bp::pure_virtual(&RepositoryMask::mask_key),
"[ro] MetadataKey\n"
"NEED_DOC"
)
+
+ .def("key", bp::pure_virtual(&Mask::key),
+ "[ro] str\n"
+ "NEED_DOC"
+ )
+
+ .def("description", bp::pure_virtual(&Mask::description),
+ "[ro] str\n"
+ "NEED_DOC"
+ )
;
/**
* UnsupportedMask
*/
- bp::class_<UnsupportedMask, bp::bases<Mask>, boost::noncopyable>
+ bp::register_ptr_to_python<tr1::shared_ptr<const UnsupportedMask> >();
+ bp::implicitly_convertible<tr1::shared_ptr<const UnsupportedMaskWrapper>, tr1::shared_ptr<const Mask> >();
+ bp::class_<UnsupportedMaskWrapper, tr1::shared_ptr<const UnsupportedMaskWrapper>,
+ bp::bases<Mask>, boost::noncopyable>
(
"UnsupportedMask",
"NEED_DOC",
- bp::no_init
+ bp::init<>()
)
- .add_property("explanation", &UnsupportedMask::explanation,
+ .def("explanation", bp::pure_virtual(&UnsupportedMask::explanation),
+ "[ro] str\n"
+ "NEED_DOC"
+ )
+
+ .def("key", bp::pure_virtual(&Mask::key),
+ "[ro] str\n"
+ "NEED_DOC"
+ )
+
+ .def("description", bp::pure_virtual(&Mask::description),
"[ro] str\n"
"NEED_DOC"
)
@@ -208,25 +431,26 @@ void expose_mask()
/**
* AssociationMask
*/
- bp::class_<AssociationMask, bp::bases<Mask>, boost::noncopyable>
+ bp::register_ptr_to_python<tr1::shared_ptr<const AssociationMask> >();
+ bp::implicitly_convertible<tr1::shared_ptr<const AssociationMaskWrapper>, tr1::shared_ptr<const Mask> >();
+ bp::class_<AssociationMaskWrapper, tr1::shared_ptr<const AssociationMaskWrapper>,
+ bp::bases<Mask>, boost::noncopyable>
(
"AssociationMask",
"NEED_DOC",
- bp::no_init
+ bp::init<>()
)
- .add_property("associated_package", &AssociationMask::associated_package,
+ .def("associated_package", bp::pure_virtual(&AssociationMask::associated_package),
"[ro] PackageID\n"
"NEED_DOC"
)
- //Work around epydoc bug
- .add_property("key", &Mask::key,
+ .def("key", bp::pure_virtual(&Mask::key),
"[ro] str\n"
"NEED_DOC"
)
- //Work around epydoc bug
- .add_property("description", &Mask::description,
+ .def("description", bp::pure_virtual(&Mask::description),
"[ro] str\n"
"NEED_DOC"
)
diff --git a/python/mask_TEST.py b/python/mask_TEST.py
index 329216b..e1e3856 100755
--- a/python/mask_TEST.py
+++ b/python/mask_TEST.py
@@ -23,6 +23,8 @@ import os
os.environ["PALUDIS_HOME"] = os.path.join(os.getcwd(), "mask_TEST_dir/home")
from paludis import *
+from subclassing_test import *
+
import unittest
Log.instance.log_level = LogLevel.WARNING
@@ -40,8 +42,8 @@ class TestCase_01_Masks(unittest.TestCase):
self.assert_(isinstance(m, Mask))
self.assert_(isinstance(m, UserMask))
- self.assertEquals(m.key, "U")
- self.assertEquals(m.description, "user")
+ self.assertEquals(m.key(), "U")
+ self.assertEquals(m.description(), "user")
def test_02_unaccepted_mask(self):
q = Query.Matches(PackageDepSpec("=masked/unaccepted-1.0", PackageDepSpecParseMode.PERMISSIVE))
@@ -51,9 +53,9 @@ class TestCase_01_Masks(unittest.TestCase):
self.assert_(isinstance(m, Mask))
self.assert_(isinstance(m, UnacceptedMask))
- self.assertEquals(m.key, "K")
- self.assertEquals(m.description, "keywords")
- self.assert_(isinstance(m.unaccepted_key, MetadataKeywordNameIterableKey))
+ self.assertEquals(m.key(), "K")
+ self.assertEquals(m.description(), "keywords")
+ self.assert_(isinstance(m.unaccepted_key(), MetadataKeywordNameIterableKey))
def test_03_repository_mask(self):
q = Query.Matches(PackageDepSpec("=masked/repo-1.0", PackageDepSpecParseMode.PERMISSIVE))
@@ -63,12 +65,12 @@ class TestCase_01_Masks(unittest.TestCase):
self.assert_(isinstance(m, Mask))
self.assert_(isinstance(m, RepositoryMask))
- self.assertEquals(m.key, "R")
- self.assertEquals(m.description, "repository")
+ self.assertEquals(m.key(), "R")
+ self.assertEquals(m.description(), "repository")
package_mask_path = os.path.join(os.getcwd(), "mask_TEST_dir/testrepo/profiles/package.mask")
- self.assertEquals(m.mask_key.value.mask_file, package_mask_path)
- self.assert_(isinstance(m.mask_key.value.comment, StringIterable))
+ self.assertEquals(m.mask_key().value().mask_file, package_mask_path)
+ self.assert_(isinstance(m.mask_key().value().comment, StringIterable))
def test_04_unsupported_mask(self):
q = Query.Matches(PackageDepSpec("=masked/unsupported-1.0", PackageDepSpecParseMode.PERMISSIVE))
@@ -78,9 +80,9 @@ class TestCase_01_Masks(unittest.TestCase):
self.assert_(isinstance(m, Mask))
self.assert_(isinstance(m, UnsupportedMask))
- self.assertEquals(m.key, "E")
- self.assertEquals(m.description, "eapi")
- self.assertEquals(m.explanation, "Unsupported EAPI 'unsupported'")
+ self.assertEquals(m.key(), "E")
+ self.assertEquals(m.description(), "eapi")
+ self.assertEquals(m.explanation(), "Unsupported EAPI 'unsupported'")
def test_05_association_mask(self):
q = Query.Matches(PackageDepSpec("=virtual/association-1.0", PackageDepSpecParseMode.PERMISSIVE))
@@ -90,9 +92,77 @@ class TestCase_01_Masks(unittest.TestCase):
self.assert_(isinstance(m, Mask))
self.assert_(isinstance(m, AssociationMask))
- self.assertEquals(m.key, "A")
- self.assertEquals(m.description, "by association")
- self.assertEquals(m.associated_package.name, "masked/repo")
+ self.assertEquals(m.key(), "A")
+ self.assertEquals(m.description(), "by association")
+ self.assertEquals(m.associated_package().name, "masked/repo")
+
+class TestCase_02_Masks_subclassing(unittest.TestCase):
+ def test_01_user_mask(self):
+ class TestUserMask(UserMask):
+ def key(self):
+ return "T"
+
+ def description(self):
+ return "test"
+
+ test_user_mask(TestUserMask())
+
+ def test_02_unaccepted_mask(self):
+ class TestUnacceptedMask(UnacceptedMask):
+ def key(self):
+ return "T"
+
+ def description(self):
+ return "test"
+
+ def unaccepted_key(self):
+ return MetadataStringKey("raw", "human", MetadataKeyType.NORMAL)
+
+ test_unaccepted_mask(TestUnacceptedMask())
+
+ def test_03_repository_mask(self):
+ class TestRepositoryMask(RepositoryMask):
+ def key(self):
+ return "T"
+
+ def description(self):
+ return "test"
+
+ def mask_key(self):
+ return MetadataStringKey("raw", "human", MetadataKeyType.NORMAL)
+
+ test_repository_mask(TestRepositoryMask())
+
+ def test_04_unsupported_mask(self):
+ class TestUnsupportedMask(UnsupportedMask):
+ def key(self):
+ return "T"
+
+ def description(self):
+ return "test"
+
+ def explanation(self):
+ return "test"
+
+ test_unsupported_mask(TestUnsupportedMask())
+
+ def test_05_association_mask(self):
+ class TestAssociationMask(AssociationMask):
+ def key(self):
+ return "T"
+
+ def description(self):
+ return "test"
+
+ def associated_package(self):
+ e = EnvironmentMaker.instance.make_from_spec("")
+ db = e.package_database
+ q = Query.Matches(PackageDepSpec("=masked/user-1.0", PackageDepSpecParseMode.PERMISSIVE))
+ pid = iter(db.query(q, QueryOrder.REQUIRE_EXACTLY_ONE)).next()
+ return pid
+
+ test_association_mask(TestAssociationMask())
+
if __name__ == "__main__":
unittest.main()
diff --git a/python/metadata_key.cc b/python/metadata_key.cc
index 341bd0b..bd8237e 100644
--- a/python/metadata_key.cc
+++ b/python/metadata_key.cc
@@ -17,159 +17,345 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "metadata_key.hh"
#include <python/paludis_python.hh>
+#include <python/exception.hh>
+#include <paludis/metadata_key.hh>
#include <paludis/name.hh>
#include <paludis/util/visitor-impl.hh>
-#include <datetime.h>
-
using namespace paludis;
using namespace paludis::python;
namespace bp = boost::python;
-struct MetadataTimeKeyWrapper
+class MetadataKeySptrToPythonVisitor :
+ public ConstVisitor<MetadataKeyVisitorTypes>
{
- static PyObject *
- value(const MetadataTimeKey & self)
+ private:
+ const tr1::shared_ptr<const MetadataKey> & _m_ptr;
+
+ public:
+ boost::python::object obj;
+
+ MetadataKeySptrToPythonVisitor(const tr1::shared_ptr<const MetadataKey> & m_ptr) :
+ _m_ptr(m_ptr)
+ {
+ }
+
+ void visit(const MetadataPackageIDKey & k)
+ {
+ obj = bp::object(tr1::static_pointer_cast<const MetadataPackageIDKey>(_m_ptr));
+ }
+
+ void visit(const MetadataStringKey & k)
+ {
+ obj = bp::object(tr1::static_pointer_cast<const MetadataStringKey>(_m_ptr));
+ }
+
+ void visit(const MetadataTimeKey & k)
+ {
+ obj = bp::object(tr1::static_pointer_cast<const MetadataTimeKey>(_m_ptr));
+ }
+
+ void visit(const MetadataContentsKey & k)
+ {
+ obj = bp::object(tr1::static_pointer_cast<const MetadataContentsKey>(_m_ptr));
+ }
+
+ void visit(const MetadataRepositoryMaskInfoKey & k)
+ {
+ obj = bp::object(tr1::static_pointer_cast<const MetadataRepositoryMaskInfoKey>(_m_ptr));
+ }
+
+ void visit(const MetadataSetKey<KeywordNameSet> & k)
+ {
+ obj = bp::object(tr1::static_pointer_cast<const MetadataSetKey<KeywordNameSet> >(_m_ptr));
+ }
+
+ void visit(const MetadataSetKey<UseFlagNameSet> & k)
+ {
+ obj = bp::object(tr1::static_pointer_cast<const MetadataSetKey<UseFlagNameSet> >(_m_ptr));
+ }
+
+ void visit(const MetadataSetKey<IUseFlagSet> & k)
+ {
+ obj = bp::object(tr1::static_pointer_cast<const MetadataSetKey<IUseFlagSet> >(_m_ptr));
+ }
+
+ void visit(const MetadataSetKey<InheritedSet> & k)
+ {
+ obj = bp::object(tr1::static_pointer_cast<const MetadataSetKey<InheritedSet> >(_m_ptr));
+ }
+
+ void visit(const MetadataSpecTreeKey<LicenseSpecTree> & k)
+ {
+ obj = bp::object(tr1::static_pointer_cast<const MetadataSpecTreeKey<LicenseSpecTree> >(_m_ptr));
+ }
+
+ void visit(const MetadataSpecTreeKey<ProvideSpecTree> & k)
+ {
+ obj = bp::object(tr1::static_pointer_cast<const MetadataSpecTreeKey<ProvideSpecTree> >(_m_ptr));
+ }
+
+ void visit(const MetadataSpecTreeKey<DependencySpecTree> & k)
+ {
+ obj = bp::object(tr1::static_pointer_cast<const MetadataSpecTreeKey<DependencySpecTree> >(_m_ptr));
+ }
+
+ void visit(const MetadataSpecTreeKey<RestrictSpecTree> & k)
+ {
+ obj = bp::object(tr1::static_pointer_cast<const MetadataSpecTreeKey<RestrictSpecTree> >(_m_ptr));
+ }
+
+ void visit(const MetadataSpecTreeKey<URISpecTree> & k)
+ {
+ obj = bp::object(tr1::static_pointer_cast<const MetadataSpecTreeKey<URISpecTree> >(_m_ptr));
+ }
+
+ void visit(const MetadataSetKey<PackageIDSequence> & k)
+ {
+ obj = bp::object(tr1::static_pointer_cast<const MetadataSetKey<PackageIDSequence> >(_m_ptr));
+ }
+};
+
+struct MetadataKeySptrToPython
+{
+ MetadataKeySptrToPython()
{
- PyDateTime_IMPORT;
- return PyDateTime_FromTimestamp(bp::make_tuple(self.value()).ptr());
+ bp::to_python_converter<tr1::shared_ptr<const MetadataKey>, MetadataKeySptrToPython>();
}
+ static PyObject *
+ convert(const tr1::shared_ptr<const MetadataKey> & m)
+ {
+ MetadataKeySptrToPythonVisitor v(m);
+ m->accept(v);
+ return bp::incref(v.obj.ptr());
+ }
};
-template <typename K_>
-struct class_set_key :
- bp::class_<K_, bp::bases<MetadataKey>, boost::noncopyable>
+struct MetadataPackageIDKeyWrapper :
+ MetadataPackageIDKey,
+ bp::wrapper<MetadataPackageIDKey>
{
- class_set_key(const std::string & set) :
- bp::class_<K_, bp::bases<MetadataKey>, boost::noncopyable>(("Metadata" + set + "Key").c_str(), bp::no_init)
+ MetadataPackageIDKeyWrapper(const std::string & r, const std::string & h, const MetadataKeyType t) :
+ MetadataPackageIDKey(r, h, t)
{
- add_property("value", &K_::value,
- ("[ro] " + set + "\n").c_str());
+ }
+
+ virtual const tr1::shared_ptr<const PackageID> value() const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("value"))
+ return f();
+ else
+ throw PythonMethodNotImplemented("MetadataPackageIDKey", "value");
}
};
-template <typename K_>
-struct class_spec_tree_key :
- bp::class_<K_, bp::bases<MetadataKey>, boost::noncopyable>
+struct MetadataStringKeyWrapper :
+ MetadataStringKey,
+ bp::wrapper<MetadataStringKey>
{
- class_spec_tree_key(const std::string & spec_tree) :
- bp::class_<K_, bp::bases<MetadataKey>, boost::noncopyable>(("Metadata" + spec_tree + "Key").c_str(), bp::no_init)
+ MetadataStringKeyWrapper(const std::string & r, const std::string & h, const MetadataKeyType t) :
+ MetadataStringKey(r, h, t)
{
- add_property("value", &K_::value,
- ("[ro] " + spec_tree + "\n").c_str());
+ }
+
+ virtual const std::string value() const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ Lock l(get_mutex());
+
+ if (bp::override f = get_override("value"))
+ return f();
+ else
+ throw PythonMethodNotImplemented("MetadataStringKey", "value");
}
};
-void
-MetadataKeyToPython::visit(const MetadataPackageIDKey & k)
+struct MetadataTimeKeyWrapper :
+ MetadataTimeKey,
+ bp::wrapper<MetadataTimeKey>
{
- value = bp::object(bp::ptr(&k));
-}
+ MetadataTimeKeyWrapper(const std::string & r, const std::string & h, const MetadataKeyType t) :
+ MetadataTimeKey(r, h, t)
+ {
+ }
-void
-MetadataKeyToPython::visit(const MetadataStringKey & k)
-{
- value = bp::object(bp::ptr(&k));
-}
+ virtual const time_t value() const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ Lock l(get_mutex());
-void
-MetadataKeyToPython::visit(const MetadataTimeKey & k)
-{
- value = bp::object(bp::ptr(&k));
-}
+ if (bp::override f = get_override("value"))
+ return f();
+ else
+ throw PythonMethodNotImplemented("MetadataTimeKey", "value");
+ }
+};
-void
-MetadataKeyToPython::visit(const MetadataContentsKey & k)
+struct MetadataContentsKeyWrapper :
+ MetadataContentsKey,
+ bp::wrapper<MetadataContentsKey>
{
- value = bp::object(bp::ptr(&k));
-}
+ MetadataContentsKeyWrapper(const std::string & r, const std::string & h, const MetadataKeyType t) :
+ MetadataContentsKey(r, h, t)
+ {
+ }
-void
-MetadataKeyToPython::visit(const MetadataRepositoryMaskInfoKey & k)
-{
- value = bp::object(bp::ptr(&k));
-}
+ virtual const tr1::shared_ptr<const Contents> value() const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ Lock l(get_mutex());
-void
-MetadataKeyToPython::visit(const MetadataSetKey<KeywordNameSet> & k)
-{
- value = bp::object(bp::ptr(&k));
-}
+ if (bp::override f = get_override("value"))
+ return f();
+ else
+ throw PythonMethodNotImplemented("MetadataContentsKey", "value");
+ }
+};
-void
-MetadataKeyToPython::visit(const MetadataSetKey<UseFlagNameSet> & k)
+struct MetadataRepositoryMaskInfoKeyWrapper :
+ MetadataRepositoryMaskInfoKey,
+ bp::wrapper<MetadataRepositoryMaskInfoKey>
{
- value = bp::object(bp::ptr(&k));
-}
+ MetadataRepositoryMaskInfoKeyWrapper(const std::string & r, const std::string & h, const MetadataKeyType t) :
+ MetadataRepositoryMaskInfoKey(r, h, t)
+ {
+ }
-void
-MetadataKeyToPython::visit(const MetadataSetKey<IUseFlagSet> & k)
-{
- value = bp::object(bp::ptr(&k));
-}
+ virtual const tr1::shared_ptr<const RepositoryMaskInfo> value() const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ Lock l(get_mutex());
-void
-MetadataKeyToPython::visit(const MetadataSetKey<InheritedSet> & k)
-{
- value = bp::object(bp::ptr(&k));
-}
+ if (bp::override f = get_override("value"))
+ return f();
+ else
+ throw PythonMethodNotImplemented("MetadataRepositoryMaskInfoKey", "value");
+ }
+};
-void
-MetadataKeyToPython::visit(const MetadataSpecTreeKey<LicenseSpecTree> & k)
+template <typename C_>
+struct MetadataSetKeyWrapper :
+ MetadataSetKey<C_>,
+ bp::wrapper<MetadataSetKey<C_> >
{
- value = bp::object(bp::ptr(&k));
-}
+ MetadataSetKeyWrapper(const std::string & r, const std::string & h, const MetadataKeyType t) :
+ MetadataSetKey<C_>(r, h, t)
+ {
+ }
-void
-MetadataKeyToPython::visit(const MetadataSpecTreeKey<ProvideSpecTree> & k)
-{
- value = bp::object(bp::ptr(&k));
-}
+ virtual const tr1::shared_ptr<const C_> value() const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ Lock l(get_mutex());
-void
-MetadataKeyToPython::visit(const MetadataSpecTreeKey<DependencySpecTree> & k)
-{
- value = bp::object(bp::ptr(&k));
-}
+ if (bp::override f = this->get_override("value"))
+ return f();
+ else
+ throw PythonMethodNotImplemented("MetadataSetKey", "value");
+ }
+};
-void
-MetadataKeyToPython::visit(const MetadataSpecTreeKey<RestrictSpecTree> & k)
+template <typename C_>
+struct MetadataSpecTreeKeyWrapper :
+ MetadataSpecTreeKey<C_>,
+ bp::wrapper<MetadataSpecTreeKey<C_> >
{
- value = bp::object(bp::ptr(&k));
-}
+ MetadataSpecTreeKeyWrapper(const std::string & r, const std::string & h, const MetadataKeyType t) :
+ MetadataSpecTreeKey<C_>(r, h, t)
+ {
+ }
-void
-MetadataKeyToPython::visit(const MetadataSpecTreeKey<URISpecTree> & k)
-{
- value = bp::object(bp::ptr(&k));
-}
+ virtual const tr1::shared_ptr<const typename C_::ConstItem> value() const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ Lock l(get_mutex());
-void
-MetadataKeyToPython::visit(const MetadataSetKey<PackageIDSequence> & k)
-{
- value = bp::object(bp::ptr(&k));
-}
+ if (bp::override f = this->get_override("value"))
+ return f();
+ else
+ throw PythonMethodNotImplemented("MetadataSpecTreeKey", "value");
+ }
+
+ virtual std::string pretty_print() const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ Lock l(get_mutex());
-struct metadata_key_to_python
+ if (bp::override f = this->get_override("pretty_print"))
+ return f();
+ else
+ throw PythonMethodNotImplemented("MetadataSpecTreeKey", "pretty_print");
+ }
+
+ virtual std::string pretty_print_flat() const
+ PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ Lock l(get_mutex());
+
+ if (bp::override f = this->get_override("pretty_print_flat"))
+ return f();
+ else
+ throw PythonMethodNotImplemented("MetadataSpecTreeKey", "pretty_print_flat");
+ }
+};
+
+template <typename C_>
+struct class_set_key :
+ bp::class_<MetadataSetKeyWrapper<C_>, tr1::shared_ptr<const MetadataSetKeyWrapper<C_> >,
+ bp::bases<MetadataKey>, boost::noncopyable>
{
- static PyObject *
- convert(const MetadataKey & k)
+ class_set_key(const std::string & set) :
+ bp::class_<MetadataSetKeyWrapper<C_>, tr1::shared_ptr<const MetadataSetKeyWrapper<C_> >,
+ bp::bases<MetadataKey>, boost::noncopyable>(
+ ("Metadata" + set + "Key").c_str(),
+ "NEED_DOC\n"
+ "This class can be subclassed in Python.",
+ bp::init<const std::string &, const std::string &, MetadataKeyType>(
+ "__init__(raw_name, human_name, MetadataKeyType)"
+ )
+ )
{
- MetadataKeyToPython v;
- k.accept(v);
- return bp::incref(v.value.ptr());
+ bp::register_ptr_to_python<tr1::shared_ptr<const MetadataSetKey<C_> > >();
+ bp::implicitly_convertible<tr1::shared_ptr<const MetadataSetKeyWrapper<C_> >,
+ tr1::shared_ptr<const MetadataKey> >();
+
+ def("value", bp::pure_virtual(&MetadataSetKey<C_>::value),
+ ("[ro] " + set + "\n").c_str());
}
};
-void register_metadata_key_to_python()
+template <typename C_>
+struct class_spec_tree_key :
+ bp::class_<MetadataSpecTreeKeyWrapper<C_>, tr1::shared_ptr<const MetadataSpecTreeKeyWrapper<C_> >,
+ bp::bases<MetadataKey>, boost::noncopyable>
{
- bp::to_python_converter<MetadataKey, metadata_key_to_python>();
-}
+ class_spec_tree_key(const std::string & spec_tree) :
+ bp::class_<MetadataSpecTreeKeyWrapper<C_>, tr1::shared_ptr<const MetadataSpecTreeKeyWrapper<C_> >,
+ bp::bases<MetadataKey>, boost::noncopyable>(
+ ("Metadata" + spec_tree + "Key").c_str(),
+ "NEED_DOC\n"
+ "This class can be subclassed in Python.",
+ bp::init<const std::string &, const std::string &, MetadataKeyType>(
+ "__init__(raw_name, human_name, MetadataKeyType)"
+ )
+ )
+ {
+ bp::register_ptr_to_python<tr1::shared_ptr<const MetadataSpecTreeKey<C_> > >();
+ bp::implicitly_convertible<tr1::shared_ptr<const MetadataSpecTreeKeyWrapper<C_> >,
+ tr1::shared_ptr<const MetadataKey> >();
+ def("value", bp::pure_virtual(&MetadataSpecTreeKey<C_>::value),
+ ("[ro] " + spec_tree + "\n").c_str());
+ def("pretty_print", bp::pure_virtual(&MetadataSpecTreeKey<C_>::pretty_print));
+ def("pretty_print_flat", bp::pure_virtual(&MetadataSpecTreeKey<C_>::pretty_print_flat));
+ }
+};
void expose_metadata_key()
{
@@ -182,111 +368,157 @@ void expose_metadata_key()
/**
* MetadataKey
*/
- register_shared_ptrs_to_python<MetadataKey>();
+ MetadataKeySptrToPython();
bp::class_<MetadataKey, boost::noncopyable>
(
"MetadataKey",
bp::no_init
)
- .add_property("raw_name", &MetadataKey::raw_name,
- "[ro] string\n"
+ .def("raw_name", &MetadataKey::raw_name,
+ "raw_name() -> string\n"
+ "NEED_DOC"
)
- .add_property("human_name", &MetadataKey::human_name,
- "[ro] string\n"
+ .def("human_name", &MetadataKey::human_name,
+ "human_name() -> string\n"
+ "NEED_DOC"
)
;
- register_metadata_key_to_python();
/**
* MetadataPackageIDKey
*/
- bp::class_<MetadataPackageIDKey, bp::bases<MetadataKey>, boost::noncopyable>
+ bp::register_ptr_to_python<tr1::shared_ptr<const MetadataPackageIDKey> >();
+ bp::implicitly_convertible<tr1::shared_ptr<const MetadataPackageIDKeyWrapper>,
+ tr1::shared_ptr<const MetadataKey> >();
+ bp::class_<MetadataPackageIDKeyWrapper, tr1::shared_ptr<const MetadataPackageIDKeyWrapper>,
+ bp::bases<MetadataKey>, boost::noncopyable>
(
"MetadataPackageIDKey",
- bp::no_init
+ "NEED_DOC\n"
+ "This class can be subclassed in Python.",
+ bp::init<const std::string &, const std::string &, MetadataKeyType>(
+ "__init__(raw_name, human_name, MetadataKeyType)"
+ )
)
- .add_property("value", &MetadataPackageIDKey::value,
- "[ro] PackageID\n"
+ .def("value", bp::pure_virtual(&MetadataPackageIDKey::value),
+ "value() -> PackageID\n"
+ "NEED_DOC"
)
;
/**
* MetadataStringKey
*/
- bp::class_<MetadataStringKey, bp::bases<MetadataKey>, boost::noncopyable>
+ bp::register_ptr_to_python<tr1::shared_ptr<const MetadataStringKey> >();
+ bp::implicitly_convertible<tr1::shared_ptr<const MetadataStringKeyWrapper>,
+ tr1::shared_ptr<const MetadataKey> >();
+ bp::class_<MetadataStringKeyWrapper, tr1::shared_ptr<const MetadataStringKeyWrapper>,
+ bp::bases<MetadataKey>, boost::noncopyable>
(
"MetadataStringKey",
- bp::no_init
+ "NEED_DOC\n"
+ "This class can be subclassed in Python.",
+ bp::init<const std::string &, const std::string &, MetadataKeyType>(
+ "__init__(raw_name, human_name, MetadataKeyType)"
+ )
)
- .add_property("value", &MetadataStringKey::value,
- "[ro] string\n"
+ .def("value", &MetadataStringKey::value,
+ "value() -> string\n"
+ "NEED_DOC"
)
;
/**
* MetadataTimeKey
*/
- bp::class_<MetadataTimeKey, bp::bases<MetadataKey>, boost::noncopyable>
+ bp::register_ptr_to_python<tr1::shared_ptr<const MetadataTimeKey> >();
+ bp::implicitly_convertible<tr1::shared_ptr<const MetadataTimeKeyWrapper>,
+ tr1::shared_ptr<const MetadataKey> >();
+ bp::class_<MetadataTimeKeyWrapper, tr1::shared_ptr<const MetadataTimeKeyWrapper>,
+ bp::bases<MetadataKey>, boost::noncopyable>
(
"MetadataTimeKey",
- bp::no_init
+ "NEED_DOC\n"
+ "This class can be subclassed in Python.",
+ bp::init<const std::string &, const std::string &, MetadataKeyType>(
+ "__init__(raw_name, human_name, MetadataKeyType)"
+ )
)
- .add_property("value", &MetadataTimeKeyWrapper::value,
- "[ro] datetime\n"
+ .def("value", bp::pure_virtual(&MetadataTimeKey::value),
+ "value() -> int\n"
)
;
/**
* MetadataContentsKey
*/
- bp::class_<MetadataContentsKey, bp::bases<MetadataKey>, boost::noncopyable>
+ bp::register_ptr_to_python<tr1::shared_ptr<const MetadataContentsKey> >();
+ bp::implicitly_convertible<tr1::shared_ptr<const MetadataContentsKeyWrapper>,
+ tr1::shared_ptr<const MetadataKey> >();
+ bp::class_<MetadataContentsKeyWrapper, tr1::shared_ptr<const MetadataContentsKeyWrapper>,
+ bp::bases<MetadataKey>, boost::noncopyable>
(
"MetadataContentsKey",
- bp::no_init
+ "NEED_DOC\n"
+ "This class can be subclassed in Python.",
+ bp::init<const std::string &, const std::string &, MetadataKeyType>(
+ "__init__(raw_name, human_name, MetadataKeyType)"
+ )
)
- .add_property("value", &MetadataContentsKey::value,
- "[ro] Contents\n"
+ .def("value", bp::pure_virtual(&MetadataContentsKey::value),
+ "value() -> Contents\n"
+ "NEED_DOC"
)
//Work around epydoc bug
- .add_property("raw_name", &MetadataContentsKey::raw_name,
- "[ro] string\n"
+ .def("raw_name", &MetadataKey::raw_name,
+ "raw_name() -> string\n"
+ "NEED_DOC"
)
//Work around epydoc bug
- .add_property("human_name", &MetadataContentsKey::human_name,
- "[ro] string\n"
+ .def("human_name", &MetadataKey::human_name,
+ "human_name() -> string\n"
+ "NEED_DOC"
)
;
/**
* MetadataRepositoryMaskInfoKey
*/
- bp::class_<MetadataRepositoryMaskInfoKey, bp::bases<MetadataKey>, boost::noncopyable>
+ bp::register_ptr_to_python<tr1::shared_ptr<const MetadataRepositoryMaskInfoKey> >();
+ bp::implicitly_convertible<tr1::shared_ptr<const MetadataRepositoryMaskInfoKeyWrapper>,
+ tr1::shared_ptr<const MetadataKey> >();
+ bp::class_<MetadataRepositoryMaskInfoKeyWrapper, tr1::shared_ptr<const MetadataRepositoryMaskInfoKeyWrapper>,
+ bp::bases<MetadataKey>, boost::noncopyable>
(
"MetadataRepositoryMaskInfoKey",
- bp::no_init
+ "NEED_DOC\n"
+ "This class can be subclassed in Python.",
+ bp::init<const std::string &, const std::string &, MetadataKeyType>(
+ "__init__(raw_name, human_name, MetadataKeyType)"
+ )
)
- .add_property("value", &MetadataRepositoryMaskInfoKey::value,
- "[ro] RepositoryMaskInfo\n"
+ .def("value", bp::pure_virtual(&MetadataRepositoryMaskInfoKey::value),
+ "value() -> RepositoryMaskInfo\n"
)
;
/**
* MetadataSetKeys
*/
- class_set_key<MetadataSetKey<KeywordNameSet> >("KeywordNameIterable");
- class_set_key<MetadataSetKey<UseFlagNameSet> >("UseFlagNameIterable");
- class_set_key<MetadataSetKey<IUseFlagSet> >("IUseFlagIterable");
- class_set_key<MetadataSetKey<InheritedSet> >("InheritedIterable");
+ class_set_key<KeywordNameSet>("KeywordNameIterable");
+ class_set_key<UseFlagNameSet>("UseFlagNameIterable");
+ class_set_key<IUseFlagSet>("IUseFlagIterable");
+ class_set_key<InheritedSet>("InheritedIterable");
/**
* MetadataSpecTreeKeys
*/
- class_spec_tree_key<MetadataSpecTreeKey<LicenseSpecTree> >("LicenseSpecTree");
- class_spec_tree_key<MetadataSpecTreeKey<ProvideSpecTree> >("ProvideSpecTree");
- class_spec_tree_key<MetadataSpecTreeKey<DependencySpecTree> >("DependencySpecTree");
- class_spec_tree_key<MetadataSpecTreeKey<RestrictSpecTree> >("RestrictSpecTree");
- class_spec_tree_key<MetadataSpecTreeKey<URISpecTree> >("URISpecTree");
+ class_spec_tree_key<LicenseSpecTree>("LicenseSpecTree");
+ class_spec_tree_key<ProvideSpecTree>("ProvideSpecTree");
+ class_spec_tree_key<DependencySpecTree>("DependencySpecTree");
+ class_spec_tree_key<RestrictSpecTree>("RestrictSpecTree");
+ class_spec_tree_key<URISpecTree>("URISpecTree");
}
diff --git a/python/metadata_key.hh b/python/metadata_key.hh
deleted file mode 100644
index 07e330f..0000000
--- a/python/metadata_key.hh
+++ /dev/null
@@ -1,55 +0,0 @@
-/* vim: set sw=4 sts=4 et foldmethod=syntax : */
-
-/*
- * Copyright (c) 2007 Piotr Jaroszyński <peper@gentoo.org>
- *
- * This file is part of the Paludis package manager. Paludis is free software;
- * you can redistribute it and/or modify it under the terms of the GNU General
- * Public License version 2, as published by the Free Software Foundation.
- *
- * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef PYTHON_GUARD_PYTHON_METADATA_KEY_HH
-#define PYTHON_GUARD_PYTHON_METADATA_KEY_HH 1
-
-#include <python/paludis_python.hh>
-
-#include <paludis/metadata_key.hh>
-
-namespace paludis
-{
- namespace python
- {
- struct PALUDIS_VISIBLE MetadataKeyToPython :
- ConstVisitor<MetadataKeyVisitorTypes>
- {
- boost::python::object value;
-
- void visit(const MetadataPackageIDKey & k);
- void visit(const MetadataStringKey & k);
- void visit(const MetadataTimeKey & k);
- void visit(const MetadataContentsKey & k);
- void visit(const MetadataRepositoryMaskInfoKey & k);
- void visit(const MetadataSetKey<KeywordNameSet> & k);
- void visit(const MetadataSetKey<UseFlagNameSet> & k);
- void visit(const MetadataSetKey<IUseFlagSet> & k);
- void visit(const MetadataSetKey<InheritedSet> & k);
- void visit(const MetadataSpecTreeKey<LicenseSpecTree> & k);
- void visit(const MetadataSpecTreeKey<ProvideSpecTree> & k);
- void visit(const MetadataSpecTreeKey<DependencySpecTree> & k);
- void visit(const MetadataSpecTreeKey<RestrictSpecTree> & k);
- void visit(const MetadataSpecTreeKey<URISpecTree> & k);
- void visit(const MetadataSetKey<PackageIDSequence> & k);
- };
- }
-}
-
-#endif
diff --git a/python/metadata_key_TEST.py b/python/metadata_key_TEST.py
index b9f0ebf..a760a44 100755
--- a/python/metadata_key_TEST.py
+++ b/python/metadata_key_TEST.py
@@ -24,49 +24,226 @@ repo_path = os.path.join(os.getcwd(), "metadata_key_TEST_dir/testrepo")
irepo_path = os.path.join(os.getcwd(), "metadata_key_TEST_dir/installed")
from paludis import *
+from subclassing_test import *
+
import unittest
Log.instance.log_level = LogLevel.WARNING
class TestCase_01_MetadataKeys(unittest.TestCase):
def setUp(self):
- global e, ie, pid, ipid
- e = NoConfigEnvironment(repo_path, "/var/empty")
- ie = NoConfigEnvironment(irepo_path)
- pid = iter(e.package_database.fetch_repository("testrepo").package_ids("foo/bar")).next()
- ipid = iter(ie.package_database.fetch_repository("installed").package_ids("cat-one/pkg-one")).next()
+ self.e = NoConfigEnvironment(repo_path, "/var/empty")
+ self.ie = NoConfigEnvironment(irepo_path)
+ self.pid = iter(self.e.package_database.fetch_repository("testrepo").package_ids("foo/bar")).next()
+ self.ipid = iter(self.ie.package_database.fetch_repository("installed").package_ids("cat-one/pkg-one")).next()
def test_01_contents(self):
- self.assertEquals(pid.find_metadata("CONTENTS"), None)
- self.assert_(isinstance(ipid.find_metadata("CONTENTS"), MetadataContentsKey))
+ self.assertEquals(self.pid.find_metadata("CONTENTS"), None)
+ self.assert_(isinstance(self.ipid.find_metadata("CONTENTS"), MetadataContentsKey))
def test_02_installed_time(self):
- self.assertEquals(pid.find_metadata("INSTALLED_TIME"), None)
- self.assert_(isinstance(ipid.find_metadata("INSTALLED_TIME"), MetadataTimeKey))
+ self.assertEquals(self.pid.find_metadata("INSTALLED_TIME"), None)
+ self.assert_(isinstance(self.ipid.find_metadata("INSTALLED_TIME"), MetadataTimeKey))
def test_03_repository(self):
- self.assertEquals(pid.find_metadata("REPOSITORY"), None)
- self.assert_(isinstance(ipid.find_metadata("REPOSITORY"), MetadataStringKey))
+ self.assertEquals(self.pid.find_metadata("REPOSITORY"), None)
+ self.assert_(isinstance(self.ipid.find_metadata("REPOSITORY"), MetadataStringKey))
def test_04_keywords(self):
- self.assert_(isinstance(pid.find_metadata("KEYWORDS"), MetadataKeywordNameIterableKey))
- self.assertEquals(ipid.find_metadata("KEYWORDS"), None)
+ self.assert_(isinstance(self.pid.find_metadata("KEYWORDS"), MetadataKeywordNameIterableKey))
+ self.assertEquals(self.ipid.find_metadata("KEYWORDS"), None)
def test_05_use(self):
- self.assertEquals(pid.find_metadata("USE"), None)
- self.assert_(isinstance(ipid.find_metadata("USE"), MetadataUseFlagNameIterableKey))
+ self.assertEquals(self.pid.find_metadata("USE"), None)
+ self.assert_(isinstance(self.ipid.find_metadata("USE"), MetadataUseFlagNameIterableKey))
def test_06_iuse(self):
- self.assert_(isinstance(pid.find_metadata("IUSE"), MetadataIUseFlagIterableKey))
- self.assert_(isinstance(ipid.find_metadata("IUSE"), MetadataIUseFlagIterableKey))
+ self.assert_(isinstance(self.pid.find_metadata("IUSE"), MetadataIUseFlagIterableKey))
+ self.assert_(isinstance(self.ipid.find_metadata("IUSE"), MetadataIUseFlagIterableKey))
def test_07_inherited(self):
- self.assert_(isinstance(pid.find_metadata("INHERITED"), MetadataInheritedIterableKey))
- self.assert_(isinstance(ipid.find_metadata("INHERITED"), MetadataInheritedIterableKey))
+ self.assert_(isinstance(self.pid.find_metadata("INHERITED"), MetadataInheritedIterableKey))
+ self.assert_(isinstance(self.ipid.find_metadata("INHERITED"), MetadataInheritedIterableKey))
def test_08_depend(self):
- self.assert_(isinstance(pid.find_metadata("DEPEND"), MetadataDependencySpecTreeKey))
- self.assertEquals(ipid.find_metadata("DEPEND"), None)
+ self.assert_(isinstance(self.pid.find_metadata("DEPEND"), MetadataDependencySpecTreeKey))
+ self.assertEquals(self.ipid.find_metadata("DEPEND"), None)
+
+class TestCase_02_MetadataKeys_suclassing(unittest.TestCase):
+ def test_01_package_id(self):
+ class TestKey(MetadataPackageIDKey):
+ def __init__(self):
+ MetadataPackageIDKey.__init__(self, "raw", "human", MetadataKeyType.NORMAL)
+
+ def value(self):
+ e = NoConfigEnvironment(repo_path, "/var/empty")
+ pid = iter(e.package_database.fetch_repository("testrepo").package_ids("foo/bar")).next()
+ return pid
+
+ test_metadata_package_id_key(TestKey())
+
+ def test_02_string(self):
+ class TestKey(MetadataStringKey):
+ def __init__(self):
+ MetadataStringKey.__init__(self, "raw", "human", MetadataKeyType.NORMAL)
+
+ def value(self):
+ return "str"
+
+ test_metadata_string_key(TestKey())
+
+ def test_03_time(self):
+ class TestKey(MetadataTimeKey):
+ def __init__(self):
+ MetadataTimeKey.__init__(self, "raw", "human", MetadataKeyType.NORMAL)
+
+ def value(self):
+ return 123
+
+ test_metadata_time_key(TestKey())
+
+
+ def test_04_contents(self):
+ class TestKey(MetadataContentsKey):
+ def __init__(self):
+ MetadataContentsKey.__init__(self, "raw", "human", MetadataKeyType.NORMAL)
+
+ def value(self):
+ return Contents()
+
+ test_metadata_contents_key(TestKey())
+
+ def test_05_repository_mask_info(self):
+ class TestKey(MetadataRepositoryMaskInfoKey):
+ def __init__(self):
+ MetadataRepositoryMaskInfoKey.__init__(self, "raw", "human", MetadataKeyType.NORMAL)
+
+ def value(self):
+ return RepositoryMaskInfo("/foo", ["comment"])
+
+ test_metadata_repository_mask_info_key(TestKey())
+
+ def test_06_keyword_name_iterable(self):
+ class TestKey(MetadataKeywordNameIterableKey):
+ def __init__(self):
+ MetadataKeywordNameIterableKey.__init__(self, "raw", "human", MetadataKeyType.NORMAL)
+
+ def value(self):
+ return ["keyword"]
+
+ test_metadata_keyword_name_set_key(TestKey())
+
+ def test_07_use_flag_name_iterable(self):
+ class TestKey(MetadataUseFlagNameIterableKey):
+ def __init__(self):
+ MetadataUseFlagNameIterableKey.__init__(self, "raw", "human", MetadataKeyType.NORMAL)
+
+ def value(self):
+ return ["use"]
+
+ test_metadata_use_flag_name_set_key(TestKey())
+
+ def test_08_iuse_flag_iterable(self):
+ class TestKey(MetadataIUseFlagIterableKey):
+ def __init__(self):
+ MetadataIUseFlagIterableKey.__init__(self, "raw", "human", MetadataKeyType.NORMAL)
+
+ def value(self):
+ return [IUseFlag("iuse", IUseFlagParseMode.PERMISSIVE)]
+
+ test_metadata_iuse_flag_set_key(TestKey())
+
+ def test_09_inherited_iterable(self):
+ class TestKey(MetadataInheritedIterableKey):
+ def __init__(self):
+ MetadataInheritedIterableKey.__init__(self, "raw", "human", MetadataKeyType.NORMAL)
+
+ def value(self):
+ return ["keyword"]
+
+ test_metadata_inherited_set_key(TestKey())
+
+ def test_10_license_spec_tree(self):
+ class TestKey(MetadataLicenseSpecTreeKey):
+ def __init__(self):
+ MetadataLicenseSpecTreeKey.__init__(self, "raw", "human", MetadataKeyType.NORMAL)
+
+ def value(self):
+ return AllDepSpec()
+
+ def pretty_print(self):
+ return "str"
+
+ def pretty_print_flat(self):
+ return "str"
+
+ test_metadata_license_spec_tree_key(TestKey())
+
+ def test_11_provide_spec_tree(self):
+ class TestKey(MetadataProvideSpecTreeKey):
+ def __init__(self):
+ MetadataProvideSpecTreeKey.__init__(self, "raw", "human", MetadataKeyType.NORMAL)
+
+ def value(self):
+ return AllDepSpec()
+
+ def pretty_print(self):
+ return "str"
+
+ def pretty_print_flat(self):
+ return "str"
+
+ test_metadata_provide_spec_tree_key(TestKey())
+
+ def test_12_dependency_spec_tree(self):
+ class TestKey(MetadataDependencySpecTreeKey):
+ def __init__(self):
+ MetadataDependencySpecTreeKey.__init__(self, "raw", "human", MetadataKeyType.NORMAL)
+
+ def value(self):
+ return AllDepSpec()
+
+ def pretty_print(self):
+ return "str"
+
+ def pretty_print_flat(self):
+ return "str"
+
+ test_metadata_dependency_spec_tree_key(TestKey())
+
+
+ def test_13_restrict_spec_tree(self):
+ class TestKey(MetadataRestrictSpecTreeKey):
+ def __init__(self):
+ MetadataRestrictSpecTreeKey.__init__(self, "raw", "human", MetadataKeyType.NORMAL)
+
+ def value(self):
+ return AllDepSpec()
+
+ def pretty_print(self):
+ return "str"
+
+ def pretty_print_flat(self):
+ return "str"
+
+ test_metadata_restrict_spec_tree_key(TestKey())
+
+ def test_14_uri_spec_tree(self):
+ class TestKey(MetadataURISpecTreeKey):
+ def __init__(self):
+ MetadataURISpecTreeKey.__init__(self, "raw", "human", MetadataKeyType.NORMAL)
+
+ def value(self):
+ return AllDepSpec()
+
+ def pretty_print(self):
+ return "str"
+
+ def pretty_print_flat(self):
+ return "str"
+
+ test_metadata_uri_spec_tree_key(TestKey())
+
if __name__ == "__main__":
unittest.main()
diff --git a/python/name.cc b/python/name.cc
index e843233..386fe77 100644
--- a/python/name.cc
+++ b/python/name.cc
@@ -128,7 +128,8 @@ void expose_name()
class_iterable<UseFlagNameSet>
(
"UseFlagNameIterable",
- "Iterable of UseFlagName"
+ "Iterable of UseFlagName",
+ true
);
/**
@@ -176,7 +177,8 @@ void expose_name()
class_iterable<KeywordNameSet>
(
"KeywordNameIterable",
- "Iterable of KeywordName"
+ "Iterable of KeywordName",
+ true
);
/**
@@ -194,7 +196,8 @@ void expose_name()
class_iterable<SetNameSet>
(
"SetNameIterable",
- "Iterable of SetName"
+ "Iterable of SetName",
+ true
);
/**
@@ -203,7 +206,8 @@ void expose_name()
class_iterable<InheritedSet>
(
"InheritedIterable",
- "Iterable of string"
+ "Iterable of string",
+ true
);
/**
@@ -269,6 +273,7 @@ void expose_name()
class_iterable<IUseFlagSet>
(
"IUseFlagIterable",
- "Iterable of IUseFlag"
+ "Iterable of IUseFlag",
+ true
);
}
diff --git a/python/package_id.cc b/python/package_id.cc
index 7f1a58a..12a71a7 100644
--- a/python/package_id.cc
+++ b/python/package_id.cc
@@ -40,22 +40,10 @@ struct PackageIDWrapper
{
PackageID::MetadataIterator i(self.find_metadata(key));
if (i != self.end_metadata())
- return bp::incref(bp::object(**i).ptr());
+ return bp::incref(bp::object(*i).ptr());
else
return Py_None;
}
-
- static IndirectIterator<PackageID::MetadataIterator>
- begin_metadata(const PackageID & self)
- {
- return indirect_iterator(self.begin_metadata());
- }
-
- static IndirectIterator<PackageID::MetadataIterator>
- end_metadata(const PackageID & self)
- {
- return indirect_iterator(self.end_metadata());
- }
};
void expose_package_id()
@@ -105,7 +93,7 @@ void expose_package_id()
"NEED_DOC"
)
- .add_property("metadata", bp::range(&PackageIDWrapper::begin_metadata, &PackageIDWrapper::end_metadata),
+ .add_property("metadata", bp::range(&PackageID::begin_metadata, &PackageID::end_metadata),
"[ro] Iterable of MetadataKey\n"
"NEED_DOC"
)
diff --git a/python/query.cc b/python/query.cc
index 55c4c69..c3bafba 100644
--- a/python/query.cc
+++ b/python/query.cc
@@ -37,6 +37,10 @@ class PythonQuery :
public:
PythonQuery();
+ virtual ~PythonQuery()
+ {
+ }
+
virtual tr1::shared_ptr<RepositoryNameSequence> repositories(const Environment &) const
{
return tr1::shared_ptr<RepositoryNameSequence>();
@@ -223,6 +227,9 @@ void expose_query()
);
q.def("__and__", operator&);
+ /**
+ * QueryBase
+ */
bp::class_<PythonQueryWrapper, bp::bases<Query>, boost::noncopyable>
(
"QueryBase",
diff --git a/python/query_TEST.py b/python/query_TEST.py
index 090d592..f188c28 100755
--- a/python/query_TEST.py
+++ b/python/query_TEST.py
@@ -78,7 +78,8 @@ class TestCase_02_QueryBase(unittest.TestCase):
e = NoConfigEnvironment(repo_path, "/var/empty")
db = e.package_database
q = self.TestQuery()
- pid = iter(db.query(q, QueryOrder.REQUIRE_EXACTLY_ONE)).next()
+ q1 = q & Query.Repository("testrepo")
+ pid = iter(db.query(q1, QueryOrder.REQUIRE_EXACTLY_ONE)).next()
self.assertEquals(pid.name, "cat/package")
diff --git a/python/repository.cc b/python/repository.cc
index da27d06..e9d48fe 100644
--- a/python/repository.cc
+++ b/python/repository.cc
@@ -193,7 +193,8 @@ void expose_repository()
class_iterable<DestinationsSet>
(
"DestinationsIterable",
- "Iterable of Repository."
+ "Iterable of Repository.",
+ true
);
/**
@@ -380,25 +381,25 @@ void expose_repository()
bp::no_init
)
.def("query_use", &RepositoryUseInterface::query_use,
- ("ufn", bp::arg("pde")),
+ ("ufn", bp::arg("pid")),
"query_use(UseFlagName, PackageID) -> UseFlagState\n"
"Query the state of the specified use flag."
)
.def("query_use_mask", &RepositoryUseInterface::query_use_mask,
- ("ufn", bp::arg("pde")),
+ ("ufn", bp::arg("pid")),
"query_use_mask(UseFlagName, PackageID) -> bool\n"
"Query whether the specified use flag is masked."
)
.def("query_use_force", &RepositoryUseInterface::query_use_force,
- ("ufn", bp::arg("pde")),
+ ("ufn", bp::arg("pid")),
"query_use_force(UseFlagName, PackageID) -> bool\n"
"Query whether the specified use flag is forceed."
)
.def("describe_use_flag", &RepositoryUseInterface::describe_use_flag,
- ("ufn", bp::arg("pde")),
+ ("ufn", bp::arg("pid")),
"describe_use_flag(UseFlagName, PackageID) -> string\n"
"Describe a use flag."
)
diff --git a/python/subclassing_test.cc b/python/subclassing_test.cc
new file mode 100644
index 0000000..a332bd8
--- /dev/null
+++ b/python/subclassing_test.cc
@@ -0,0 +1,220 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Piotr Jaroszyński <peper@gentoo.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <python/paludis_python.hh>
+
+#include <paludis/util/tr1_memory.hh>
+#include <paludis/util/set.hh>
+#include <paludis/environment.hh>
+#include <paludis/package_database.hh>
+#include <paludis/repositories/fake/fake_repository.hh>
+#include <paludis/repositories/fake/fake_package_id.hh>
+#include <paludis/mask.hh>
+#include <paludis/hook.hh>
+
+using namespace paludis;
+namespace bp = boost::python;
+
+namespace environment
+{
+ void test_env(Environment & e)
+ {
+ tr1::shared_ptr<FakeRepository> repo(new FakeRepository(&e, RepositoryName("fakerepo")));
+ tr1::shared_ptr<PackageID> pid(repo->add_version("cat", "pkg", "1.0"));
+ e.package_database()->add_repository(0, repo);
+
+ UseFlagName u("use");
+ e.query_use(u, *pid);
+
+ e.known_use_expand_names(u, *pid);
+
+ e.accept_license("l", *pid);
+
+ tr1::shared_ptr<KeywordNameSet> kns(new KeywordNameSet);
+ kns->insert(KeywordName("keyword"));
+ e.accept_keywords(kns, *pid);
+
+ e.mask_for_breakage(*pid);
+
+ e.mask_for_user(*pid);
+
+ e.unmasked_by_user(*pid);
+
+ e.package_database();
+
+ e.bashrc_files();
+
+ e.syncers_dirs();
+
+ e.fetchers_dirs();
+
+ e.hook_dirs();
+
+ e.paludis_command();
+
+ e.set_paludis_command("paludis");
+
+ e.root();
+
+ e.reduced_uid();
+
+ e.reduced_gid();
+
+ e.mirrors("mirror");
+
+ e.set_names();
+
+ e.set(SetName("set"));
+
+ e.default_destinations();
+
+ e.perform_hook(Hook("test"));
+
+ e.default_distribution();
+ }
+}
+
+namespace mask
+{
+ void test_mask(Mask & m)
+ {
+ m.key();
+ m.description();
+ }
+
+ void test_user_mask(UserMask & m)
+ {
+ test_mask(m);
+ }
+
+ void test_unaccepted_mask(UnacceptedMask & m)
+ {
+ test_mask(m);
+ m.unaccepted_key();
+ }
+
+ void test_repository_mask(RepositoryMask & m)
+ {
+ test_mask(m);
+ m.mask_key();
+ }
+
+ void test_unsupported_mask(UnsupportedMask & m)
+ {
+ test_mask(m);
+ m.explanation();
+ }
+
+ void test_association_mask(AssociationMask & m)
+ {
+ test_mask(m);
+ m.associated_package();
+ }
+}
+
+namespace metadata_key
+{
+ void test_metadata_key(MetadataKey & m)
+ {
+ m.raw_name();
+ m.human_name();
+ }
+
+ void test_metadata_package_id_key(MetadataPackageIDKey & m)
+ {
+ test_metadata_key(m);
+ m.value();
+ }
+
+ void test_metadata_string_key(MetadataStringKey & m)
+ {
+ test_metadata_key(m);
+ m.value();
+ }
+
+ void test_metadata_time_key(MetadataTimeKey & m)
+ {
+ test_metadata_key(m);
+ m.value();
+ }
+
+ void test_metadata_contents_key(MetadataContentsKey & m)
+ {
+ test_metadata_key(m);
+ m.value();
+ }
+
+ void test_metadata_repository_mask_info_key(MetadataRepositoryMaskInfoKey & m)
+ {
+ test_metadata_key(m);
+ m.value();
+ }
+
+ template <typename C_>
+ void test_metadata_set_key(MetadataSetKey<C_> & m)
+ {
+ test_metadata_key(m);
+ m.value();
+ }
+
+ template <typename C_>
+ void test_metadata_spec_tree_key(MetadataSpecTreeKey<C_> & m)
+ {
+ test_metadata_key(m);
+ m.value();
+ m.pretty_print();
+ m.pretty_print_flat();
+ }
+}
+
+
+BOOST_PYTHON_MODULE(subclassing_test)
+{
+ /**
+ * Environemnt tests
+ */
+ bp::def("test_env", &environment::test_env);
+
+ /**
+ * Mask tests
+ */
+ bp::def("test_user_mask", &mask::test_user_mask);
+ bp::def("test_unaccepted_mask", &mask::test_unaccepted_mask);
+ bp::def("test_repository_mask", &mask::test_repository_mask);
+ bp::def("test_unsupported_mask", &mask::test_unsupported_mask);
+ bp::def("test_association_mask", &mask::test_association_mask);
+
+ /**
+ * MetadataKey tests
+ */
+ bp::def("test_metadata_package_id_key", &metadata_key::test_metadata_package_id_key);
+ bp::def("test_metadata_string_key", &metadata_key::test_metadata_string_key);
+ bp::def("test_metadata_time_key", &metadata_key::test_metadata_time_key);
+ bp::def("test_metadata_contents_key", &metadata_key::test_metadata_contents_key);
+ bp::def("test_metadata_repository_mask_info_key", &metadata_key::test_metadata_repository_mask_info_key);
+ bp::def("test_metadata_keyword_name_set_key", &metadata_key::test_metadata_set_key<KeywordNameSet>);
+ bp::def("test_metadata_use_flag_name_set_key", &metadata_key::test_metadata_set_key<UseFlagNameSet>);
+ bp::def("test_metadata_iuse_flag_set_key", &metadata_key::test_metadata_set_key<IUseFlagSet>);
+ bp::def("test_metadata_inherited_set_key", &metadata_key::test_metadata_set_key<InheritedSet>);
+ bp::def("test_metadata_license_spec_tree_key", &metadata_key::test_metadata_spec_tree_key<LicenseSpecTree>);
+ bp::def("test_metadata_provide_spec_tree_key", &metadata_key::test_metadata_spec_tree_key<ProvideSpecTree>);
+ bp::def("test_metadata_dependency_spec_tree_key", &metadata_key::test_metadata_spec_tree_key<DependencySpecTree>);
+ bp::def("test_metadata_restrict_spec_tree_key", &metadata_key::test_metadata_spec_tree_key<RestrictSpecTree>);
+ bp::def("test_metadata_uri_spec_tree_key", &metadata_key::test_metadata_spec_tree_key<URISpecTree>);
+}
diff --git a/src/clients/adjutrix/what_needs_keywording.cc b/src/clients/adjutrix/what_needs_keywording.cc
index c45c467..219c24a 100644
--- a/src/clients/adjutrix/what_needs_keywording.cc
+++ b/src/clients/adjutrix/what_needs_keywording.cc
@@ -125,7 +125,7 @@ int do_what_needs_keywording(NoConfigEnvironment & env)
for (PackageID::MasksIterator m(p->package_id->begin_masks()), m_end(p->package_id->end_masks()) ;
m != m_end ; ++m)
- masks.append(stringify(m->key()));
+ masks.append(stringify((*m)->key()));
cout << std::setw(10) << std::left << masks;
diff --git a/src/clients/contrarius/install.cc b/src/clients/contrarius/install.cc
index 66d414c..84d896d 100644
--- a/src/clients/contrarius/install.cc
+++ b/src/clients/contrarius/install.cc
@@ -357,7 +357,7 @@ do_install(tr1::shared_ptr<Environment> env, std::string spec_str)
{
if (need_comma)
cerr << ", ";
- cerr << m->description();
+ cerr << (*m)->description();
need_comma = true;
}
cerr << endl;
diff --git a/src/clients/gtkpaludis/libgtkpaludis/versions_list_model.cc b/src/clients/gtkpaludis/libgtkpaludis/versions_list_model.cc
index b85125d..9c9fc50 100644
--- a/src/clients/gtkpaludis/libgtkpaludis/versions_list_model.cc
+++ b/src/clients/gtkpaludis/libgtkpaludis/versions_list_model.cc
@@ -124,7 +124,7 @@ VersionsListModel::populate_in_paludis_thread()
if (! mr_string.empty())
mr_string.append(", ");
- mr_string.append(m->description());
+ mr_string.append((*m)->description());
}
data->items.push_back(PopulateDataItem(*p, mr_string, prefer_default));
diff --git a/src/clients/paludis/install.cc b/src/clients/paludis/install.cc
index bbcfa80..48dd431 100644
--- a/src/clients/paludis/install.cc
+++ b/src/clients/paludis/install.cc
@@ -694,7 +694,7 @@ do_install(tr1::shared_ptr<Environment> env)
{
if (need_comma)
cerr << ", ";
- cerr << m->description();
+ cerr << (*m)->description();
need_comma = true;
}
diff --git a/src/clients/paludis/report.cc b/src/clients/paludis/report.cc
index 8ae6f5d..8c97efc 100644
--- a/src/clients/paludis/report.cc
+++ b/src/clients/paludis/report.cc
@@ -102,7 +102,7 @@ namespace
{
if (comma)
cout << ", ";
- cout << colour(cl_masked, m->description());
+ cout << colour(cl_masked, (*m)->description());
comma = true;
}
++_n_errors;
diff --git a/src/output/console_install_task.cc b/src/output/console_install_task.cc
index dfdffd0..15c4a29 100644
--- a/src/output/console_install_task.cc
+++ b/src/output/console_install_task.cc
@@ -1181,7 +1181,7 @@ ConsoleInstallTask::display_merge_list_entry_mask_reasons(const DepListEntry & e
if (need_comma)
output_no_endl(", ");
MaskDisplayer d;
- m->accept(d);
+ (*m)->accept(d);
output_no_endl(d.s.str());
}
diff --git a/src/output/console_query_task.cc b/src/output/console_query_task.cc
index 9f50024..8f2754b 100644
--- a/src/output/console_query_task.cc
+++ b/src/output/console_query_task.cc
@@ -147,8 +147,8 @@ ConsoleQueryTask::display_versions_by_repository(const PackageDepSpec &,
for (PackageID::MasksIterator m((*e)->begin_masks()), m_end((*e)->end_masks()) ;
m != m_end ; ++m)
{
- reasons.append(stringify(m->key()));
- _imp->masks_to_explain->insert(m->key(), m->description());
+ reasons.append(stringify((*m)->key()));
+ _imp->masks_to_explain->insert((*m)->key(), (*m)->description());
}
right_column.append(render_as_masked("(" + (*e)->canonical_form(idcf_version) + ")" + reasons));
}