From 5b935af0c790ef9d5a76aa6dd44c8ee5e89959c0 Mon Sep 17 00:00:00 2001
From: Aleš Matěj <amatej@redhat.com>
Date: Feb 10 2020 15:39:51 +0000
Subject: Backport patch to fix failing build with Python 3.9 (RhBug:1788918)


---

diff --git a/179.patch b/179.patch
new file mode 100644
index 0000000..f79b48d
--- /dev/null
+++ b/179.patch
@@ -0,0 +1,111 @@
+From 34450c11255f7ae19ecda92f9bb4ff2b5adf498b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hr=C3=A1zk=C3=BD?= <lhrazky@redhat.com>
+Date: Thu, 16 Jan 2020 16:36:11 +0100
+Subject: [PATCH] Fix calling Python API without holding GIL (RhBug:1788918)
+
+Librepo releases GIL for the download operations, but it wasn't taking
+it again early enough in some callbacks where Python API is being called.
+
+This commit moves taking the GIL in the callbacks to before any Python
+API is called.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=1788918
+---
+ librepo/python/handle-py.c         | 6 ++++--
+ librepo/python/metadatatarget-py.c | 6 ++++--
+ librepo/python/packagetarget-py.c  | 6 ++++--
+ 3 files changed, 12 insertions(+), 6 deletions(-)
+
+diff --git a/librepo/python/handle-py.c b/librepo/python/handle-py.c
+index 28aad87..02615ad 100644
+--- a/librepo/python/handle-py.c
++++ b/librepo/python/handle-py.c
+@@ -142,6 +142,8 @@ fastestmirror_callback(void *data, LrFastestMirrorStages stage, void *ptr)
+     else
+         user_data = Py_None;
+ 
++    EndAllowThreads(self->state);
++
+     if (!ptr) {
+         pydata = Py_None;
+     } else {
+@@ -159,7 +161,6 @@ fastestmirror_callback(void *data, LrFastestMirrorStages stage, void *ptr)
+         }
+     }
+ 
+-    EndAllowThreads(self->state);
+     result = PyObject_CallFunction(self->fastestmirror_cb,
+                         "(OlO)", user_data, (long) stage, pydata);
+     Py_XDECREF(result);
+@@ -187,11 +188,12 @@ hmf_callback(void *data, const char *msg, const char *url, const char *metadata)
+     else
+         user_data = Py_None;
+ 
++    EndAllowThreads(self->state);
++
+     py_msg = PyStringOrNone_FromString(msg);
+     py_url = PyStringOrNone_FromString(url);
+     py_metadata = PyStringOrNone_FromString(metadata);
+ 
+-    EndAllowThreads(self->state);
+     result = PyObject_CallFunction(self->hmf_cb,
+                         "(OOOO)", user_data, py_msg, py_url, py_metadata);
+ 
+diff --git a/librepo/python/metadatatarget-py.c b/librepo/python/metadatatarget-py.c
+index d5f4088..4cb67ad 100644
+--- a/librepo/python/metadatatarget-py.c
++++ b/librepo/python/metadatatarget-py.c
+@@ -142,10 +142,11 @@ metadatatarget_mirrorfailure_callback(void *data,
+     else
+         user_data = Py_None;
+ 
++    EndAllowThreads(self->state);
++
+     py_msg = PyStringOrNone_FromString(msg);
+     py_url = PyStringOrNone_FromString(url);
+ 
+-    EndAllowThreads(self->state);
+     result = PyObject_CallFunction(self->mirrorfailure_cb,
+                                    "(OOO)", user_data, py_msg, py_url);
+ 
+@@ -205,9 +206,10 @@ metadatatarget_end_callback(void *data,
+     else
+         user_data = Py_None;
+ 
++    EndAllowThreads(self->state);
++
+     py_msg = PyStringOrNone_FromString(msg);
+ 
+-    EndAllowThreads(self->state);
+     result = PyObject_CallFunction(self->end_cb,
+                                    "(OiO)", user_data, status, py_msg);
+     Py_DECREF(py_msg);
+diff --git a/librepo/python/packagetarget-py.c b/librepo/python/packagetarget-py.c
+index 839ec8c..f5182dd 100644
+--- a/librepo/python/packagetarget-py.c
++++ b/librepo/python/packagetarget-py.c
+@@ -134,9 +134,10 @@ packagetarget_end_callback(void *data,
+     else
+         user_data = Py_None;
+ 
++    EndAllowThreads(self->state);
++
+     py_msg = PyStringOrNone_FromString(msg);
+ 
+-    EndAllowThreads(self->state);
+     result = PyObject_CallFunction(self->end_cb,
+                                    "(OiO)", user_data, status, py_msg);
+     Py_DECREF(py_msg);
+@@ -185,10 +186,11 @@ packagetarget_mirrorfailure_callback(void *data,
+     else
+         user_data = Py_None;
+ 
++    EndAllowThreads(self->state);
++
+     py_msg = PyStringOrNone_FromString(msg);
+     py_url = PyStringOrNone_FromString(url);
+ 
+-    EndAllowThreads(self->state);
+     result = PyObject_CallFunction(self->mirrorfailure_cb,
+                                    "(OOO)", user_data, py_msg, py_url);
+ 
diff --git a/librepo.spec b/librepo.spec
index e47548b..a18ebcc 100644
--- a/librepo.spec
+++ b/librepo.spec
@@ -27,13 +27,15 @@
 
 Name:           librepo
 Version:        1.11.1
-Release:        3%{?dist}
+Release:        4%{?dist}
 Summary:        Repodata downloading library
 
 License:        LGPLv2+
 URL:            https://github.com/rpm-software-management/librepo
 Source0:        %{url}/archive/%{version}/%{name}-%{version}.tar.gz
 Patch01:        180.patch
+# fixes failing build with Python 3.9, bz1788918
+Patch02:        179.patch
 
 BuildRequires:  cmake
 BuildRequires:  gcc
@@ -190,6 +192,9 @@ popd
 %endif
 
 %changelog
+* Mon Feb 10 2020 Ales Matej <amatej@fedoraproject.org> - 1.11.1-4
+- Fix calling Python API without holding GIL (RhBug:1788918)
+
 * Wed Feb 05 2020 Lukas Slebodnik <lslebodn@fedoraproject.org> - 1.11.1-3
 - Do not unref LrErr_Exception on exit (RhBug:1778854)