Commit 3c2da22f authored by Samuel GAIST's avatar Samuel GAIST

[decorators] Moved frozen decorator out of utils

And added test for it.
parent 69d7560b
#!/usr/bin/env python
# -*- coding: utf-8 -*-
###############################################################################
# #
# Copyright (c) 2016 Idiap Research Institute, http://www.idiap.ch/ #
# Contact: beat.support@idiap.ch #
# #
# This file is part of the beat.editor module of the BEAT platform. #
# #
# Commercial License Usage #
# Licensees holding valid commercial BEAT licenses may use this file in #
# accordance with the terms contained in a written agreement between you #
# and Idiap. For further information contact tto@idiap.ch #
# #
# Alternatively, this file may be used under the terms of the GNU Affero #
# Public License version 3 as published by the Free Software and appearing #
# in the file LICENSE.AGPL included in the packaging of this file. #
# The BEAT platform is distributed in the hope that it will be useful, but #
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY #
# or FITNESS FOR A PARTICULAR PURPOSE. #
# #
# You should have received a copy of the GNU Affero Public License along #
# with the BEAT platform. If not, see http://www.gnu.org/licenses/. #
# #
###############################################################################
"""
Decorators
"""
from functools import wraps
def frozen(cls):
"""
Don't allow new attributes to be added outside of init
Based on https://stackoverflow.com/a/29368642/5843716
"""
cls.__frozen = False
def frozensetattr(self, key, value):
"""Don't allow attributes to be added outside of __init__"""
if self.__frozen and not hasattr(self, key):
raise RuntimeError(
"Class {} is frozen. Cannot set {} = {}".format(
cls.__name__, key, value
)
)
else:
object.__setattr__(self, key, value)
def init_decorator(func):
@wraps(func)
def wrapper(self, *args, **kwargs):
func(self, *args, **kwargs)
self.__frozen = True
return wrapper
cls.__setattr__ = frozensetattr
cls.__init__ = init_decorator(cls.__init__)
return cls
# vim: set fileencoding=utf-8 :
###############################################################################
# #
# Copyright (c) 2019 Idiap Research Institute, http://www.idiap.ch/ #
# Contact: beat.support@idiap.ch #
# #
# This file is part of the beat.editor module of the BEAT platform. #
# #
# Commercial License Usage #
# Licensees holding valid commercial BEAT licenses may use this file in #
# accordance with the terms contained in a written agreement between you #
# and Idiap. For further information contact tto@idiap.ch #
# #
# Alternatively, this file may be used under the terms of the GNU Affero #
# Public License version 3 as published by the Free Software and appearing #
# in the file LICENSE.AGPL included in the packaging of this file. #
# The BEAT platform is distributed in the hope that it will be useful, but #
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY #
# or FITNESS FOR A PARTICULAR PURPOSE. #
# #
# You should have received a copy of the GNU Affero Public License along #
# with the BEAT platform. If not, see http://www.gnu.org/licenses/. #
# #
###############################################################################
import pytest
from ..decorators import frozen
def test_frozen():
@frozen
class FrozenClass:
pass
frozen_cls_instance = FrozenClass()
with pytest.raises(RuntimeError):
frozen_cls_instance.value = None
......@@ -35,7 +35,6 @@ import logging
import simplejson as json
import pkg_resources
from functools import wraps
from packaging import version
from PyQt5 import QtCore
......@@ -89,40 +88,6 @@ def setup_logger(name, verbosity):
return logger
def frozen(cls):
"""
Don't allow new attributes to be added outside of init
Based on https://stackoverflow.com/a/29368642/5843716
"""
cls.__frozen = False
def frozensetattr(self, key, value):
"""Don't allow attributes to be added outside of __init__"""
if self.__frozen and not hasattr(self, key):
print(
"Class {} is frozen. Cannot set {} = {}".format(
cls.__name__, key, value
)
)
else:
object.__setattr__(self, key, value)
def init_decorator(func):
@wraps(func)
def wrapper(self, *args, **kwargs):
func(self, *args, **kwargs)
self.__frozen = True
return wrapper
cls.__setattr__ = frozensetattr
cls.__init__ = init_decorator(cls.__init__)
return cls
def dataformat_basetypes():
"""Returns the list of base types that can be used for dataformat"""
......
......@@ -24,7 +24,7 @@
###############################################################################
from ..backend.asset import AssetType
from ..utils import frozen
from ..decorators import frozen
from .editor import AbstractAssetEditor
......
......@@ -44,7 +44,7 @@ from PyQt5.QtWidgets import QMessageBox
from ..backend.asset import AssetType
from ..backend.asset import Asset
from ..utils import frozen
from ..decorators import frozen
from .editor import PlaceholderEditor
from .algorithmeditor import AlgorithmEditor
......
......@@ -54,7 +54,7 @@ from beat.core.protocoltemplate import ProtocolTemplate
from ..backend.assetmodel import AssetModel
from ..backend.asset import AssetType
from ..utils import frozen
from ..decorators import frozen
from ..utils import is_Qt_equal_or_higher
from .editor import AbstractAssetEditor
......
......@@ -40,7 +40,7 @@ from PyQt5.QtWidgets import QSpinBox
from PyQt5.QtWidgets import QVBoxLayout
from PyQt5.QtWidgets import QWidget
from ..utils import frozen
from ..decorators import frozen
from ..utils import dataformat_basetypes
from ..backend.asset import AssetType
......
......@@ -24,7 +24,7 @@
###############################################################################
from ..backend.asset import AssetType
from ..utils import frozen
from ..decorators import frozen
from .editor import AbstractAssetEditor
......
......@@ -23,7 +23,7 @@
# #
###############################################################################
from ..utils import frozen
from ..decorators import frozen
from ..backend.asset import AssetType
from ..backend.assetmodel import AssetModel
......
......@@ -38,7 +38,7 @@ from PyQt5.QtWidgets import QLineEdit
from PyQt5.QtWidgets import QPushButton
from PyQt5.QtWidgets import QWidget
from ..utils import frozen
from ..decorators import frozen
from ..backend.asset import AssetType
from ..backend.assetmodel import AssetModel
......
......@@ -24,7 +24,7 @@
###############################################################################
from ..backend.asset import AssetType
from ..utils import frozen
from ..decorators import frozen
from .editor import AbstractAssetEditor
......
......@@ -40,7 +40,7 @@ from PyQt5.QtWidgets import QTableWidgetItem
from PyQt5.QtWidgets import QVBoxLayout
from PyQt5.QtWidgets import QWidget
from ..utils import frozen
from ..decorators import frozen
from ..backend.asset import AssetType
from ..backend.assetmodel import AssetModel
......
......@@ -34,7 +34,7 @@ from PyQt5.QtGui import QValidator
from PyQt5.QtWidgets import QAbstractSpinBox
from ..utils import frozen
from ..decorators import frozen
@frozen
......
......@@ -24,7 +24,7 @@
###############################################################################
from ..backend.asset import AssetType
from ..utils import frozen
from ..decorators import frozen
from .editor import AbstractAssetEditor
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment