| |
@@ -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
|
| |