Skip to content

Commit

Permalink
Add context manager to handle temporary unfreezing of `frozen_after_i…
Browse files Browse the repository at this point in the history
…nit` objects

# Rust tests and lints will be skipped. Delete if not intended.
[ci skip-rust]

# Building wheels and fs_util will be skipped. Delete if not intended.
[ci skip-build-wheels]
  • Loading branch information
Christopher Neugebauer committed Sep 14, 2022
1 parent 660e300 commit a6190ec
Showing 1 changed file with 12 additions and 1 deletion.
13 changes: 12 additions & 1 deletion src/python/pants/util/meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
# Licensed under the Apache License, Version 2.0 (see LICENSE).

from abc import ABC, abstractmethod
from contextlib import contextmanager
from dataclasses import FrozenInstanceError as FrozenInstanceError
from functools import wraps
from typing import Any, Callable, Optional, Type, TypeVar, Union
from typing import Any, Callable, Iterator, Optional, Type, TypeVar, Union

T = TypeVar("T")
C = TypeVar("C", bound=Type)
Expand Down Expand Up @@ -125,6 +126,15 @@ def freeze_instance(self) -> None:
def unfreeze_instance(self) -> None:
self._is_frozen = False

@contextmanager
def unfrozen(self) -> Iterator:
old_is_frozen = self._is_frozen
try:
self._is_frozen = False
yield
finally:
self._is_frozen = old_is_frozen

@wraps(prev_init)
def new_init(self, *args: Any, **kwargs: Any) -> None:
prev_init(self, *args, **kwargs)
Expand All @@ -140,6 +150,7 @@ def new_setattr(self, key: str, value: Any) -> None:

cls._freeze_instance = freeze_instance
cls._unfreeze_instance = unfreeze_instance
cls._unfrozen = unfrozen
cls.__init__ = new_init
cls.__setattr__ = new_setattr # type: ignore[assignment]

Expand Down

0 comments on commit a6190ec

Please sign in to comment.