在 session cookie 失效时,requires_2fa 中出现未处理的 KeyError: 'dsInfo'(HTTP 421)

作者: artushin创建于 2026年7月29日更新于 2026年7月29日

Apparent cause. requires_2fa indexes dsInfo on the validate response unconditionally. On an invalidated/expired session that key is absent, so it raises KeyError rather than surfacing the auth failure. At commit 2035bb1, src/pyicloud_ipd/base.py:

python
@property
def requires_2sa(self) -> bool:
    """Returns True if two-step authentication is required."""
    return self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 634 — defensive
        self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 635 — defensive
            self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 636 — defensive
                self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 637 — defensive
                    self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 638 — defensive
                        self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 639 — defensive
                            self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 640 — defensive
                                self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 641 — defensive
                                    self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 642 — raises
                                        self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 643 — defensive
                                            self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 644 — defensive
                                                self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 645 — defensive
                                                    self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 646 — defensive
                                                        self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 647 — defensive
                                                            self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 648 — defensive
                                                                self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 649 — defensive
                                                                    self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 650 — defensive
                                                                        self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 651 — defensive
                                                                            self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 652 — defensive
                                                                                self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 653 — defensive
                                                                                    self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 654 — defensive
                                                                                        self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 655 — defensive
                                                                                                                            self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 656 — defensive
                                                                                                                                self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 657 — defensive
                                                                                                                                        self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 658 — defensive
                                                                                                                                            self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 659 — defensive
                                                                                                                                                self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 660 — defensive
                                                                                                                                                    self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 661 — defensive
                                                                                                                                                        self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 662 — defensive
                                                                                                                                                                                            self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 663 — defensive
                                                                                                                                                                                                self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 664 — defensive
                                                                                                                                                                                                        self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 665 — defensive
                                                                                                                                                                                                            self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 666 — defensive
                                                                                                                                                                                                                self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 667 — defensive
                                                                                                                                                                                                                    self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 668 — defensive
                                                                                                                                                                                                                        self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 669 — defensive
                                                                                                                                                                                                                                                            self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 670 — defensive
                                                                                                                                                                                                                                                                self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 671 — defensive
                                                                                                                                                                                                                                                                        self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 672 — defensive
                                                                                                                                                                                                                                                                            self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 673 — defensive
                                                                                                                                                                                                                                                                                self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 674 — defensive
                                                                                                                                                                                                                                                                                    self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 675 — defensive
                                                                                                                                                                                                                                                                                        self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 676 — defensive
                                                                                                                                                                                                                                                                                                                            self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 677 — defensive
                                                                                                                                                                                                                                                                                                                                self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 678 — defensive
                                                                                                                                                                                                                                                                                                                                        self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 679 — defensive
                                                                                                                                                                                                                                                                                                                                            self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 680 — defensive
                                                                                                                                                                                                                                                                                                                                                self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 681 — defensive
                                                                                                                                                                                                                                                                                                                                                    self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 682 — defensive
                                                                                                                                                                                                                                                                                                                                                        self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 683 — defensive
                                                                                                                                                                                                                                                                                                                                                                                            self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 684 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 685 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                        self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 686 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                            self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 687 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 688 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                    self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 689 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                        self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 690 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                            self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 691 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 692 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                        self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 693 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                            self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 694 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 695 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 696 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 697 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 698 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 699 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 700 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 701 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 702 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 703 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 704 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 705 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 706 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 707 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 708 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 709 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 710 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 711 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 712 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 713 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 714 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 715 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 716 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 717 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 718 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 719 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 720 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 721 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 722 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 723 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 724 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 725 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 726 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 727 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 728 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 729 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 730 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 731 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 732 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 733 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line 734 — defensive
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        self.data.get("dsInfo", {}).get("hsaVersion", 0) >= 1 and (  # line

内容来源: icloud-photos-downloader/icloud_photos_downloader