# Buggy code
def _download_dir(self, from_info, to_info, name, no_progress_bar, file_mode, dir_mode):
    from_infos = list(self.walk_files(from_info))
    to_infos = (to_info / info.relative_to(from_info) for info in from_infos)

    with Tqdm(
        total=len(from_infos),
        desc="Downloading directory",
        unit="Files",
        disable=no_progress_bar,
    ) as pbar:
        download_files = pbar.wrap_fn(
            partial(
                self._download_file,
                name=name,
                no_progress_bar=True,
                file_mode=file_mode,
                dir_mode=dir_mode,
            )
        )
        with ThreadPoolExecutor(max_workers=self.remote.JOBS) as executor:
            futures = executor.map(download_files, from_infos, to_infos)
            return sum(futures)


# Traceback (AttributeError)
Traceback (most recent call last):
File "d:\miniconda3\lib\site-packages\dvc\main.py", line 49, in main
ret = cmd.run()
File "d:\miniconda3\lib\site-packages\dvc\command\get_url.py", line 17, in run
Repo.get_url(self.args.url, out=self.args.out)
File "d:\miniconda3\lib\site-packages\dvc\repo\get_url.py", line 17, in get_url
(dep,) = dependency.loads_from(None, [url])
File "d:\miniconda3\lib\site-packages\dvc\dependency\__init__.py", line 83, in loads_from
ret.append(_get(stage, s, info))
File "d:\miniconda3\lib\site-packages\dvc\dependency\__init__.py", line 68, in _get
return LocalDependency(stage, p, info)
File "d:\miniconda3\lib\site-packages\dvc\output\local.py", line 25, in __init__
super().__init__(stage, path, *args, **kwargs)
File "d:\miniconda3\lib\site-packages\dvc\output\base.py", line 98, in __init__
self.path_info = self._parse_path(remote, path)
File "d:\miniconda3\lib\site-packages\dvc\output\local.py", line 40, in _parse_path
p = self.stage.wdir / p
AttributeError: 'NoneType' object has no attribute 'wdir'

# Fixed code
def _download_dir(self, from_info, to_info, name, no_progress_bar, file_mode, dir_mode):
    from_infos = list(self.walk_files(from_info))
    to_infos = (to_info / info.relative_to(from_info) for info in from_infos)

    with Tqdm(
        total=len(from_infos),
        desc="Downloading directory",
        unit="Files",
        disable=no_progress_bar,
    ) as pbar:
        download_files = pbar.wrap_fn(
            partial(
                self._download_file,
                name=name,
                no_progress_bar=True,
                file_mode=file_mode,
                dir_mode=dir_mode,
            )
        )
        with ThreadPoolExecutor(max_workers=self.remote.JOBS) as executor:
            futures = [
                executor.submit(download_files, from_info, to_info)
                for from_info, to_info in zip(from_infos, to_infos)
            ]

            # NOTE: unlike pulling/fetching cache, where we need to
            # download everything we can, not raising an error here might
            # turn very ugly, as the user might think that he has
            # downloaded a complete directory, while having a partial one,
            # which might cause unexpected results in his pipeline.
            for future in as_completed(futures):
                # NOTE: executor won't let us raise until all futures that
                # it has are finished, so we need to cancel them ourselves
                # before re-raising.
                exc = future.exception()
                if exc:
                    for entry in futures:
                        entry.cancel()
                    raise exc