d2l-ai/d2l-zh · error · AssertionError

只有zip/tar文件可以被解压缩

Error message

只有zip/tar文件可以被解压缩

What it means

AssertionError from d2l.mxnet.download_extract: after os.path.splitext on the downloaded filename, only '.zip' (ZipFile) and '.tar'/'.gz' (tarfile) extensions are supported; any other extension hits assert False with the Chinese message 'only zip/tar files can be extracted'. It is a format whitelist for the Kaggle-house style extraction helper.

Source

Thrown at d2l/mxnet.py:379

    print(f'正在从{url}下载{fname}...')
    r = requests.get(url, stream=True, verify=True)
    with open(fname, 'wb') as f:
        f.write(r.content)
    return fname

def download_extract(name, folder=None):
    """下载并解压zip/tar文件

    Defined in :numref:`sec_kaggle_house`"""
    fname = download(name)
    base_dir = os.path.dirname(fname)
    data_dir, ext = os.path.splitext(fname)
    if ext == '.zip':
        fp = zipfile.ZipFile(fname, 'r')
    elif ext in ('.tar', '.gz'):
        fp = tarfile.open(fname, 'r')
    else:
        assert False, '只有zip/tar文件可以被解压缩'
    fp.extractall(base_dir)
    return os.path.join(base_dir, folder) if folder else data_dir

def download_all():
    """下载DATA_HUB中的所有文件

    Defined in :numref:`sec_kaggle_house`"""
    for name in DATA_HUB:
        download(name)

DATA_HUB['kaggle_house_train'] = (
    DATA_URL + 'kaggle_house_pred_train.csv',
    '585e9cc93e70b39160e7921475f9bcd7d31219ce')

DATA_HUB['kaggle_house_test'] = (
    DATA_URL + 'kaggle_house_pred_test.csv',
    'fa19780a7b011d9b009e8bff8e99922a8ee2eb90')

View on GitHub (pinned to e6b18ccea7)

Solutions

  1. Package your data as .zip or .tar/.gz and update the DATA_HUB URL to match
  2. If the file is already uncompressed (csv/json), call d2l.download(name) directly instead of download_extract
  3. Rename a mislabeled archive (e.g. file with no extension -> file.zip) after confirming its real format with `file`
  4. For .tgz/.bz2, extend the check locally: `elif ext in ('.tar', '.gz', '.tgz', '.bz2')` or extract with tarfile.open(fname, 'r:*') yourself

Example fix

# before
DATA_HUB['mydata'] = (DATA_URL + 'mydata.csv', sha1)
d2l.download_extract('mydata')  # AssertionError: 只有zip/tar文件可以被解压缩
# after
DATA_HUB['mydata'] = (DATA_URL + 'mydata.zip', sha1_zip)
d2l.download_extract('mydata')  # or simply d2l.download('mydata') for the csv
Defensive patterns

Strategy: validation

Validate before calling

import os
name = 'mydata'
ext = os.path.splitext(d2l.DATA_HUB[name][0].split('/')[-1])[1]
if ext not in ('.zip', '.tar', '.gz'):
    raise ValueError(f'{name} is {ext}; download_extract supports zip/tar/gz only')
path = d2l.download_extract(name)

Type guard

def is_extractable(name: str, hub=d2l.DATA_HUB) -> bool:
    return os.path.splitext(hub[name][0].split('/')[-1])[1] in ('.zip', '.tar', '.gz')

Prevention

When it happens

Trigger: Registering a DATA_HUB entry whose URL ends in '.csv', '.json', '.txt', '.rar', or '.7z' and then calling download_extract on it; also '.tgz' or '.bz2' files, which the splitext check does not recognize even though tarfile could open them.

Common situations: Users reuse the kaggle-house boilerplate for their own dataset and forget the archive-format constraint; files whose true format is zip but named without the .zip extension; downloading raw '.gz' text files expecting auto-extraction of the inner file.

Related errors


AI-assisted analysis of d2l-ai/d2l-zh@e6b18ccea7 (2026-08-14). Data as JSON: /api/errors/be710764d383b8d0. Report an issue: GitHub.