Hello community,

here is the log from the commit of package libdnf for openSUSE:Factory checked 
in at 2019-05-12 11:44:37
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libdnf (Old)
 and      /work/SRC/openSUSE:Factory/.libdnf.new.5148 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libdnf"

Sun May 12 11:44:37 2019 rev:10 rq:702040 version:0.33.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/libdnf/libdnf.changes    2019-04-28 
20:12:17.986461496 +0200
+++ /work/SRC/openSUSE:Factory/.libdnf.new.5148/libdnf.changes  2019-05-12 
11:45:13.959952308 +0200
@@ -1,0 +2,9 @@
+Fri May 10 14:37:02 UTC 2019 - Neal Gompa <ngomp...@gmail.com>
+
+- Update to version 0.33.0
+  + Import subkeys when importing GPG keys (gh#projectatomic/rpm-ostree#1094)
+  + [module] Fix swig binding for getModuleDependencies() (rh#1704871)
+  + [module] Prevent std::string from nullptr 
(gh#rpm-software-management/libdnf#717)
+  + Reintroduce hawkey.Repo as deprecated class
+
+-------------------------------------------------------------------

Old:
----
  libdnf-0.31.0.tar.gz

New:
----
  libdnf-0.33.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libdnf.spec ++++++
--- /var/tmp/diff_new_pack.rmP7TJ/_old  2019-05-12 11:45:16.347959320 +0200
+++ /var/tmp/diff_new_pack.rmP7TJ/_new  2019-05-12 11:45:16.347959320 +0200
@@ -37,7 +37,7 @@
 %define devname %{name}-devel
 
 Name:           libdnf
-Version:        0.31.0
+Version:        0.33.0
 Release:        0
 Summary:        Library providing C and Python APIs atop libsolv
 License:        LGPL-2.1-or-later

++++++ libdnf-0.31.0.tar.gz -> libdnf-0.33.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.31.0/VERSION.cmake 
new/libdnf-0.33.0/VERSION.cmake
--- old/libdnf-0.31.0/VERSION.cmake     2019-04-25 16:55:26.000000000 +0200
+++ new/libdnf-0.33.0/VERSION.cmake     2019-05-07 14:09:59.000000000 +0200
@@ -1,4 +1,4 @@
 set (LIBDNF_MAJOR_VERSION 0)
-set (LIBDNF_MINOR_VERSION 31)
+set (LIBDNF_MINOR_VERSION 33)
 set (LIBDNF_MICRO_VERSION 0)
 set (LIBDNF_VERSION 
${LIBDNF_MAJOR_VERSION}.${LIBDNF_MINOR_VERSION}.${LIBDNF_MICRO_VERSION})
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.31.0/bindings/swig/module.i 
new/libdnf-0.33.0/bindings/swig/module.i
--- old/libdnf-0.31.0/bindings/swig/module.i    2019-04-25 16:55:26.000000000 
+0200
+++ new/libdnf-0.33.0/bindings/swig/module.i    2019-05-07 14:09:59.000000000 
+0200
@@ -36,15 +36,18 @@
 %template(VectorModulePackagePtr) std::vector<libdnf::ModulePackage *>;
 %template(VectorVectorVectorModulePackagePtr) 
std::vector<std::vector<std::vector<libdnf::ModulePackage *>>>;
 %template(VectorModuleProfile) std::vector<libdnf::ModuleProfile>;
+%template(VectorModuleDependencies) std::vector<ModuleDependencies>;
 
 %include <std_vector_ext.i>
 
 // this must follow std_vector_ext.i include, otherwise it returns garbage 
instead of list of strings
 %template(MapStringVectorString) std::map<std::string, 
std::vector<std::string>>;
+%template(VectorMapStringVectorString) std::vector<std::map<std::string, 
std::vector<std::string>>>;
 
 // make SWIG wrap following headers
 %nodefaultctor libdnf::ModulePackage;
 %nodefaultctor libdnf::ModuleProfile;
+%nodefaultctor libdnf::ModuleDependencies;
 
 %include "libdnf/module/ModulePackage.hpp"
 %ignore libdnf::ModulePackageContainer::Exception;
@@ -54,3 +57,4 @@
 %ignore libdnf::ModulePackageContainer::EnableMultipleStreamsException;
 %include "libdnf/module/ModulePackageContainer.hpp"
 %include "libdnf/module/modulemd/ModuleProfile.hpp"
+%include "libdnf/module/modulemd/ModuleDependencies.hpp"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.31.0/bindings/swig/smartcols.i 
new/libdnf-0.33.0/bindings/swig/smartcols.i
--- old/libdnf-0.31.0/bindings/swig/smartcols.i 2019-04-25 16:55:26.000000000 
+0200
+++ new/libdnf-0.33.0/bindings/swig/smartcols.i 2019-05-07 14:09:59.000000000 
+0200
@@ -13,6 +13,8 @@
 #include "libdnf/utils/smartcols/Cell.hpp"
 %}
 
+%rename(_print) print;
+
 %shared_ptr(Column)
 %shared_ptr(Line)
 %shared_ptr(Cell)
@@ -29,4 +31,4 @@
 %include "libdnf/utils/smartcols/Table.hpp"
 %include "libdnf/utils/smartcols/Column.hpp"
 %include "libdnf/utils/smartcols/Line.hpp"
-%include "libdnf/utils/smartcols/Cell.hpp"
\ No newline at end of file
+%include "libdnf/utils/smartcols/Cell.hpp"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.31.0/docs/release_notes.rst 
new/libdnf-0.33.0/docs/release_notes.rst
--- old/libdnf-0.31.0/docs/release_notes.rst    2019-04-25 16:55:26.000000000 
+0200
+++ new/libdnf-0.33.0/docs/release_notes.rst    2019-05-07 14:09:59.000000000 
+0200
@@ -20,6 +20,15 @@
 ######################
 
 ====================
+0.33.0 Release Notes
+====================
+- Enhance logging handling
+- Do not log DEBUG messages by default
+- Also add subkeys when adding GPG keys
+- Reintroduce hawkey.Repo (deprecated, for compatibility)
+- [module] Fix swig binding for getModuleDependencies()
+
+====================
 0.31.0 Release Notes
 ====================
 - Installroot now requires absolute path
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.31.0/libdnf/dnf-context.cpp 
new/libdnf-0.33.0/libdnf/dnf-context.cpp
--- old/libdnf-0.31.0/libdnf/dnf-context.cpp    2019-04-25 16:55:26.000000000 
+0200
+++ new/libdnf-0.33.0/libdnf/dnf-context.cpp    2019-05-07 14:09:59.000000000 
+0200
@@ -228,8 +228,8 @@
 dnf_context_init(DnfContext *context)
 {
     DnfContextPrivate *priv = GET_PRIVATE(context);
-    gchar *vars_dir[] = {"/etc/dnf/vars", "/etc/yum/vars", NULL};
-    priv->vars_dir = g_strdupv(vars_dir);
+    const gchar *vars_dir[] = {"/etc/dnf/vars", "/etc/yum/vars", NULL};
+    priv->vars_dir = g_strdupv(const_cast<gchar **>(vars_dir));
     priv->install_root = g_strdup("/");
     priv->check_disk_space = TRUE;
     priv->check_transaction = TRUE;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.31.0/libdnf/dnf-keyring.cpp 
new/libdnf-0.33.0/libdnf/dnf-keyring.cpp
--- old/libdnf-0.31.0/libdnf/dnf-keyring.cpp    2019-04-25 16:55:26.000000000 
+0200
+++ new/libdnf-0.33.0/libdnf/dnf-keyring.cpp    2019-05-07 14:09:59.000000000 
+0200
@@ -57,11 +57,13 @@
                            GError **error)
 {
     gboolean ret = TRUE;
-    gint rc;
+    int rc;
     gsize len;
     pgpArmor armor;
     pgpDig dig = NULL;
     rpmPubkey pubkey = NULL;
+    rpmPubkey *subkeys = NULL;
+    int nsubkeys = 0;
     uint8_t *pkt = NULL;
     g_autofree gchar *data = NULL;
 
@@ -136,6 +138,20 @@
         goto out;
     }
 
+    subkeys = rpmGetSubkeys(pubkey, &nsubkeys);
+    for (int i = 0; i < nsubkeys; i++) {
+        rpmPubkey subkey = subkeys[i];
+        if (rpmKeyringAddKey(keyring, subkey) < 0) {
+            ret = FALSE;
+            g_set_error(error,
+                        DNF_ERROR,
+                        DNF_ERROR_GPG_SIGNATURE_INVALID,
+                        "failed to add subkeys for %s to rpmdb",
+                        filename);
+            goto out;
+        }
+    }
+
     /* success */
     g_debug("added missing public key %s to rpmdb", filename);
     ret = TRUE;
@@ -144,6 +160,12 @@
         free(pkt); /* yes, free() */
     if (pubkey != NULL)
         rpmPubkeyFree(pubkey);
+    if (subkeys != NULL) {
+        for (int i = 0; i < nsubkeys; i++) {
+          rpmPubkeyFree(subkeys[i]);
+        }
+        free(subkeys);
+    }
     if (dig != NULL)
         pgpFreeDig(dig);
     return ret;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libdnf-0.31.0/libdnf/module/modulemd/ModuleDependencies.cpp 
new/libdnf-0.33.0/libdnf/module/modulemd/ModuleDependencies.cpp
--- old/libdnf-0.31.0/libdnf/module/modulemd/ModuleDependencies.cpp     
2019-04-25 16:55:26.000000000 +0200
+++ new/libdnf-0.33.0/libdnf/module/modulemd/ModuleDependencies.cpp     
2019-05-07 14:09:59.000000000 +0200
@@ -23,12 +23,17 @@
 
 namespace libdnf {
 
+ModuleDependencies::ModuleDependencies() : dependencies(nullptr) {}
+
 ModuleDependencies::ModuleDependencies(ModulemdDependencies *dependencies)
         : dependencies(dependencies)
 {}
 
 std::vector <std::map<std::string, std::vector<std::string>>> 
ModuleDependencies::getRequires() const
 {
+    if (!dependencies) {
+        return {};
+    }
     auto cRequires = modulemd_dependencies_peek_requires(dependencies);
     return getRequirements(cRequires);
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libdnf-0.31.0/libdnf/module/modulemd/ModuleDependencies.hpp 
new/libdnf-0.33.0/libdnf/module/modulemd/ModuleDependencies.hpp
--- old/libdnf-0.31.0/libdnf/module/modulemd/ModuleDependencies.hpp     
2019-04-25 16:55:26.000000000 +0200
+++ new/libdnf-0.33.0/libdnf/module/modulemd/ModuleDependencies.hpp     
2019-05-07 14:09:59.000000000 +0200
@@ -34,6 +34,7 @@
 class ModuleDependencies
 {
 public:
+    explicit ModuleDependencies();
     explicit ModuleDependencies(ModulemdDependencies *dependencies);
 
     std::vector<std::map<std::string, std::vector<std::string> > > 
getRequires() const;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libdnf-0.31.0/libdnf/module/modulemd/ModuleProfile.cpp 
new/libdnf-0.33.0/libdnf/module/modulemd/ModuleProfile.cpp
--- old/libdnf-0.31.0/libdnf/module/modulemd/ModuleProfile.cpp  2019-04-25 
16:55:26.000000000 +0200
+++ new/libdnf-0.33.0/libdnf/module/modulemd/ModuleProfile.cpp  2019-05-07 
14:09:59.000000000 +0200
@@ -32,7 +32,8 @@
     if (!profile) {
         return {};
     }
-    return modulemd_profile_peek_name(profile);
+    auto name = modulemd_profile_peek_name(profile);
+    return name ? name : "";
 }
 
 std::string ModuleProfile::getDescription() const
@@ -40,7 +41,8 @@
     if (!profile) {
         return {};
     }
-    return modulemd_profile_peek_description(profile);
+    auto description =  modulemd_profile_peek_description(profile);
+    return description ? description : "";
 }
 
 std::vector<std::string> ModuleProfile::getContent() const
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.31.0/libdnf/repo/Repo.cpp 
new/libdnf-0.33.0/libdnf/repo/Repo.cpp
--- old/libdnf-0.31.0/libdnf/repo/Repo.cpp      2019-04-25 16:55:26.000000000 
+0200
+++ new/libdnf-0.33.0/libdnf/repo/Repo.cpp      2019-05-07 14:09:59.000000000 
+0200
@@ -319,7 +319,6 @@
         libsolvRepo->appdata = nullptr;
 }
 
-static int count = 0;
 Repo::Repo(const std::string & id, std::unique_ptr<ConfigRepo> && conf, 
Repo::Type type)
 {
     if (type == Type::AVAILABLE) {
@@ -1724,7 +1723,7 @@
     }
 }
 
-long LibrepoLog::addHandler(const std::string & filePath)
+long LibrepoLog::addHandler(const std::string & filePath, bool debug)
 {
     static long uid = 0;
 
@@ -1739,7 +1738,14 @@
     data->fd = fd;
 
     // Set handler
-    data->handlerId = g_log_set_handler(LR_LOGDOMAIN, G_LOG_LEVEL_MASK, 
librepoLogCB, data.get());
+    GLogLevelFlags log_mask = debug ? G_LOG_LEVEL_MASK : 
static_cast<GLogLevelFlags>(
+        G_LOG_LEVEL_INFO |
+        G_LOG_LEVEL_MESSAGE |
+        G_LOG_LEVEL_WARNING |
+        G_LOG_LEVEL_CRITICAL |
+        G_LOG_LEVEL_ERROR);
+
+    data->handlerId = g_log_set_handler(LR_LOGDOMAIN, log_mask, librepoLogCB, 
data.get());
     data->used = true;
 
     // Save user data (in a thread safe way)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.31.0/libdnf/repo/Repo.hpp 
new/libdnf-0.33.0/libdnf/repo/Repo.hpp
--- old/libdnf-0.31.0/libdnf/repo/Repo.hpp      2019-04-25 16:55:26.000000000 
+0200
+++ new/libdnf-0.33.0/libdnf/repo/Repo.hpp      2019-05-07 14:09:59.000000000 
+0200
@@ -338,7 +338,7 @@
 
 struct LibrepoLog {
 public:
-    static long addHandler(const std::string & filePath);
+    static long addHandler(const std::string & filePath, bool debug = false);
     static void removeHandler(long uid);
     static void removeAllHandlers();
 };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libdnf-0.31.0/libdnf/transaction/MergedTransaction.cpp 
new/libdnf-0.33.0/libdnf/transaction/MergedTransaction.cpp
--- old/libdnf-0.31.0/libdnf/transaction/MergedTransaction.cpp  2019-04-25 
16:55:26.000000000 +0200
+++ new/libdnf-0.33.0/libdnf/transaction/MergedTransaction.cpp  2019-05-07 
14:09:59.000000000 +0200
@@ -405,6 +405,8 @@
         case TransactionItemAction::OBSOLETE:
             resolveAltered(previousItemPair, mTransItem);
             break;
+        case TransactionItemAction::REINSTALLED:
+            break;
     }
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.31.0/libdnf.spec 
new/libdnf-0.33.0/libdnf.spec
--- old/libdnf-0.31.0/libdnf.spec       2019-04-25 16:55:26.000000000 +0200
+++ new/libdnf-0.33.0/libdnf.spec       2019-05-07 14:09:59.000000000 +0200
@@ -31,7 +31,7 @@
     %{nil}
 
 Name:           libdnf
-Version:        0.31.0
+Version:        0.33.0
 Release:        1%{?dist}
 Summary:        Library providing simplified C and Python API to libsolv
 License:        LGPLv2+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.31.0/python/hawkey/CMakeLists.txt 
new/libdnf-0.33.0/python/hawkey/CMakeLists.txt
--- old/libdnf-0.31.0/python/hawkey/CMakeLists.txt      2019-04-25 
16:55:26.000000000 +0200
+++ new/libdnf-0.33.0/python/hawkey/CMakeLists.txt      2019-05-07 
14:09:59.000000000 +0200
@@ -33,6 +33,7 @@
     packagedelta-py.cpp
     query-py.cpp
     reldep-py.cpp
+    repo-py.cpp
     sack-py.cpp
     selector-py.cpp
     subject-py.cpp
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.31.0/python/hawkey/__init__.py 
new/libdnf-0.33.0/python/hawkey/__init__.py
--- old/libdnf-0.31.0/python/hawkey/__init__.py 2019-04-25 16:55:26.000000000 
+0200
+++ new/libdnf-0.33.0/python/hawkey/__init__.py 2019-05-07 14:09:59.000000000 
+0200
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2012-2014 Red Hat, Inc.
+# Copyright (C) 2012-2019 Red Hat, Inc.
 #
 # Licensed under the GNU Lesser General Public License Version 2.1
 #
@@ -52,7 +52,7 @@
     # functions
     'chksum_name', 'chksum_type', 'split_nevra', 'convert_hawkey_reason',
     # classes
-    'Goal', 'NEVRA', 'NSVCAP', 'Package', 'Query', 'Sack', 'Selector', 
'Subject']
+    'Goal', 'NEVRA', 'NSVCAP', 'Package', 'Query', 'Repo', 'Sack', 'Selector', 
'Subject']
 
 NEVRA = _hawkey.NEVRA
 Query = _hawkey.Query
