#19 Add patch for compatibility with Python 3.13, workaround removed cgi stdlib module
Opened 3 months ago by thrnciar. Modified a month ago
rpms/ thrnciar/python-cherrypy python3.13  into  rawhide

file added
+147
@@ -0,0 +1,147 @@ 

+ From fe764cb1598cf87bf3826ac4ee9f98bda060278c Mon Sep 17 00:00:00 2001

+ From: Dan Radez <dradez@redhat.com>

+ Date: Tue, 9 Jan 2024 11:27:05 -0500

+ Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A7=20Stop=20using=20the=20`cgi`=20std?=

+  =?UTF-8?q?lib=20module?=

+ MIME-Version: 1.0

+ Content-Type: text/plain; charset=UTF-8

+ Content-Transfer-Encoding: 8bit

+ 

+ the module was deprecatied in py 3.11 and removed in py 3.13

+ there are examples of using the email module to resolve this:

+ PEP 594

+ https://github.com/python-babel/babel/issues/873

+ https://stackoverflow.com/questions/69068527/python-3-cgi-parse-header

+ 

+ This method doesn't seem to work for cherrypy.

+ The email.message module is trying to create a higher level

+ object that is intelligent about the headers it has defined. The

+ cgi.parse_header function is a very low level unintelligent function

+ that simply parses header content based on structure and does not

+ inspect the contents. Because of the intelligence of the email.message

+ object cherrypy can't use it in the very generic way that the

+ cgi.parse_header function was being used.

+ 

+ Fix #2014

+ ---

+  CHANGES.rst              |  6 ++++++

+  cherrypy/_cpcompat.py    | 37 +++++++++++++++++++++++++++++++++++++

+  cherrypy/lib/covercp.py  |  6 +++---

+  cherrypy/lib/httputil.py |  2 +-

+  pytest.ini               |  3 ---

+  5 files changed, 47 insertions(+), 7 deletions(-)

+ 

+ diff --git a/CHANGES.rst b/CHANGES.rst

+ index cad61837b..a5a433e21 100644

+ --- a/CHANGES.rst

+ +++ b/CHANGES.rst

+ @@ -1,3 +1,9 @@

+ +v(next)

+ +-------

+ +

+ +* Removed the use of :mod:`cgi` deprecated in Python 3.11

+ +  -- by :user:`radez`.

+ +

+  v18.9.0

+  -------

+  

+ diff --git a/cherrypy/_cpcompat.py b/cherrypy/_cpcompat.py

+ index a43f6d369..8f4a221a4 100644

+ --- a/cherrypy/_cpcompat.py

+ +++ b/cherrypy/_cpcompat.py

+ @@ -21,6 +21,43 @@

+  import http.client

+  

+  

+ +def _cgi_parseparam(s):

+ +    while s[:1] == ';':

+ +        s = s[1:]

+ +        end = s.find(';')

+ +        while end > 0 and (s.count('"', 0, end) - s.count('\\"', 0, end)) % 2:

+ +            end = s.find(';', end + 1)

+ +        if end < 0:

+ +            end = len(s)

+ +        f = s[:end]

+ +        yield f.strip()

+ +        s = s[end:]

+ +

+ +

+ +def cgi_parse_header(line):

+ +    """Parse a Content-type like header.

+ +

+ +    Return the main content-type and a dictionary of options.

+ +

+ +    Copied from removed stdlib cgi module. Couldn't find

+ +    something to replace it with that provided same functionality

+ +    from the email module as suggested.

+ +    """

+ +    parts = _cgi_parseparam(';' + line)

+ +    key = parts.__next__()

+ +    pdict = {}

+ +    for p in parts:

+ +        i = p.find('=')

+ +        if i >= 0:

+ +            name = p[:i].strip().lower()

+ +            value = p[i + 1:].strip()

+ +            if len(value) >= 2 and value[0] == value[-1] == '"':

+ +                value = value[1:-1]

+ +                value = value.replace('\\\\', '\\').replace('\\"', '"')

+ +            pdict[name] = value

+ +    return key, pdict

+ +

+ +

+  def ntob(n, encoding='ISO-8859-1'):

