see read_array_header_1_0
(fp, version, max_header_size=_MAX_HEADER_SIZE)
| 585 | |
| 586 | |
| 587 | def _read_array_header(fp, version, max_header_size=_MAX_HEADER_SIZE): |
| 588 | """ |
| 589 | see read_array_header_1_0 |
| 590 | """ |
| 591 | # Read an unsigned, little-endian short int which has the length of the |
| 592 | # header. |
| 593 | import struct |
| 594 | hinfo = _header_size_info.get(version) |
| 595 | if hinfo is None: |
| 596 | raise ValueError("Invalid version {!r}".format(version)) |
| 597 | hlength_type, encoding = hinfo |
| 598 | |
| 599 | hlength_str = _read_bytes(fp, struct.calcsize(hlength_type), "array header length") |
| 600 | header_length = struct.unpack(hlength_type, hlength_str)[0] |
| 601 | header = _read_bytes(fp, header_length, "array header") |
| 602 | header = header.decode(encoding) |
| 603 | if len(header) > max_header_size: |
| 604 | raise ValueError( |
| 605 | f"Header info length ({len(header)}) is large and may not be safe " |
| 606 | "to load securely.\n" |
| 607 | "To allow loading, adjust `max_header_size` or fully trust " |
| 608 | "the `.npy` file using `allow_pickle=True`.\n" |
| 609 | "For safety against large resource use or crashes, sandboxing " |
| 610 | "may be necessary.") |
| 611 | |
| 612 | # The header is a pretty-printed string representation of a literal |
| 613 | # Python dictionary with trailing newlines padded to a ARRAY_ALIGN byte |
| 614 | # boundary. The keys are strings. |
| 615 | # "shape" : tuple of int |
| 616 | # "fortran_order" : bool |
| 617 | # "descr" : dtype.descr |
| 618 | # Versions (2, 0) and (1, 0) could have been created by a Python 2 |
| 619 | # implementation before header filtering was implemented. |
| 620 | # |
| 621 | # For performance reasons, we try without _filter_header first though |
| 622 | try: |
| 623 | d = safe_eval(header) |
| 624 | except SyntaxError as e: |
| 625 | if version <= (2, 0): |
| 626 | header = _filter_header(header) |
| 627 | try: |
| 628 | d = safe_eval(header) |
| 629 | except SyntaxError as e2: |
| 630 | msg = "Cannot parse header: {!r}" |
| 631 | raise ValueError(msg.format(header)) from e2 |
| 632 | else: |
| 633 | warnings.warn( |
| 634 | "Reading `.npy` or `.npz` file required additional " |
| 635 | "header parsing as it was created on Python 2. Save the " |
| 636 | "file again to speed up loading and avoid this warning.", |
| 637 | UserWarning, stacklevel=4) |
| 638 | else: |
| 639 | msg = "Cannot parse header: {!r}" |
| 640 | raise ValueError(msg.format(header)) from e |
| 641 | if not isinstance(d, dict): |
| 642 | msg = "Header is not a dictionary: {!r}" |
| 643 | raise ValueError(msg.format(d)) |
| 644 |
no test coverage detected