@@ -333,3 +333,13 @@
     def _list_or_query_to_selector(sack, list_or_query):
         sltr = Selector(sack)
         return sltr.set(pkg=list_or_query)
+
+
+class Repo(_hawkey.Repo):
+
+    def __init__(self, name):
+        warnings.simplefilter('always', DeprecationWarning)
+        msg = "The class hawkey.Repo is deprecated. " \
+              "Please use dnf.repo.Repo instead. The class will be removed on 
2019-12-31."
+        warnings.warn(msg, DeprecationWarning)
+        super(Repo, self).__init__(name)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.31.0/python/hawkey/hawkeymodule.cpp 
new/libdnf-0.33.0/python/hawkey/hawkeymodule.cpp
--- old/libdnf-0.31.0/python/hawkey/hawkeymodule.cpp    2019-04-25 
16:55:26.000000000 +0200
+++ new/libdnf-0.33.0/python/hawkey/hawkeymodule.cpp    2019-05-07 
14:09:59.000000000 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012-2014 Red Hat, Inc.
+ * Copyright (C) 2012-2019 Red Hat, Inc.
  *
  * Licensed under the GNU Lesser General Public License Version 2.1
  *
@@ -46,6 +46,7 @@
 #include "packagedelta-py.hpp"
 #include "query-py.hpp"
 #include "reldep-py.hpp"
