Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/vk.py (Python)

Code before:
    clean_html,
    ExtractorError,
    get_element_by_class,
    int_or_none,
    orderedSet,
    str_or_none,
    str_to_int,
    update_url_query,
    unescapeHTML,
    unified_timestamp,
    url_or_none,
    urlencode_postdata,
)
from .dailymotion import DailymotionIE
from .odnoklassniki import OdnoklassnikiIE
from .pladform import PladformIE
from .vimeo import VimeoIE
from .youtube import YoutubeIE


class VKBaseIE(InfoExtractor):
    _NETRC_MACHINE = 'vk'
    _WAF_URI = 'https://vk.com/429.html?'

    def _download_webpage_handle(self, *args, **kwargs):
        content, urlh = super(VKBaseIE, self)._download_webpage_handle(
            *args, **kwargs)
        challenge_url = urlh.geturl()
        if challenge_url.startswith(self._WAF_URI):
            cookie = self._get_cookies(challenge_url).get('hash429')
            if cookie:
                hash429 = hashlib.md5(cookie.value.encode('ascii')).hexdigest()
                resolve_url = update_url_query(challenge_url, {'key': hash429})
                self._request_webpage(
                    resolve_url, None,
                    note='Resolving WAF challenge for VK',
                    errnote='Failed bypass WAF challenge for VK')
                return self._download_webpage_handle(*args, **kwargs)
        return (content, urlh)

    def _perform_login(self, username, password):
        login_page, url_handle = self._download_webpage_handle(
            'https://vk.com', None, 'Downloading login page')

        login_form = self._hidden_inputs(login_page)

        login_form.update({
            'email': username.encode('cp1251'),
            'pass': password.encode('cp1251'),
        })


Review comment (suggestion):
```suggestion
        content, urlh = super()._download_webpage_handle(
```
It can also return `False`. Handle that case

Code after:
from .pladform import PladformIE
from .vimeo import VimeoIE
from .youtube import YoutubeIE
from ..compat import compat_urlparse
from ..utils import (
    ExtractorError,
    clean_html,
    get_element_by_class,
    int_or_none,
    orderedSet,
    str_or_none,
    str_to_int,
    unescapeHTML,
    unified_timestamp,
    update_url_query,
    url_or_none,
    urlencode_postdata,
)


class VKBaseIE(InfoExtractor):
    _NETRC_MACHINE = 'vk'

    def _download_webpage_handle(self, url_or_request, video_id, *args, fatal=True, **kwargs):
        response = super()._download_webpage_handle(url_or_request, video_id, *args, fatal=fatal, **kwargs)
        challenge_url, cookie = response[1].geturl() if response else '', None
        if challenge_url.startswith('https://vk.com/429.html?'):
            cookie = self._get_cookies(challenge_url).get('hash429')
        if not cookie:
            return response

        hash429 = hashlib.md5(cookie.value.encode('ascii')).hexdigest()
        self._request_webpage(
            update_url_query(challenge_url, {'key': hash429}), video_id, fatal=fatal,
            note='Resolving WAF challenge', errnote='Failed to bypass WAF challenge')
        return super()._download_webpage_handle(url_or_request, video_id, *args, fatal=True, **kwargs)

    def _perform_login(self, username, password):
        login_page, url_handle = self._download_webpage_handle(
            'https://vk.com', None, 'Downloading login page')

        login_form = self._hidden_inputs(login_page)

        login_form.update({
            'email': username.encode('cp1251'),
            'pass': password.encode('cp1251'),
        })

        # vk serves two same remixlhk cookies in Set-Cookie header and expects
        # first one to be actually set
        self._apply_first_set_cookie_header(url_handle, 'remixlhk')