diff options
author | dirkf <fieldhouse@gmx.net> | 2024-01-20 18:28:52 +0000 |
---|---|---|
committer | dirkf <fieldhouse@gmx.net> | 2024-01-22 11:10:34 +0000 |
commit | 66518714169185195a359e173cef73fba31d76b8 (patch) | |
tree | d617f6a28fa9b579ff9e85bbd520127ca1fdac58 | |
parent | be008e657d79832642e2158557c899249c9e31cd (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.py | 14 | ||||
-rw-r--r-- | youtube_dl/compat.py | 27 |
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 |