+#include "repo-py.hpp"
 #include "sack-py.hpp"
 #include "selector-py.hpp"
 #include "subject-py.hpp"
@@ -193,6 +194,11 @@
         return PYCOMP_MOD_ERROR_VAL;
     Py_INCREF(&selector_Type);
     PyModule_AddObject(m, "Selector", (PyObject *)&selector_Type);
+    /* _hawkey.Repo */
+    if (PyType_Ready(&repo_Type) < 0)
+        return PYCOMP_MOD_ERROR_VAL;
+    Py_INCREF(&repo_Type);
+    PyModule_AddObject(m, "Repo", (PyObject *)&repo_Type);
     /* _hawkey.NEVRA */
     if (PyType_Ready(&nevra_Type) < 0)
         return PYCOMP_MOD_ERROR_VAL;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.31.0/python/hawkey/repo-py.cpp 
new/libdnf-0.33.0/python/hawkey/repo-py.cpp
--- old/libdnf-0.31.0/python/hawkey/repo-py.cpp 1970-01-01 01:00:00.000000000 
+0100
+++ new/libdnf-0.33.0/python/hawkey/repo-py.cpp 2019-05-07 14:09:59.000000000 
+0200
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2012-2019 Red Hat, Inc.
+ *
+ * Licensed under the GNU Lesser General Public License Version 2.1
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <Python.h>
+#include <stdint.h>
+
+// hawkey
+#include "hy-repo.h"
+
+// pyhawkey
+#include "hawkey-pysys.hpp"
+#include "repo-py.hpp"
+
+#include "pycomp.hpp"
+
+typedef struct {
+    PyObject_HEAD
+    HyRepo repo;
+} _RepoObject;
+
+typedef struct {
+    int (*getter)(HyRepo);
+    void (*setter)(HyRepo, int);
+} IntGetSetter;
+
+HyRepo repoFromPyObject(PyObject *o)
+{
+    if (!PyObject_TypeCheck(o, &repo_Type)) {
+        return NULL;
+    }
+    return ((_RepoObject *)o)->repo;
+}
+
+PyObject *repoToPyObject(HyRepo repo)
+{
+    _RepoObject *self = (_RepoObject *)repo_Type.tp_alloc(&repo_Type, 0);
+    if (self)
+        self->repo = repo;
+    return (PyObject *)self;
+}
+
+/* functions on the type */
+
+static PyObject *
+repo_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    _RepoObject *self = (_RepoObject *)type->tp_alloc(type, 0);
+    if (self) {
+        self->repo = hy_repo_create("(default)");
+        if (self->repo == NULL) {
+            Py_DECREF(self);
+            return NULL;
+        }
+    }
+    return (PyObject *) self;
+}
+
+static int
+repo_init(_RepoObject *self, PyObject *args, PyObject *kwds)
+{
+    const char *name;
+    if (!PyArg_ParseTuple(args, "s", &name))
+        return -1;
+    hy_repo_set_string(self->repo, HY_REPO_NAME, name);
+    return 0;
+}
+
+static void
+repo_dealloc(_RepoObject *self)
+{
+    hy_repo_free(self->repo);
+    Py_TYPE(self)->tp_free(self);
+}
+
+/* getsetters */
+
+static PyObject *
+get_int(_RepoObject *self, void *closure)
+{
+    IntGetSetter *functions = (IntGetSetter*)closure;
+    return PyLong_FromLong(functions->getter(self->repo));
+}
+
+static int
+set_int(_RepoObject *self, PyObject *value, void *closure)
+{
+    IntGetSetter *functions = (IntGetSetter*)closure;
+    long num = PyLong_AsLong(value);
+    if (PyErr_Occurred())
+            return -1;
+    if (num > INT_MAX || num < INT_MIN) {
+        PyErr_SetString(PyExc_ValueError, "Value in the integer range 
expected.");
+        return -1;
+    }
+    functions->setter(self->repo, num);
+    return 0;
+}
+
+static PyObject *
+get_str(_RepoObject *self, void *closure)
+{
+    int str_key = (intptr_t)closure;
+    const char *str;
+    PyObject *ret;
+
+    str = hy_repo_get_string(self->repo, str_key);
+    if (str == NULL) {
+        ret = PyString_FromString("");
+    } else {
+        ret = PyString_FromString(str);
+    }
+    return ret; // NULL if PyString_FromString failed
+}
+
+static int
+set_str(_RepoObject *self, PyObject *value, void *closure)
+{
+    intptr_t str_key = (intptr_t)closure;
+    PycompString str_value(value);
+    if (!str_value.getCString())
+        return -1;
+    hy_repo_set_string(self->repo, str_key, str_value.getCString());
+    return 0;
+}
+
+static IntGetSetter hy_repo_cost{hy_repo_get_cost, hy_repo_set_cost};
+
+static IntGetSetter hy_repo_priority{hy_repo_get_priority, 
hy_repo_set_priority};
+
+static PyGetSetDef repo_getsetters[] = {
+    {(char*)"cost", (getter)get_int, (setter)set_int, (char*)"repository cost",
+     (void *)&hy_repo_cost},
+    {(char*)"name", (getter)get_str, (setter)set_str, NULL,
+     (void *)HY_REPO_NAME},
+    {(char*)"priority", (getter)get_int, (setter)set_int, (char*)"repository 
priority",
+     (void *)&hy_repo_priority},
+    {(char*)"repomd_fn", (getter)get_str, (setter)set_str, NULL,
+     (void *)HY_REPO_MD_FN},
+    {(char*)"primary_fn", (getter)get_str, (setter)set_str, NULL,
+     (void *)HY_REPO_PRIMARY_FN},
+    {(char*)"filelists_fn", (getter)get_str, (setter)set_str, NULL,
+     (void *)HY_REPO_FILELISTS_FN},
+    {(char*)"modules_fn", (getter)get_str, (setter)set_str, NULL,
+     (void *)MODULES_FN},
+    {(char*)"presto_fn", (getter)get_str, (setter)set_str, NULL,
+     (void *)HY_REPO_PRESTO_FN},
+    {(char*)"updateinfo_fn", (getter)get_str, (setter)set_str, NULL,
+     (void *)HY_REPO_UPDATEINFO_FN},
+    {(char*)"other_fn", (getter)get_str, (setter)set_str, NULL,
+     (void *)HY_REPO_OTHER_FN},
+    {NULL}                        /* sentinel */
+};
+
+PyTypeObject repo_Type = {
+    PyVarObject_HEAD_INIT(NULL, 0)
+    "_hawkey.Repo",                /*tp_name*/
+    sizeof(_RepoObject),        /*tp_basicsize*/
+    0,                                /*tp_itemsize*/
+    (destructor) repo_dealloc,  /*tp_dealloc*/
+    0,                                /*tp_print*/
+    0,                                /*tp_getattr*/
+    0,                                /*tp_setattr*/
+    0,                                /*tp_compare*/
+    0,                                /*tp_repr*/
+    0,                                /*tp_as_number*/
+    0,                                /*tp_as_sequence*/
+    0,                                /*tp_as_mapping*/
+    0,                                /*tp_hash */
+    0,                                /*tp_call*/
+    0,                                /*tp_str*/
+    0,                                /*tp_getattro*/
+    0,                                /*tp_setattro*/
+    0,                                /*tp_as_buffer*/
+    Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/
+    "Repo object",                /* tp_doc */
+    0,                                /* tp_traverse */
+    0,                                /* tp_clear */
+    0,                                /* tp_richcompare */
+    0,                                /* tp_weaklistoffset */
+    PyObject_SelfIter,                /* tp_iter */
+    0,                                 /* tp_iternext */
+    0,                                /* tp_methods */
+    0,                                /* tp_members */
+    repo_getsetters,                /* tp_getset */
+    0,                                /* tp_base */
+    0,                                /* tp_dict */
+    0,                                /* tp_descr_get */
+    0,                                /* tp_descr_set */
+    0,                                /* tp_dictoffset */
+    (initproc)repo_init,        /* tp_init */
+    0,                                /* tp_alloc */
+    repo_new,                        /* tp_new */
+    0,                                /* tp_free */
+    0,                                /* tp_is_gc */
+};
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.31.0/python/hawkey/repo-py.hpp 
new/libdnf-0.33.0/python/hawkey/repo-py.hpp
--- old/libdnf-0.31.0/python/hawkey/repo-py.hpp 1970-01-01 01:00:00.000000000 
+0100
+++ new/libdnf-0.33.0/python/hawkey/repo-py.hpp 2019-05-07 14:09:59.000000000 
+0200
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2012-2019 Red Hat, Inc.
+ *
+ * Licensed under the GNU Lesser General Public License Version 2.1
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef REPO_PY_H
+#define REPO_PY_H
+
+#include "hy-types.h"
+
+extern PyTypeObject repo_Type;
+
+HyRepo repoFromPyObject(PyObject *o);
+PyObject *repoToPyObject(HyRepo repo);
+
+#endif // REPO_PY_H
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.31.0/python/hawkey/sack-py.cpp 
new/libdnf-0.33.0/python/hawkey/sack-py.cpp
--- old/libdnf-0.31.0/python/hawkey/sack-py.cpp 2019-04-25 16:55:26.000000000 
+0200
+++ new/libdnf-0.33.0/python/hawkey/sack-py.cpp 2019-05-07 14:09:59.000000000 
+0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012-2015 Red Hat, Inc.
+ * Copyright (C) 2012-2019 Red Hat, Inc.
  *
  * Licensed under the GNU Lesser General Public License Version 2.1
  *
@@ -37,6 +37,7 @@
 #include "hawkey-pysys.hpp"
 #include "iutil-py.hpp"
 #include "package-py.hpp"
+#include "repo-py.hpp"
 #include "sack-py.hpp"
 
 #include "pycomp.hpp"
@@ -187,15 +188,34 @@
     g_free(msg);
 }
 
