aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordirkf <fieldhouse@gmx.net>2024-01-20 18:28:52 +0000
committerdirkf <fieldhouse@gmx.net>2024-01-22 11:10:34 +0000
commit66518714169185195a359e173cef73fba31d76b8 (patch)
treed617f6a28fa9b579ff9e85bbd520127ca1fdac58
parentbe008e657d79832642e2158557c899249c9e31cd (diff)
[compat] Rework compat for `method` parameter of `compat_urllib_request.Request` constructor
* fixes #32573 * does not break `utils.HEADrequest` (eg)
-rw-r--r--test/test_compat.py14
-rw-r--r--youtube_dl/compat.py27
2 files changed, 31 insertions, 10 deletions
diff --git a/test/test_compat.py b/test/test_compat.py
index e233b1ae1..b83c8cb41 100644
--- a/test/test_compat.py
+++ b/test/test_compat.py
@@ -23,6 +23,7 @@ from youtube_dl.compat import (
compat_urllib_parse_unquote,
compat_urllib_parse_unquote_plus,
compat_urllib_parse_urlencode,
+ compat_urllib_request,
)
@@ -135,6 +136,19 @@ class TestCompat(unittest.TestCase):
self.assertEqual(compat_casefold('\u03a3'), '\u03c3')
self.assertEqual(compat_casefold('A\u0345\u03a3'), 'a\u03b9\u03c3')
+ def test_compat_urllib_request_Request(self):
+ self.assertEqual(
+ compat_urllib_request.Request('http://127.0.0.1', method='PUT').get_method(),
+ 'PUT')
+
+ class PUTrequest(compat_urllib_request.Request):
+ def get_method(self):
+ return 'PUT'
+
+ self.assertEqual(
+ PUTrequest('http://127.0.0.1').get_method(),
+ 'PUT')
+
if __name__ == '__main__':
unittest.main()
diff --git a/youtube_dl/compat.py b/youtube_dl/compat.py
index 3c526a78d..818ccebd0 100644
--- a/youtube_dl/compat.py
+++ b/youtube_dl/compat.py
@@ -58,19 +58,26 @@ except ImportError: # Python 2
# Also fix up lack of method arg in old Pythons
try:
- _req = compat_urllib_request.Request
- _req('http://127.0.0.1', method='GET')
+ type(compat_urllib_request.Request('http://127.0.0.1', method='GET'))
except TypeError:
- class _request(object):
- def __new__(cls, url, *args, **kwargs):
- method = kwargs.pop('method', None)
- r = _req(url, *args, **kwargs)
- if method:
- r.get_method = types.MethodType(lambda _: method, r)
- return r
+ def _add_init_method_arg(cls):
- compat_urllib_request.Request = _request
+ init = cls.__init__
+ def wrapped_init(self, *args, **kwargs):
+ method = kwargs.pop('method', 'GET')
+ init(self, *args, **kwargs)
+ if any(callable(x.__dict__.get('get_method')) for x in (self.__class__, self) if x != cls):
+ # allow instance or its subclass to override get_method()
+ return
+ if self.has_data() and method == 'GET':
+ method = 'POST'
+ self.get_method = types.MethodType(lambda _: method, self)
+
+ cls.__init__ = wrapped_init
+
+ _add_init_method_arg(compat_urllib_request.Request)
+ del _add_init_method_arg
try:
import urllib.error as compat_urllib_error