Потокобезопасное исправление обезьяны - PullRequest
0 голосов
/ 27 мая 2019

В нашем приложении Django есть большие блоки кода, где мы хотим, чтобы исключение было вызвано, если значение, извлеченное из базы данных, равно None.

Конечно, мы могли бы написать собственный аксессор для этого поведения, но для того, чтобы эти блоки кода были простыми, мы залатали обезьяны Model:

def raise_error_on_none_model_values(func):
    @wraps(func)
    def wrapped(*args, **kwargs):
        # execute function if already patched
        already_patched = (
            Model.__getattribute__ == _getattribute_raising_if_value_is_none
        )
        if already_patched:
            return func(*args, **kwargs)

        # patch
        Model.__getattribute__ = _getattribute_raising_if_value_is_none

        # execute function
        try:
            return func(**kwargs)
        finally:
            del Model.__getattribute__

    return wrapped

Тем не менее, мы (конечно!) Сталкиваемся с проблемами при использовании многопоточности.

Я исследовал, могут ли помочь такие библиотеки, как wrapt или gevent, но я не уверен, могут ли они помочь.

Можно ли сделать потокобезопасный патч обезьяны? Есть ли лучший способ достичь того, что мы хотим сделать?

...