{"record":{"id":"9ecde8ad691b458e","repo":"d2l-ai/d2l-zh","slug":"only-zip-tar-files-can-be-extracted","errorCode":null,"errorMessage":"Only zip/tar files can be extracted","messagePattern":"Only zip/tar files can be extracted","errorType":"validation","errorClass":"AssertionError","httpStatus":null,"severity":"error","filePath":"contrib/to-rm-mx-contrib-text/d2lzh/text/embedding.py","lineNumber":41,"sourceCode":"    if not os.path.exists(path):\n        os.makedirs(path)\n\ndef download(embedding_name, pretrained_file_name, cache_dir=os.path.join('..', 'data')):\n    url, sha1 = PRETRAINED_FILE[embedding_name][pretrained_file_name]\n    mkdir_if_not_exist(cache_dir)\n    return gluon.utils.download(url, cache_dir, sha1_hash=sha1)\n\ndef download_extract(embedding_name, pretrained_file_name, folder=None):\n    \"\"\"Download and extract a zip/tar file.\"\"\"\n    fname = download(embedding_name, pretrained_file_name)\n    base_dir = os.path.dirname(fname) \n    data_dir, ext = os.path.splitext(fname)\n    if ext == '.zip':\n        fp = zipfile.ZipFile(fname, 'r')\n    elif ext in ('.tar', '.gz'):\n        fp = tarfile.open(fname, 'r')\n    else:\n        assert False, 'Only zip/tar files can be extracted'\n    fp.extractall(base_dir)\n    if folder:\n        return os.path.join(base_dir, folder)\n    else:\n        return data_dir\n    \ndef get_pretrained_file_names(embedding_name=None):\n    if embedding_name is not None:\n        return PRETRAINED_FILE[embedding_name].keys()\n    else:\n        return PRETRAINED_FILE\n    \ndef create(embedding_name, pretrained_file_name, vocabulary=None):\n    return TokenEmbedding(embedding_name, pretrained_file_name.lower(), vocabulary)\n    \nclass TokenEmbedding:\n    \"\"\"Token Embedding.\"\"\"\n    def __init__(self, embedding_name, pretrained_file_name, vocabulary=None):","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/d2l-ai/d2l-zh/blob/e6b18ccea71451a55fcd861d7b96fddf2587b09a/contrib/to-rm-mx-contrib-text/d2lzh/text/embedding.py#L23-L59","documentation":"download_extract in contrib/to-rm-mx-contrib-text/d2lzh/text/embedding.py downloads a pretrained-embedding file with gluon.utils.download and then dispatches on its extension: '.zip' opens a ZipFile, '.tar'/'.gz' open a tarfile. Any other extension hits assert False, 'Only zip/tar files can be extracted' — the helper has no code path for non-archive files. It fires when the requested pretrained file, after download, is not one of the archive formats the function knows how to extract.","triggerScenarios":"Calling download_extract(embedding_name, pretrained_file_name) where PRETRAINED_FILE[embedding_name] maps to a plain (non-archive) file such as a '.bin', '.vec', '.txt', or '.npy' embedding; or passing a custom pretrained_file_name whose extension is not .zip/.tar/.gz. Also triggered by case-sensitivity mistakes ('.ZIP', '.TAR') since os.path.splitext comparison is exact, and by compound extensions like '.tar.bz2' (ext is '.bz2', not in the allowed set).","commonSituations":"Trying to load fastText/GloVe/word2vec files shipped as raw binaries or text instead of zips; adding a new embedding to PRETRAINED_FILE without checking how the file is actually packaged; renaming or re-hosting a pretrained file so its extension changes; older d2lzh versions whose extension list ('.tar', '.gz') misses formats like .bz2/.xz that newer archives use; typos or uppercase extensions in the file name map.","solutions":["Check the actual downloaded file's extension with os.path.splitext; if it is a raw embedding file (.vec/.txt/.bin/.npy), do not call download_extract — use download() and consume the file directly, since there is nothing to extract.","If the archive uses a format the branch misses (e.g. '.tar.bz2', '.tgz', '.ZIP'), normalize the check: use fname.lower() and cover '.zip', '.tar', '.gz', '.tgz', '.bz2', '.xz' with the matching tarfile.open mode ('r:*' handles all tar variants).","If you control PRETRAINED_FILE, point the entry at a .zip or .tar/.gz archive of the embedding so download_extract's contract is satisfied.","Verify the download actually succeeded and is not an HTML error page saved under a wrong name (gluon.utils.download without a matching sha1_hash can save a redirect page whose extension still trips the assert).","Prefer the newer d2l package's token-embedding APIs over the legacy contrib/to-rm-mx-contrib-text module if you are not bound to old Gluon code."],"exampleFix":"# before\nfname = download(embedding_name, pretrained_file_name)\ndata_dir, ext = os.path.splitext(fname)\nif ext == '.zip':\n    fp = zipfile.ZipFile(fname, 'r')\nelif ext in ('.tar', '.gz'):\n    fp = tarfile.open(fname, 'r')\nelse:\n    assert False, 'Only zip/tar files can be extracted'\n\n# after (tolerant extension handling, tarfile 'r:*' auto-detects compression)\nfname = download(embedding_name, pretrained_file_name)\ndata_dir, ext = os.path.splitext(fname)\next = ext.lower()\nif ext == '.zip':\n    fp = zipfile.ZipFile(fname, 'r')\nelif ext in ('.tar', '.gz', '.tgz', '.bz2', '.xz'):\n    fp = tarfile.open(fname, 'r:*')\nelse:\n    raise ValueError(f'Nothing to extract for non-archive file {fname}; use download() directly')\nfp.extractall(os.path.dirname(fname))","handlingStrategy":"validation","validationCode":"import os\n\nEXTRACTABLE = {'.zip', '.tar', '.gz', '.tgz', '.bz2', '.xz'}\n\nfname = download(embedding_name, pretrained_file_name)\n_, ext = os.path.splitext(fname)\nif ext.lower() not in EXTRACTABLE:\n    # raw embedding file: nothing to extract, consume it directly\n    embedding_path = fname\nelse:\n    embedding_path = download_extract(embedding_name, pretrained_file_name)","typeGuard":"def is_extractable_archive(path) -> bool:\n    _, ext = os.path.splitext(path)\n    return ext.lower() in ('.zip', '.tar', '.gz', '.tgz', '.bz2', '.xz')\n\n# usage\nfname = download(embedding_name, pretrained_file_name)\nif not is_extractable_archive(fname):\n    raise ValueError(f'{fname} is a raw file; call download() and skip extraction')","tryCatchPattern":"try:\n    out_dir = download_extract(embedding_name, pretrained_file_name)\nexcept AssertionError as e:\n    fname = download(embedding_name, pretrained_file_name)\n    raise RuntimeError(\n        f'download_extract cannot handle {os.path.splitext(fname)[1]!r}; '\n        f'if it is a raw embedding file, use download() and read it directly') from e","preventionTips":["Before calling download_extract, inspect the extension of the filename registered in PRETRAINED_FILE and confirm it is an archive the function supports.","When registering new embeddings, prefer shipping them as .zip or .tar/.gz archives, matching what download_extract expects.","Normalize extensions with ext.lower() so '.ZIP' or '.TAR' entries do not fall into the assert branch.","Use tarfile.open(fname, 'r:*') when you control the code — it auto-detects gz/bz2/xz compression and removes most extension dispatch.","Verify downloads with the sha1_hash argument of gluon.utils.download so a corrupted or redirect-page file is caught before extension dispatch."],"tags":["file-format","download","pretrained-embeddings","assertion","mxnet-gluon"],"backgroundTag":null,"analyzedSha":"e6b18ccea71451a55fcd861d7b96fddf2587b09a","analyzedAt":"2026-08-14T20:05:26.414Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}