diff options
| -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 | 
