| 774 | self.manager.dispatch.expire(self, None) |
| 775 | |
| 776 | def _expire_attributes( |
| 777 | self, |
| 778 | dict_: _InstanceDict, |
| 779 | attribute_names: Iterable[str], |
| 780 | no_loader: bool = False, |
| 781 | ) -> None: |
| 782 | pending = self.__dict__.get("_pending_mutations", None) |
| 783 | |
| 784 | callables = self.callables |
| 785 | |
| 786 | for key in attribute_names: |
| 787 | impl = self.manager[key].impl |
| 788 | if impl.accepts_scalar_loader: |
| 789 | if no_loader and (impl.callable_ or key in callables): |
| 790 | continue |
| 791 | |
| 792 | self.expired_attributes.add(key) |
| 793 | if callables and key in callables: |
| 794 | del callables[key] |
| 795 | old = dict_.pop(key, NO_VALUE) |
| 796 | if is_collection_impl(impl) and old is not NO_VALUE: |
| 797 | impl._invalidate_collection(old) |
| 798 | |
| 799 | lkv = self._last_known_values |
| 800 | if lkv is not None and key in lkv and old is not NO_VALUE: |
| 801 | lkv[key] = old |
| 802 | |
| 803 | self.committed_state.pop(key, None) |
| 804 | if pending: |
| 805 | pending.pop(key, None) |
| 806 | |
| 807 | self.manager.dispatch.expire(self, attribute_names) |
| 808 | |
| 809 | def _load_expired( |
| 810 | self, state: InstanceState[_O], passive: PassiveFlag |