From ea59f869dcbd73b1d0dca973314604f689b50c34 Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Thu, 4 Jan 2024 16:18:00 -0500 Subject: [PATCH 1/2] hardwareprofile: remove external dependency on simplejson This uses the requests module and converts requests responses to json using requests' own `.json()` method on responses. For incomprehensible reasons, requests has spent about a decade using either simplejson or the standard library's json module more or less at will, and returning either one or the other exception types. They don't know why they use simplejson, we don't know why they use simplejson. In requests 3 (which will be released in the Year Of The Linux Desktop or when pigs fly, whichever one comes later) simplejson is dropped entirely. There are innumerable issues discussing the problem on the requests bugtracker, with the general consensus being that it's better to randomly return either one of two different libraries and two different library return types in errors -- because it was historically done that way and people might be depending on it. ?????? Bugs: https://github.com/psf/requests/pull/710 https://github.com/psf/requests/pull/2516 https://github.com/psf/requests/issues/3052 https://github.com/psf/requests/issues/4169 https://github.com/psf/requests/issues/4842 https://github.com/psf/requests/issues/5794 https://github.com/psf/requests/issues/6084 The awkward workaround is to guarantee that requests' silent behavior of using simplejson *if it is installed* is forcibly triggered by forcibly depending on simplejson, and then catching the simplejson exception. The better solution here is pretty simple: do not rely on the requests module's automatic json conversion, this is as simple as using the already-imported json module and calling json.loads() on the retrieved content. Fixes: 1df343e9ab7defa284a73390210a65cf2112f17e Reimplements: bb154a843b737cc3ad8c1a45fa04a1a3609aff05 (cherry picked from commit 6348dc01a45af6ed63c09326ec94cd425db1d6d7) --- mythtv/configure | 1 - mythtv/programs/scripts/hardwareprofile/smolt.py | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/mythtv/configure b/mythtv/configure index 7e966ef817..3429c208e2 100755 --- a/mythtv/configure +++ b/mythtv/configure @@ -6555,7 +6555,6 @@ if enabled bindings_python; then check_py_lib MySQLdb || disable_bindings_python "MySQLdb" check_py_lib lxml || disable_bindings_python "lxml" check_py_lib requests || disable_bindings_python "requests" - check_py_lib simplejson || disable_bindings_python "simplejson" check_py_lib future || disable_bindings_python "future" fi diff --git a/mythtv/programs/scripts/hardwareprofile/smolt.py b/mythtv/programs/scripts/hardwareprofile/smolt.py index 1bcc8060d0..464f068d6f 100644 --- a/mythtv/programs/scripts/hardwareprofile/smolt.py +++ b/mythtv/programs/scripts/hardwareprofile/smolt.py @@ -50,7 +50,6 @@ except ImportError: from urlparse import urlparse import json from json import JSONEncoder -from simplejson import errors as sje import datetime import logging @@ -790,8 +789,8 @@ class _HardwareProfile: sys.exit(1) try: - admin_obj = admin_token.json() - except sje.JSONDecodeError: + admin_obj = json.loads(admin_token.content) + except json.JSONDecodeError: self.session.close() error(_('Incorrect server response. Expected a JSON string')) return (1, None, None) -- 2.41.0 From 7c1dbe7a86dc9b445a1a491f5a849b0eba21aead Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Wed, 13 Dec 2023 23:11:11 -0500 Subject: [PATCH 2/2] hardwareprofile: remove ancient "future" compatibility library for python2 Ironically, for a package that was intended to provide portability between python2 and python3, it is broken with python 3.12. A better library to use in all cases is "six". However, mythtv requires python 3.8 for a while now. Using "future.standard_library" is a no-op other than costing a pointless import and being troublesome to actually install. The hacky copy of six.with_metaclass included in "future" is rewritten to use the pure python3 form of a metaclass. (cherry picked from commit 4a1ea331bb2b106e7ae7e7e9bb7970f71b8a84b3) --- mythtv/configure | 1 - .../scripts/hardwareprofile/MultipartPostHandler.py | 2 -- .../hardwareprofile/distros/mythtv_data/request.py | 2 -- .../scripts/hardwareprofile/distros/mythtv_data/uuiddb.py | 2 -- mythtv/programs/scripts/hardwareprofile/hwdata.py | 8 +++----- mythtv/programs/scripts/hardwareprofile/os_detect.py | 5 ++--- mythtv/programs/scripts/hardwareprofile/request.py | 2 -- mythtv/programs/scripts/hardwareprofile/scan.py | 2 -- mythtv/programs/scripts/hardwareprofile/uuiddb.py | 2 -- 9 files changed, 5 insertions(+), 21 deletions(-) diff --git a/mythtv/configure b/mythtv/configure index 3429c208e2..4bfbbd8c64 100755 --- a/mythtv/configure +++ b/mythtv/configure @@ -6555,7 +6555,6 @@ if enabled bindings_python; then check_py_lib MySQLdb || disable_bindings_python "MySQLdb" check_py_lib lxml || disable_bindings_python "lxml" check_py_lib requests || disable_bindings_python "requests" - check_py_lib future || disable_bindings_python "future" fi # Check for perl dependencies diff --git a/mythtv/programs/scripts/hardwareprofile/MultipartPostHandler.py b/mythtv/programs/scripts/hardwareprofile/MultipartPostHandler.py index 51619096b8..6ff2443d2e 100644 --- a/mythtv/programs/scripts/hardwareprofile/MultipartPostHandler.py +++ b/mythtv/programs/scripts/hardwareprofile/MultipartPostHandler.py @@ -41,8 +41,6 @@ Further Example: """ from __future__ import print_function -from future import standard_library -standard_library.install_aliases() from builtins import object from email.generator import _make_boundary import mimetypes diff --git a/mythtv/programs/scripts/hardwareprofile/distros/mythtv_data/request.py b/mythtv/programs/scripts/hardwareprofile/distros/mythtv_data/request.py index 2ae4fd3fdd..81362ba8b7 100644 --- a/mythtv/programs/scripts/hardwareprofile/distros/mythtv_data/request.py +++ b/mythtv/programs/scripts/hardwareprofile/distros/mythtv_data/request.py @@ -21,8 +21,6 @@ # providing the base url, user agent, and proxy information. # The object returned is slightly modified, with a shortcut to urlopen. -from future import standard_library -standard_library.install_aliases() from builtins import object import urllib.request, urllib.error, urllib.parse import urllib.parse diff --git a/mythtv/programs/scripts/hardwareprofile/distros/mythtv_data/uuiddb.py b/mythtv/programs/scripts/hardwareprofile/distros/mythtv_data/uuiddb.py index 6960f8705a..9d22556c04 100644 --- a/mythtv/programs/scripts/hardwareprofile/distros/mythtv_data/uuiddb.py +++ b/mythtv/programs/scripts/hardwareprofile/distros/mythtv_data/uuiddb.py @@ -16,8 +16,6 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. -from future import standard_library -standard_library.install_aliases() from builtins import map from builtins import str from builtins import object diff --git a/mythtv/programs/scripts/hardwareprofile/hwdata.py b/mythtv/programs/scripts/hardwareprofile/hwdata.py index ba297bf24f..0770d32b96 100644 --- a/mythtv/programs/scripts/hardwareprofile/hwdata.py +++ b/mythtv/programs/scripts/hardwareprofile/hwdata.py @@ -25,8 +25,6 @@ from __future__ import division from __future__ import absolute_import from builtins import int from builtins import open -from future import standard_library -standard_library.install_aliases() from builtins import object from smolt_config import get_config_attr @@ -71,9 +69,9 @@ class DeviceMap(object): pass else: raise Exception('Hardware data file not found. Please set the location HWDATA_DIR in config.py') - - - + + + vendors = {} curvendor = None curdevice = None diff --git a/mythtv/programs/scripts/hardwareprofile/os_detect.py b/mythtv/programs/scripts/hardwareprofile/os_detect.py index 7d0edee00e..beabf7d865 100644 --- a/mythtv/programs/scripts/hardwareprofile/os_detect.py +++ b/mythtv/programs/scripts/hardwareprofile/os_detect.py @@ -26,7 +26,6 @@ from __future__ import print_function from builtins import object import os -from future.utils import with_metaclass class OrderedType( type ): # provide global sequencing for OS class and subclasses to ensure @@ -37,7 +36,7 @@ class OrderedType( type ): mcs.nextorder += 1 return type.__new__(mcs, name, bases, attrs) -class OS( with_metaclass(OrderedType, object) ): +class OS(metaclass=OrderedType): _requires_func = True def __init__(self, ostype=-1, func=None, inst=None): if callable(ostype): @@ -189,7 +188,7 @@ class OSInfoType( type ): # fall through to Unknown return 'Unknown' -class get_os_info( with_metaclass(OSInfoType, object) ): +class get_os_info(metaclass=OSInfoType): @OS('nt') def windows(self): win_version = { diff --git a/mythtv/programs/scripts/hardwareprofile/request.py b/mythtv/programs/scripts/hardwareprofile/request.py index 6e6a20b9e7..d6668cef3d 100644 --- a/mythtv/programs/scripts/hardwareprofile/request.py +++ b/mythtv/programs/scripts/hardwareprofile/request.py @@ -21,8 +21,6 @@ # providing the base url, user agent, and proxy information. # The object returned is slightly modified, with a shortcut to urlopen. -from future import standard_library -standard_library.install_aliases() from builtins import object try: diff --git a/mythtv/programs/scripts/hardwareprofile/scan.py b/mythtv/programs/scripts/hardwareprofile/scan.py index 1389400ece..d100bfe692 100644 --- a/mythtv/programs/scripts/hardwareprofile/scan.py +++ b/mythtv/programs/scripts/hardwareprofile/scan.py @@ -18,8 +18,6 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. from __future__ import print_function -from future import standard_library -standard_library.install_aliases() import smolt import json diff --git a/mythtv/programs/scripts/hardwareprofile/uuiddb.py b/mythtv/programs/scripts/hardwareprofile/uuiddb.py index e7ba3891ec..3c2fc16d86 100644 --- a/mythtv/programs/scripts/hardwareprofile/uuiddb.py +++ b/mythtv/programs/scripts/hardwareprofile/uuiddb.py @@ -16,8 +16,6 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. -from future import standard_library -standard_library.install_aliases() from builtins import object import configparser import logging -- 2.41.0