+      """Return the given native string as a byte string in the given

+      encoding.

+ diff --git a/cherrypy/lib/covercp.py b/cherrypy/lib/covercp.py

+ index 6c3871fc9..f22cce742 100644

+ --- a/cherrypy/lib/covercp.py

+ +++ b/cherrypy/lib/covercp.py

+ @@ -22,7 +22,7 @@

+  

+  import re

+  import sys

+ -import cgi

+ +import html

+  import os

+  import os.path

+  import urllib.parse

+ @@ -352,9 +352,9 @@ def annotated_file(self, filename, statements, excluded, missing):

+                  buffer.append((lineno, line))

+              if empty_the_buffer:

+                  for lno, pastline in buffer:

+ -                    yield template % (lno, cgi.escape(pastline))

+ +                    yield template % (lno, html.escape(pastline))

+                  buffer = []

+ -                yield template % (lineno, cgi.escape(line))

+ +                yield template % (lineno, html.escape(line))

+  

+      @cherrypy.expose

+      def report(self, name):

+ diff --git a/cherrypy/lib/httputil.py b/cherrypy/lib/httputil.py

+ index 62bc1bd04..e72bbf8e7 100644

+ --- a/cherrypy/lib/httputil.py

+ +++ b/cherrypy/lib/httputil.py

+ @@ -12,7 +12,7 @@

+  import re

+  import builtins

+  from binascii import b2a_base64

+ -from cgi import parse_header

+ +from cherrypy._cpcompat import cgi_parse_header as parse_header

+  from email.header import decode_header

+  from http.server import BaseHTTPRequestHandler

+  from urllib.parse import unquote_plus

+ diff --git a/pytest.ini b/pytest.ini

+ index 53e18e200..bcecc9bd5 100644

+ --- a/pytest.ini

+ +++ b/pytest.ini

+ @@ -59,9 +59,6 @@ filterwarnings =

+    ignore:the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses:DeprecationWarning

+    ignore:the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses:PendingDeprecationWarning

+  

+ -  # TODO: Replace the use of `cgi`. It seems untrivial.

+ -  ignore:'cgi' is deprecated and slated for removal in Python 3.13:DeprecationWarning

+ -

+    # TODO: Remove once `cheroot.webtest._open_url_once` is fixed to release

+    # TODO: connection properly.

+    ignore:unclosed <socket.socket fd=:ResourceWarning

file modified
+9 -1
@@ -10,7 +10,7 @@ 

  Name:           python-cherrypy

  %global         camelname CherryPy

  Version:        18.9.0

- Release:        4%{?dist}

+ Release:        5%{?dist}

  Summary:        Pythonic, object-oriented web development framework

  License:        BSD

  URL:            https://cherrypy.dev/
@@ -31,6 +31,10 @@ 

  # github pr https://github.com/cherrypy/cherrypy/pull/2007

  Patch4:         0001-Replace-deprecated-utcnow-datetime-function.patch

  

+ # Compatibility with Python 3.13

+ # Workaround removed cgi stdlib module

+ Patch5:         https://github.com/cherrypy/cherrypy/pull/2021.patch

+ 

  BuildArch:      noarch

  

  BuildRequires:  python3-devel
@@ -106,6 +110,10 @@ 

  %{python3_sitelib}/cherrypy/tutorial

  

  %changelog

+ * Thu Feb 22 2024 Tomáš Hrnčiar <thrnciar@redhat.com> - 18.9.0-5

+ - Add patch for compatibility with Python 3.13, workaround removed cgi stdlib module

+ - Fixes: rhbz#2256924

+ 

  * Fri Jan 26 2024 Fedora Release Engineering <releng@fedoraproject.org> - 18.9.0-4

  - Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild

  

no initial comment

rebased onto b694860

3 months ago

Build succeeded.
https://fedora.softwarefactory-project.io/zuul/buildset/bee621ef54d54a03b967b6792d57f543

This fixes the issue.

Upstream says:

Dan was going to add some regression tests for the change, which is what the PR is waiting for.

So perhaps we wait as well? There is no rush to get this merged, we can use this PR to build from in 3.13 copr.

I've pushed up an initial draft of some tests upstream.
Just a quick update to let everyone know we have some progress forward here.

I expect to iterate a couple times on them, then we can get this merged in.

Metadata