Commit 0bf57ddd authored by Samuel GAIST's avatar Samuel GAIST
Browse files

[decorators] Moved frozen decorator out of utils

And added test for it.
parent d0b2494f
#!/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 ...@@ -35,7 +35,6 @@ import logging
import simplejson as json import simplejson as json
import pkg_resources import pkg_resources
from functools import wraps
from packaging import version from packaging import version
from PyQt5 import QtCore from PyQt5 import QtCore
...@@ -89,40 +88,6 @@ def setup_logger(name, verbosity): ...@@ -89,40 +88,6 @@ def setup_logger(name, verbosity):
return logger 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(): def dataformat_basetypes():
"""Returns the list of base types that can be used for dataformat""" """Returns the list of base types that can be used for dataformat"""
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
############################################################################### ###############################################################################
from ..backend.asset import AssetType from ..backend.asset import AssetType
from ..utils import frozen from ..decorators import frozen
from .editor import AbstractAssetEditor from .editor import AbstractAssetEditor
......
...@@ -44,7 +44,7 @@ from PyQt5.QtWidgets import QMessageBox ...@@ -44,7 +44,7 @@ from PyQt5.QtWidgets import QMessageBox
from ..backend.asset import AssetType from ..backend.asset import AssetType
from ..backend.asset import Asset from ..backend.asset import Asset
from ..utils import frozen from ..decorators import frozen
from .editor import PlaceholderEditor from .editor import PlaceholderEditor
from .algorithmeditor import AlgorithmEditor from .algorithmeditor import AlgorithmEditor
......
...@@ -54,7 +54,7 @@ from beat.core.protocoltemplate import ProtocolTemplate ...@@ -54,7 +54,7 @@ from beat.core.protocoltemplate import ProtocolTemplate
from ..backend.assetmodel import AssetModel from ..backend.assetmodel import AssetModel
from ..backend.asset import AssetType from ..backend.asset import AssetType
from ..utils import frozen from ..decorators import frozen
from ..utils import is_Qt_equal_or_higher from ..utils import is_Qt_equal_or_higher
from .editor import AbstractAssetEditor from .editor import AbstractAssetEditor
......
...@@ -40,7 +40,7 @@ from PyQt5.QtWidgets import QSpinBox ...@@ -40,7 +40,7 @@ from PyQt5.QtWidgets import QSpinBox
from PyQt5.QtWidgets import QVBoxLayout from PyQt5.QtWidgets import QVBoxLayout
from PyQt5.QtWidgets import QWidget from PyQt5.QtWidgets import QWidget
from ..utils import frozen from ..decorators import frozen
from ..utils import dataformat_basetypes from ..utils import dataformat_basetypes
from ..backend.asset import AssetType from ..backend.asset import AssetType
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
############################################################################### ###############################################################################
from ..backend.asset import AssetType from ..backend.asset import AssetType
from ..utils import frozen from ..decorators import frozen
from .editor import AbstractAssetEditor from .editor import AbstractAssetEditor
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
# # # #
############################################################################### ###############################################################################
from ..utils import frozen from ..decorators import frozen
from ..backend.asset import AssetType from ..backend.asset import AssetType
from ..backend.assetmodel import AssetModel from ..backend.assetmodel import AssetModel
......
...@@ -38,7 +38,7 @@ from PyQt5.QtWidgets import QLineEdit ...@@ -38,7 +38,7 @@ from PyQt5.QtWidgets import QLineEdit
from PyQt5.QtWidgets import QPushButton from PyQt5.QtWidgets import QPushButton
from PyQt5.QtWidgets import QWidget from PyQt5.QtWidgets import QWidget
from ..utils import frozen from ..decorators import frozen
from ..backend.asset import AssetType from ..backend.asset import AssetType
from ..backend.assetmodel import AssetModel from ..backend.assetmodel import AssetModel
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
############################################################################### ###############################################################################
from ..backend.asset import AssetType from ..backend.asset import AssetType
from ..utils import frozen from ..decorators import frozen
from .editor import AbstractAssetEditor from .editor import AbstractAssetEditor
......
...@@ -40,7 +40,7 @@ from PyQt5.QtWidgets import QTableWidgetItem ...@@ -40,7 +40,7 @@ from PyQt5.QtWidgets import QTableWidgetItem
from PyQt5.QtWidgets import QVBoxLayout from PyQt5.QtWidgets import QVBoxLayout
from PyQt5.QtWidgets import QWidget from PyQt5.QtWidgets import QWidget
from ..utils import frozen from ..decorators import frozen
from ..backend.asset import AssetType from ..backend.asset import AssetType
from ..backend.assetmodel import AssetModel from ..backend.assetmodel import AssetModel
......
...@@ -34,7 +34,7 @@ from PyQt5.QtGui import QValidator ...@@ -34,7 +34,7 @@ from PyQt5.QtGui import QValidator
from PyQt5.QtWidgets import QAbstractSpinBox from PyQt5.QtWidgets import QAbstractSpinBox
from ..utils import frozen from ..decorators import frozen
@frozen @frozen
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
############################################################################### ###############################################################################
from ..backend.asset import AssetType from ..backend.asset import AssetType
from ..utils import frozen from ..decorators import frozen
from .editor import AbstractAssetEditor from .editor import AbstractAssetEditor
......
Supports Markdown
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