+static void
+log_handler_noop(const gchar *, GLogLevelFlags, const gchar *, gpointer)
+{
+}
+
 gboolean
-set_logfile(const gchar *path, FILE *log_out)
+set_logfile(const gchar *path, FILE *log_out, bool debug)
 {
     log_out = fopen(path, "a");
 
     if (!log_out)
         return FALSE;
 
-    g_log_set_default_handler(log_handler, log_out);
+    // The default log handler prints messages that weren't handled by any
+    // other logger to stderr/stdout, we do not want that
+    g_log_set_default_handler(log_handler_noop, nullptr);
+
+    GLogLevelFlags log_mask = debug ? G_LOG_LEVEL_MASK : 
static_cast<GLogLevelFlags>(
+        G_LOG_LEVEL_INFO |
+        G_LOG_LEVEL_MESSAGE |
+        G_LOG_LEVEL_WARNING |
+        G_LOG_LEVEL_CRITICAL |
+        G_LOG_LEVEL_ERROR);
+
+    // set the handler for the default domain as well as "libdnf"
+    g_log_set_handler(nullptr, log_mask, log_handler, log_out);
+    g_log_set_handler("libdnf", log_mask, log_handler, log_out);
+
     g_info("=== Started libdnf-%d.%d.%d ===", LIBDNF_MAJOR_VERSION,
             LIBDNF_MINOR_VERSION, LIBDNF_MICRO_VERSION);
     return TRUE;
@@ -214,16 +234,22 @@
     PyObject *logfile_py = NULL;
     self->log_out = NULL;
     int make_cache_dir = 0;
+    PyObject *debug_object = nullptr;
     gboolean all_arch = FALSE;
     const char *kwlist[] = {"cachedir", "arch", "rootdir", "pkgcls",
-                      "pkginitval", "make_cache_dir", "logfile", "all_arch",
-                      NULL};
+                      "pkginitval", "make_cache_dir", "logfile", "logdebug",
+                      "all_arch", NULL};
 
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OssOOiOi", (char**) kwlist,
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OssOOiOO!i", (char**) 
kwlist,
                                      &cachedir_py, &arch, &rootdir,
                                      &custom_class, &custom_val,
-                                     &make_cache_dir, &logfile_py, &all_arch))
+                                     &make_cache_dir, &logfile_py,
+                                     &PyBool_Type, &debug_object,
+                                     &all_arch))
         return -1;
+
+    bool debug = debug_object != nullptr && PyObject_IsTrue(debug_object);
+
     if (cachedir_py != NULL) {
         cachedir = PycompString(cachedir_py);
         if (!cachedir.getCString())
@@ -247,7 +273,7 @@
         PycompString logfile(logfile_py);
         if (!logfile.getCString())
             return -1;
-        if (!set_logfile(logfile.getCString(), self->log_out)) {
+        if (!set_logfile(logfile.getCString(), self->log_out, debug)) {
             PyErr_Format(PyExc_IOError, "Failed to open log file: %s", 
logfile.getCString());
             return -1;
         }
@@ -641,16 +667,23 @@
         return 0;
 
     if (repoPyObj) {
-        auto repoSwigPyObj = reinterpret_cast<RepoSwigPyObject 
*>(PyObject_GetAttrString(repoPyObj, "this"));
-        if (!repoSwigPyObj) {
-            PyErr_SetString(PyExc_SystemError, "Unable to parse 
repoSwigPyObject");
-            return NULL;
-        }
 
-        crepo = repoSwigPyObj->ptr;
+        // Is it old deprecated _hawkey.Repo object?
+        crepo = repoFromPyObject(repoPyObj);
+
+        // Or is it swig object?
         if (!crepo) {
-            PyErr_SetString(PyExc_SystemError, "Unable to parse repo swig 
object");
-            return NULL;
+            auto repoSwigPyObj = reinterpret_cast<RepoSwigPyObject 
*>(PyObject_GetAttrString(repoPyObj, "this"));
+            if (!repoSwigPyObj) {
+                PyErr_SetString(PyExc_SystemError, "Unable to parse 
repoSwigPyObject");
+                return NULL;
+            }
+
+            crepo = repoSwigPyObj->ptr;
+            if (!crepo) {
+                PyErr_SetString(PyExc_SystemError, "Unable to parse repo swig 
object");
+                return NULL;
+            }
         }
     }
 
@@ -678,16 +711,22 @@
                                      &load_presto, &load_updateinfo, 
&load_other))
         return 0;
 
-    auto repoSwigPyObj = reinterpret_cast<RepoSwigPyObject 
*>(PyObject_GetAttrString(repoPyObj, "this"));
-    if (!repoSwigPyObj) {
-        PyErr_SetString(PyExc_SystemError, "Unable to parse repoSwigPyObject");
-        return NULL;
-    }
+    // Is it old deprecated _hawkey.Repo object?
+    libdnf::Repo * crepo = repoFromPyObject(repoPyObj);
 
-    libdnf::Repo * crepo = repoSwigPyObj->ptr;
+    // Or is it swig object?
     if (!crepo) {
-        PyErr_SetString(PyExc_SystemError, "Unable to parse repo swig object");
-        return NULL;
+        auto repoSwigPyObj = reinterpret_cast<RepoSwigPyObject 
*>(PyObject_GetAttrString(repoPyObj, "this"));
+        if (!repoSwigPyObj) {
+            PyErr_SetString(PyExc_SystemError, "Unable to parse 
repoSwigPyObject");
+            return NULL;
+        }
+
+        crepo = repoSwigPyObj->ptr;
+        if (!crepo) {
+            PyErr_SetString(PyExc_SystemError, "Unable to parse repo swig 
object");
+            return NULL;
+        }
     }
 
     int flags = 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.31.0/python/hawkey/sack-py.hpp 
new/libdnf-0.33.0/python/hawkey/sack-py.hpp
--- old/libdnf-0.31.0/python/hawkey/sack-py.hpp 2019-04-25 16:55:26.000000000 
+0200
+++ new/libdnf-0.33.0/python/hawkey/sack-py.hpp 2019-05-07 14:09:59.000000000 
+0200
@@ -35,7 +35,7 @@
 int sack_converter(PyObject *o, DnfSack **sack_ptr);
 
 PyObject *new_package(PyObject *sack, Id id);
-gboolean set_logfile(const gchar *path, FILE *log_out);
+gboolean set_logfile(const gchar *path, FILE *log_out, bool debug = false);
 const char *log_level_name(int level);
 
 #endif // SACK_PY_H
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.31.0/python/hawkey/tests/module/__init__.py 
new/libdnf-0.33.0/python/hawkey/tests/module/__init__.py
--- old/libdnf-0.31.0/python/hawkey/tests/module/__init__.py    2019-04-25 
16:55:26.000000000 +0200
+++ new/libdnf-0.33.0/python/hawkey/tests/module/__init__.py    2019-05-07 
14:09:59.000000000 +0200
@@ -32,6 +32,8 @@
 UNITTEST_DIR = _hawkey_test.UNITTEST_DIR
 YUM_DIR_SUFFIX = _hawkey_test.YUM_DIR_SUFFIX
 
+glob_for_repofiles = _hawkey_test.glob_for_repofiles
+
 class TestSackMixin(object):
     def __init__(self, repo_dir):
         self.repo_dir = repo_dir
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libdnf-0.31.0/python/hawkey/tests/module/hawkey_testmodule.cpp 
new/libdnf-0.33.0/python/hawkey/tests/module/hawkey_testmodule.cpp
--- old/libdnf-0.31.0/python/hawkey/tests/module/hawkey_testmodule.cpp  
2019-04-25 16:55:26.000000000 +0200
+++ new/libdnf-0.33.0/python/hawkey/tests/module/hawkey_testmodule.cpp  
2019-05-07 14:09:59.000000000 +0200
@@ -23,6 +23,7 @@
 // hawkey
 #include "dnf-sack-private.hpp"
 
+#include "python/hawkey/repo-py.hpp"
 #include "python/hawkey/sack-py.hpp"
 #include "tests/hawkey/testshared.h"
 
@@ -53,9 +54,24 @@
     Py_RETURN_NONE;
 }
 
+static PyObject *
+py_glob_for_repofiles(PyObject *unused, PyObject *args)
+{
+    const char *repo_name, *path;
+    DnfSack *sack;
+
+    if (!PyArg_ParseTuple(args, "O&ss",
+                         sack_converter, &sack, &repo_name, &path))
+       return NULL;
+    HyRepo repo = glob_for_repofiles(dnf_sack_get_pool(sack), repo_name, path);
+    return repoToPyObject(repo);
+}
+
 static struct PyMethodDef testmodule_methods[] = {
     {"load_repo",              (PyCFunction)py_load_repo,
      METH_VARARGS, NULL},
+    {"glob_for_repofiles",     (PyCFunction)py_glob_for_repofiles,
+     METH_VARARGS, NULL},
     {NULL}                             /* sentinel */
 };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.31.0/python/hawkey/tests/tests/base.py 
new/libdnf-0.33.0/python/hawkey/tests/tests/base.py
--- old/libdnf-0.31.0/python/hawkey/tests/tests/base.py 2019-04-25 
16:55:26.000000000 +0200
+++ new/libdnf-0.33.0/python/hawkey/tests/tests/base.py 2019-05-07 
14:09:59.000000000 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2012-2013 Red Hat, Inc.
+# Copyright (C) 2012-2019 Red Hat, Inc.
 #
 # Licensed under the GNU Lesser General Public License Version 2.1
 #
@@ -72,6 +72,12 @@
         repo.load()
         super(TestSack, self).load_repo(repo, **kwargs)
 
+    # Loading using hawkey.Repo
+    def load_repo_hawkey_Repo(self, **kwargs):
+        d = os.path.join(self.repo_dir, hawkey.test.YUM_DIR_SUFFIX)
+        repo = hawkey.test.glob_for_repofiles(self, "messerk", d)
+        super(TestSack, self).load_repo(repo, **kwargs)
+
 def by_name(sack, name):
     return hawkey.Query(sack).filter(name=name)[0]
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.31.0/python/hawkey/tests/tests/test_repo.py 
new/libdnf-0.33.0/python/hawkey/tests/tests/test_repo.py
--- old/libdnf-0.31.0/python/hawkey/tests/tests/test_repo.py    1970-01-01 
01:00:00.000000000 +0100
+++ new/libdnf-0.33.0/python/hawkey/tests/tests/test_repo.py    2019-05-07 
14:09:59.000000000 +0200
@@ -0,0 +1,49 @@
+#
+# Copyright (C) 2012-2019 Red Hat, Inc.
+#
+# Licensed under the GNU Lesser General Public License Version 2.1
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+import hawkey
+import unittest
+
+
+class Package(unittest.TestCase):
+    def test_create(self):
+        r = hawkey.Repo("fog")
+        self.assertIsNotNone(r)
+        self.assertRaises(TypeError, hawkey.Repo);
+        self.assertRaises(TypeError, hawkey.Repo, 3)
+        self.assertRaises(TypeError, hawkey.Repo, rain="pouring")
+
+    def test_cost_assignment(self):
+        r = hawkey.Repo("fog")
+        r.cost = 300
+        self.assertEqual(300, r.cost)
+
+        r2 = hawkey.Repo("blizzard")
+        self.assertEqual(1000, r2.cost)
+        with self.assertRaises(TypeError):
+            r2.cost = '4'
+
+    def test_str_assignment(self):
+        r = hawkey.Repo('fog')
+        with self.assertRaises(TypeError):
+            r.repomd_fn = 3
+        r.repomd_fn = 'rain'
+        self.assertEqual(r.repomd_fn, 'rain')
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libdnf-0.31.0/python/hawkey/tests/tests/test_sack.py 
new/libdnf-0.33.0/python/hawkey/tests/tests/test_sack.py
--- old/libdnf-0.31.0/python/hawkey/tests/tests/test_sack.py    2019-04-25 
16:55:26.000000000 +0200
+++ new/libdnf-0.33.0/python/hawkey/tests/tests/test_sack.py    2019-05-07 
14:09:59.000000000 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2012-2015 Red Hat, Inc.
+# Copyright (C) 2012-2019 Red Hat, Inc.
 #
 # Licensed under the GNU Lesser General Public License Version 2.1
 #
@@ -48,6 +48,14 @@
         self.assertEqual(len(sack), hawkey.test.EXPECT_YUM_NSOLVABLES +
                          hawkey.test.EXPECT_SYSTEM_NSOLVABLES)
 
+    # Loading test using hawkey.Repo
+    def test_load_yum_hawkey_Repo(self):
+        sack = base.TestSack(repo_dir=self.repo_dir)
+        sack.load_system_repo()
+        sack.load_repo_hawkey_Repo(build_cache=True)
+        self.assertEqual(len(sack), hawkey.test.EXPECT_YUM_NSOLVABLES +
+                         hawkey.test.EXPECT_SYSTEM_NSOLVABLES)
+
     def test_cache_dir(self):
         sack = base.TestSack(repo_dir=self.repo_dir)
         self.assertTrue(sack.cache_dir.startswith("/tmp/pyhawkey"))
@@ -77,6 +85,13 @@
         self.assertRaises(IOError, sack.load_repo, repo)
         sack = hawkey.Sack()
 
+    # Loading test using hawkey.Repo
+    def test_failed_load_hawkey_Repo(self):
+        sack = hawkey.Sack(cachedir=base.cachedir)
+        repo = hawkey.Repo("name")
+        self.assertRaises(IOError, sack.load_repo, repo)
+        sack = hawkey.Sack()
+
     def test_unicoded_cachedir(self):
         # does not raise UnicodeEncodeError
         hawkey.Sack(cachedir=u"unicod\xe9")


Reply via email to