Repository: yt-dlp/yt-dlp
File: yt_dlp/networking/common.py (Python)

Code before:
            if urllib.request._parse_proxy(proxy_url)[0] is None:
                raise UnsupportedRequest(f'Proxy "{proxy_url}" missing scheme')

            scheme = urllib.parse.urlparse(proxy_url).scheme.lower()
            if scheme not in self._SUPPORTED_PROXY_SCHEMES:
                raise UnsupportedRequest(f'Unsupported proxy type: "{scheme}"')

    def _check_extensions(self, extensions):
        """Check extensions for unsupported extensions. Subclasses should extend this."""
        assert isinstance(extensions.get('cookiejar'), (CookieJar, types.NoneType))
        assert isinstance(extensions.get('timeout'), (float, int, types.NoneType))

    @wrap_request_errors
    def validate(self, request: Request):
        if not isinstance(request, Request):
            raise TypeError('Expected an instance of Request')
        self._check_url_scheme(request)
        self._check_proxies(request.proxies or self.proxies)
        extensions = request.extensions.copy()
        self._check_extensions(extensions)
        if extensions:
            # TODO: add support for optional extensions
            raise UnsupportedRequest(f'Unsupported extensions: {", ".join(extensions.keys())}')

    @wrap_request_errors
    def send(self, request: Request) -> Response:
        if not isinstance(request, Request):
            raise TypeError('Expected an instance of Request')
        return self._send(request)

    @abc.abstractmethod
    def _send(self, request: Request):
        """Handle a request from start to finish. Redefine in subclasses."""

    def close(self):
        pass

    @classproperty
    def RH_NAME(cls):
        return cls.__name__[:-2]

    @classproperty
    def RH_KEY(cls):
        assert cls.__name__.endswith('RH'), 'RequestHandler class names must end with "RH"'
        return cls.__name__[:-2]

    def __enter__(self):
        return self

    def __exit__(self, *args):
        self.close()

Review comment (suggestion):
We need `_validate_` cause we don't want people overriding `validate()`, since we need `wrap_request_errors` to apply.

Code after:
            if urllib.request._parse_proxy(proxy_url)[0] is None:
                raise UnsupportedRequest(f'Proxy "{proxy_url}" missing scheme')

            scheme = urllib.parse.urlparse(proxy_url).scheme.lower()
            if scheme not in self._SUPPORTED_PROXY_SCHEMES:
                raise UnsupportedRequest(f'Unsupported proxy type: "{scheme}"')

    def _check_extensions(self, extensions):
        """Check extensions for unsupported extensions. Subclasses should extend this."""
        assert isinstance(extensions.get('cookiejar'), (CookieJar, NoneType))
        assert isinstance(extensions.get('timeout'), (float, int, NoneType))

    def _validate(self, request):
        self._check_url_scheme(request)
        self._check_proxies(request.proxies or self.proxies)
        extensions = request.extensions.copy()
        self._check_extensions(extensions)
        if extensions:
            # TODO: add support for optional extensions
            raise UnsupportedRequest(f'Unsupported extensions: {", ".join(extensions.keys())}')

    @wrap_request_errors
    def validate(self, request: Request):
        if not isinstance(request, Request):
            raise TypeError('Expected an instance of Request')
        self._validate(request)

    @wrap_request_errors
    def send(self, request: Request) -> Response:
        if not isinstance(request, Request):
            raise TypeError('Expected an instance of Request')
        return self._send(request)

    @abc.abstractmethod
    def _send(self, request: Request):
        """Handle a request from start to finish. Redefine in subclasses."""

    def close(self):
        pass

    @classproperty
    def RH_NAME(cls):
        return cls.__name__[:-2]

    @classproperty
    def RH_KEY(cls):
        assert cls.__name__.endswith('RH'), 'RequestHandler class names must end with "RH"'
        return cls.__name__[:-2]

    def __enter__(self):
        return self