mirror of
https://github.com/evennia/evennia.git
synced 2026-03-28 02:36:32 +01:00
Ran black on sources
This commit is contained in:
parent
2c57200cf7
commit
4ef9f994db
3 changed files with 194 additions and 239 deletions
|
|
@ -31,6 +31,7 @@ class _MockObj:
|
|||
assert category == self.category
|
||||
self.dbstore[key] = value
|
||||
|
||||
|
||||
# we want to test the base traits too
|
||||
_TEST_TRAIT_CLASS_PATHS = [
|
||||
"evennia.contrib.traits.Trait",
|
||||
|
|
@ -39,8 +40,10 @@ _TEST_TRAIT_CLASS_PATHS = [
|
|||
"evennia.contrib.traits.GaugeTrait",
|
||||
]
|
||||
|
||||
|
||||
class _TraitHandlerBase(TestCase):
|
||||
"Base for trait tests"
|
||||
|
||||
@patch("evennia.contrib.traits._TRAIT_CLASS_PATHS", new=_TEST_TRAIT_CLASS_PATHS)
|
||||
def setUp(self):
|
||||
self.obj = _MockObj()
|
||||
|
|
@ -48,7 +51,7 @@ class _TraitHandlerBase(TestCase):
|
|||
self.obj.traits = self.traithandler
|
||||
|
||||
def _get_dbstore(self, key):
|
||||
return self.obj.dbstore['traits'][key]
|
||||
return self.obj.dbstore["traits"][key]
|
||||
|
||||
|
||||
class TraitHandlerTest(_TraitHandlerBase):
|
||||
|
|
@ -56,32 +59,18 @@ class TraitHandlerTest(_TraitHandlerBase):
|
|||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.traithandler.add("test1", name="Test1", trait_type="trait")
|
||||
self.traithandler.add(
|
||||
"test1",
|
||||
name="Test1",
|
||||
trait_type='trait'
|
||||
)
|
||||
self.traithandler.add(
|
||||
"test2",
|
||||
name="Test2",
|
||||
trait_type='trait',
|
||||
value=["foo", {"1": [1, 2, 3]}, 4],
|
||||
"test2", name="Test2", trait_type="trait", value=["foo", {"1": [1, 2, 3]}, 4],
|
||||
)
|
||||
|
||||
def test_add_trait(self):
|
||||
self.assertEqual(
|
||||
self._get_dbstore("test1"),
|
||||
{"name": "Test1",
|
||||
"trait_type": 'trait',
|
||||
"value": None,
|
||||
}
|
||||
self._get_dbstore("test1"), {"name": "Test1", "trait_type": "trait", "value": None,}
|
||||
)
|
||||
self.assertEqual(
|
||||
self._get_dbstore("test2"),
|
||||
{"name": "Test2",
|
||||
"trait_type": 'trait',
|
||||
"value": ["foo", {"1": [1, 2, 3]}, 4],
|
||||
}
|
||||
{"name": "Test2", "trait_type": "trait", "value": ["foo", {"1": [1, 2, 3]}, 4],},
|
||||
)
|
||||
self.assertEqual(len(self.traithandler), 2)
|
||||
|
||||
|
|
@ -109,21 +98,14 @@ class TraitHandlerTest(_TraitHandlerBase):
|
|||
def test_getting(self):
|
||||
"Test we are getting data from the dbstore"
|
||||
self.assertEqual(
|
||||
self.traithandler.test1._data,
|
||||
{"name": "Test1", "trait_type": "trait",
|
||||
"value": None}
|
||||
)
|
||||
self.assertEqual(
|
||||
self.traithandler._cache, Something
|
||||
self.traithandler.test1._data, {"name": "Test1", "trait_type": "trait", "value": None}
|
||||
)
|
||||
self.assertEqual(self.traithandler._cache, Something)
|
||||
self.assertEqual(
|
||||
self.traithandler.test2._data,
|
||||
{"name": "Test2", "trait_type": "trait",
|
||||
"value": ["foo", {"1": [1, 2, 3]}, 4]}
|
||||
)
|
||||
self.assertEqual(
|
||||
self.traithandler._cache, Something
|
||||
{"name": "Test2", "trait_type": "trait", "value": ["foo", {"1": [1, 2, 3]}, 4]},
|
||||
)
|
||||
self.assertEqual(self.traithandler._cache, Something)
|
||||
self.assertFalse(self.traithandler.get("foo"))
|
||||
self.assertFalse(self.traithandler.bar)
|
||||
|
||||
|
|
@ -151,20 +133,13 @@ class TraitHandlerTest(_TraitHandlerBase):
|
|||
self.assertEqual(trait.value, None)
|
||||
trait.value = 10
|
||||
self.assertEqual(trait.value, 10)
|
||||
self.assertEqual(
|
||||
self.obj.attributes.get("traits", category="traits")['test1']['value'],
|
||||
10
|
||||
)
|
||||
self.assertEqual(self.obj.attributes.get("traits", category="traits")["test1"]["value"], 10)
|
||||
trait.value = 20
|
||||
self.assertEqual(trait.value, 20)
|
||||
self.assertEqual(
|
||||
self.obj.attributes.get("traits", category="traits")['test1']['value'],
|
||||
20
|
||||
)
|
||||
self.assertEqual(self.obj.attributes.get("traits", category="traits")["test1"]["value"], 20)
|
||||
del trait.value
|
||||
self.assertEqual(
|
||||
self.obj.attributes.get("traits", category="traits")['test1']['value'],
|
||||
None
|
||||
self.obj.attributes.get("traits", category="traits")["test1"]["value"], None
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -188,44 +163,40 @@ class TestTrait(_TraitHandlerBase):
|
|||
def test_init(self):
|
||||
self.assertEqual(
|
||||
self.trait._data,
|
||||
{"name": "Test1",
|
||||
"trait_type": "trait",
|
||||
"value": "value",
|
||||
"extra_val1": "xvalue1",
|
||||
"extra_val2": "xvalue2"
|
||||
}
|
||||
{
|
||||
"name": "Test1",
|
||||
"trait_type": "trait",
|
||||
"value": "value",
|
||||
"extra_val1": "xvalue1",
|
||||
"extra_val2": "xvalue2",
|
||||
},
|
||||
)
|
||||
|
||||
def test_validate_input__valid(self):
|
||||
"""Test valid validation input"""
|
||||
# all data supplied, and extras
|
||||
dat = {
|
||||
"name": "Test",
|
||||
"trait_type": "trait",
|
||||
"value": 10,
|
||||
"extra_val": 1000
|
||||
}
|
||||
dat = {"name": "Test", "trait_type": "trait", "value": 10, "extra_val": 1000}
|
||||
expected = copy(dat) # we must break link or return === dat always
|
||||
self.assertEqual(expected, traits.Trait.validate_input(traits.Trait, dat))
|
||||
|
||||
# don't supply value, should get default
|
||||
dat = {
|
||||
"name": "Test",
|
||||
"trait_type": "trait",
|
||||
# missing value
|
||||
"extra_val": 1000
|
||||
"name": "Test",
|
||||
"trait_type": "trait",
|
||||
# missing value
|
||||
"extra_val": 1000,
|
||||
}
|
||||
expected = copy(dat)
|
||||
expected["value"] = traits.Trait.default_keys['value']
|
||||
expected["value"] = traits.Trait.default_keys["value"]
|
||||
self.assertEqual(expected, traits.Trait.validate_input(traits.Trait, dat))
|
||||
|
||||
# make sure extra values are cleaned if trait accepts no extras
|
||||
dat = {
|
||||
"name": "Test",
|
||||
"trait_type": "trait",
|
||||
"value": 10,
|
||||
"extra_val1": 1000,
|
||||
"extra_val2": "xvalue"
|
||||
"name": "Test",
|
||||
"trait_type": "trait",
|
||||
"value": 10,
|
||||
"extra_val1": 1000,
|
||||
"extra_val2": "xvalue",
|
||||
}
|
||||
expected = copy(dat)
|
||||
expected.pop("extra_val1")
|
||||
|
|
@ -236,24 +207,22 @@ class TestTrait(_TraitHandlerBase):
|
|||
def test_validate_input__fail(self):
|
||||
"""Test failing validation"""
|
||||
dat = {
|
||||
# missing name
|
||||
"trait_type": "trait",
|
||||
"value": 10,
|
||||
"extra_val": 1000
|
||||
# missing name
|
||||
"trait_type": "trait",
|
||||
"value": 10,
|
||||
"extra_val": 1000,
|
||||
}
|
||||
with self.assertRaises(traits.TraitException):
|
||||
traits.Trait.validate_input(traits.Trait, dat)
|
||||
|
||||
# make value a required key
|
||||
mock_default_keys = {
|
||||
"value": traits.MandatoryTraitKey
|
||||
}
|
||||
mock_default_keys = {"value": traits.MandatoryTraitKey}
|
||||
with patch.object(traits.Trait, "default_keys", mock_default_keys):
|
||||
dat = {
|
||||
"name": "Trait",
|
||||
"trait_type": "trait",
|
||||
# missing value, now mandatory
|
||||
"extra_val": 1000
|
||||
"name": "Trait",
|
||||
"trait_type": "trait",
|
||||
# missing value, now mandatory
|
||||
"extra_val": 1000,
|
||||
}
|
||||
with self.assertRaises(traits.TraitException):
|
||||
traits.Trait.validate_input(traits.Trait, dat)
|
||||
|
|
@ -261,15 +230,15 @@ class TestTrait(_TraitHandlerBase):
|
|||
def test_trait_getset(self):
|
||||
"""Get-set-del operations on trait"""
|
||||
self.assertEqual(self.trait.name, "Test1")
|
||||
self.assertEqual(self.trait['name'], "Test1")
|
||||
self.assertEqual(self.trait["name"], "Test1")
|
||||
self.assertEqual(self.trait.value, "value")
|
||||
self.assertEqual(self.trait['value'], "value")
|
||||
self.assertEqual(self.trait.extra_val1, "xvalue1" )
|
||||
self.assertEqual(self.trait['extra_val2'], "xvalue2")
|
||||
self.assertEqual(self.trait["value"], "value")
|
||||
self.assertEqual(self.trait.extra_val1, "xvalue1")
|
||||
self.assertEqual(self.trait["extra_val2"], "xvalue2")
|
||||
|
||||
self.trait.value = 20
|
||||
self.assertEqual(self.trait['value'], 20)
|
||||
self.trait['value'] = 20
|
||||
self.assertEqual(self.trait["value"], 20)
|
||||
self.trait["value"] = 20
|
||||
self.assertEqual(self.trait.value, 20)
|
||||
self.trait.extra_val1 = 100
|
||||
self.assertEqual(self.trait.extra_val1, 100)
|
||||
|
|
@ -279,7 +248,7 @@ class TestTrait(_TraitHandlerBase):
|
|||
|
||||
del self.trait.foo
|
||||
with self.assertRaises(KeyError):
|
||||
self.trait['foo']
|
||||
self.trait["foo"]
|
||||
with self.assertRaises(AttributeError):
|
||||
self.trait.foo
|
||||
del self.trait.extra_val1
|
||||
|
|
@ -298,16 +267,17 @@ class TestTraitStatic(_TraitHandlerBase):
|
|||
"""
|
||||
Test for static Traits
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.traithandler.add(
|
||||
"test1",
|
||||
name="Test1",
|
||||
trait_type='static',
|
||||
trait_type="static",
|
||||
base=1,
|
||||
mod=2,
|
||||
extra_val1="xvalue1",
|
||||
extra_val2="xvalue2"
|
||||
extra_val2="xvalue2",
|
||||
)
|
||||
self.trait = self.traithandler.get("test1")
|
||||
|
||||
|
|
@ -317,13 +287,14 @@ class TestTraitStatic(_TraitHandlerBase):
|
|||
def test_init(self):
|
||||
self.assertEqual(
|
||||
self._get_dbstore("test1"),
|
||||
{"name": "Test1",
|
||||
"trait_type": 'static',
|
||||
"base": 1,
|
||||
"mod": 2,
|
||||
"extra_val1": "xvalue1",
|
||||
"extra_val2": "xvalue2"
|
||||
}
|
||||
{
|
||||
"name": "Test1",
|
||||
"trait_type": "static",
|
||||
"base": 1,
|
||||
"mod": 2,
|
||||
"extra_val1": "xvalue1",
|
||||
"extra_val2": "xvalue2",
|
||||
},
|
||||
)
|
||||
|
||||
def test_value(self):
|
||||
|
|
@ -346,53 +317,44 @@ class TestTraitCounter(_TraitHandlerBase):
|
|||
"""
|
||||
Test for counter- Traits
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.traithandler.add(
|
||||
"test1",
|
||||
name="Test1",
|
||||
trait_type='counter',
|
||||
trait_type="counter",
|
||||
base=1,
|
||||
mod=2,
|
||||
min=0,
|
||||
max=10,
|
||||
extra_val1="xvalue1",
|
||||
extra_val2="xvalue2",
|
||||
descs={
|
||||
0: "range0",
|
||||
2: "range1",
|
||||
5: "range2",
|
||||
7: "range3",
|
||||
}
|
||||
descs={0: "range0", 2: "range1", 5: "range2", 7: "range3",},
|
||||
)
|
||||
self.trait = self.traithandler.get("test1")
|
||||
|
||||
def _get_values(self):
|
||||
"""Get (base, mod, value, min, max)."""
|
||||
return (self.trait.base, self.trait.mod,
|
||||
self.trait.value, self.trait.min, self.trait.max)
|
||||
return (self.trait.base, self.trait.mod, self.trait.value, self.trait.min, self.trait.max)
|
||||
|
||||
def test_init(self):
|
||||
self.assertEqual(
|
||||
self._get_dbstore("test1"),
|
||||
{"name": "Test1",
|
||||
"trait_type": 'counter',
|
||||
"base": 1,
|
||||
"mod": 2,
|
||||
"min": 0,
|
||||
"max": 10,
|
||||
"extra_val1": "xvalue1",
|
||||
"extra_val2": "xvalue2",
|
||||
"descs": {
|
||||
0: "range0",
|
||||
2: "range1",
|
||||
5: "range2",
|
||||
7: "range3",
|
||||
},
|
||||
"rate": 0,
|
||||
"ratetarget": None,
|
||||
"last_update": None,
|
||||
}
|
||||
{
|
||||
"name": "Test1",
|
||||
"trait_type": "counter",
|
||||
"base": 1,
|
||||
"mod": 2,
|
||||
"min": 0,
|
||||
"max": 10,
|
||||
"extra_val1": "xvalue1",
|
||||
"extra_val2": "xvalue2",
|
||||
"descs": {0: "range0", 2: "range1", 5: "range2", 7: "range3",},
|
||||
"rate": 0,
|
||||
"ratetarget": None,
|
||||
"last_update": None,
|
||||
},
|
||||
)
|
||||
|
||||
def test_value(self):
|
||||
|
|
@ -453,7 +415,7 @@ class TestTraitCounter(_TraitHandlerBase):
|
|||
|
||||
# re-activate boundaries
|
||||
self.trait.max = 15
|
||||
self.trait.min = 10 # his is blocked since base+mod is lower
|
||||
self.trait.min = 10 # his is blocked since base+mod is lower
|
||||
self.assertEqual(self._get_values(), (-200, 5, -195, -195, 15))
|
||||
|
||||
def test_boundaries__inverse(self):
|
||||
|
|
@ -533,33 +495,34 @@ class TestTraitCounterTimed(_TraitHandlerBase):
|
|||
"""
|
||||
Test for trait with timer component
|
||||
"""
|
||||
|
||||
@patch("evennia.contrib.traits.time", new=MagicMock(return_value=1000))
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.traithandler.add(
|
||||
"test1",
|
||||
name="Test1",
|
||||
trait_type='counter',
|
||||
trait_type="counter",
|
||||
base=1,
|
||||
mod=2,
|
||||
min=0,
|
||||
max=100,
|
||||
extra_val1="xvalue1",
|
||||
extra_val2="xvalue2",
|
||||
descs={
|
||||
0: "range0",
|
||||
2: "range1",
|
||||
5: "range2",
|
||||
7: "range3",
|
||||
},
|
||||
descs={0: "range0", 2: "range1", 5: "range2", 7: "range3",},
|
||||
rate=1,
|
||||
ratetarget=None,
|
||||
)
|
||||
self.trait = self.traithandler.get("test1")
|
||||
|
||||
def _get_timer_data(self):
|
||||
return (self.trait.value, self.trait.current, self.trait.rate,
|
||||
self.trait._data["last_update"], self.trait.ratetarget)
|
||||
return (
|
||||
self.trait.value,
|
||||
self.trait.current,
|
||||
self.trait.rate,
|
||||
self.trait._data["last_update"],
|
||||
self.trait.ratetarget,
|
||||
)
|
||||
|
||||
@patch("evennia.contrib.traits.time")
|
||||
def test_timer_rate(self, mock_time):
|
||||
|
|
@ -608,52 +571,42 @@ class TestTraitCounterTimed(_TraitHandlerBase):
|
|||
|
||||
|
||||
class TestTraitGauge(_TraitHandlerBase):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.traithandler.add(
|
||||
"test1",
|
||||
name="Test1",
|
||||
trait_type='gauge',
|
||||
trait_type="gauge",
|
||||
base=8, # max = base + mod
|
||||
mod=2,
|
||||
extra_val1="xvalue1",
|
||||
extra_val2="xvalue2",
|
||||
descs={
|
||||
0: "range0",
|
||||
2: "range1",
|
||||
5: "range2",
|
||||
7: "range3",
|
||||
}
|
||||
descs={0: "range0", 2: "range1", 5: "range2", 7: "range3",},
|
||||
)
|
||||
self.trait = self.traithandler.get("test1")
|
||||
|
||||
def _get_values(self):
|
||||
"""Get (base, mod, value, min, max)."""
|
||||
return (self.trait.base, self.trait.mod, self.trait.value,
|
||||
self.trait.min, self.trait.max)
|
||||
return (self.trait.base, self.trait.mod, self.trait.value, self.trait.min, self.trait.max)
|
||||
|
||||
def test_init(self):
|
||||
self.assertEqual(
|
||||
self._get_dbstore("test1"),
|
||||
{"name": "Test1",
|
||||
"trait_type": 'gauge',
|
||||
"base": 8,
|
||||
"mod": 2,
|
||||
"min": 0,
|
||||
"extra_val1": "xvalue1",
|
||||
"extra_val2": "xvalue2",
|
||||
"descs": {
|
||||
0: "range0",
|
||||
2: "range1",
|
||||
5: "range2",
|
||||
7: "range3",
|
||||
},
|
||||
"rate": 0,
|
||||
"ratetarget": None,
|
||||
"last_update": None,
|
||||
}
|
||||
{
|
||||
"name": "Test1",
|
||||
"trait_type": "gauge",
|
||||
"base": 8,
|
||||
"mod": 2,
|
||||
"min": 0,
|
||||
"extra_val1": "xvalue1",
|
||||
"extra_val2": "xvalue2",
|
||||
"descs": {0: "range0", 2: "range1", 5: "range2", 7: "range3",},
|
||||
"rate": 0,
|
||||
"ratetarget": None,
|
||||
"last_update": None,
|
||||
},
|
||||
)
|
||||
|
||||
def test_value(self):
|
||||
"""value is current, where current defaults to base + mod"""
|
||||
# current unset - follows base + mod
|
||||
|
|
@ -724,6 +677,7 @@ class TestTraitGauge(_TraitHandlerBase):
|
|||
self.assertEqual(self._get_values(), (0, 0, 0, 0, 0))
|
||||
with self.assertRaises(traits.TraitException):
|
||||
del self.trait.max
|
||||
|
||||
def test_boundaries__inverse(self):
|
||||
"""Try to set reversed boundaries"""
|
||||
self.trait.mod = 0
|
||||
|
|
@ -798,32 +752,33 @@ class TestTraitGaugeTimed(_TraitHandlerBase):
|
|||
"""
|
||||
Test for trait with timer component
|
||||
"""
|
||||
|
||||
@patch("evennia.contrib.traits.time", new=MagicMock(return_value=1000))
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.traithandler.add(
|
||||
"test1",
|
||||
name="Test1",
|
||||
trait_type='gauge',
|
||||
trait_type="gauge",
|
||||
base=98,
|
||||
mod=2,
|
||||
min=0,
|
||||
extra_val1="xvalue1",
|
||||
extra_val2="xvalue2",
|
||||
descs={
|
||||
0: "range0",
|
||||
2: "range1",
|
||||
5: "range2",
|
||||
7: "range3",
|
||||
},
|
||||
descs={0: "range0", 2: "range1", 5: "range2", 7: "range3",},
|
||||
rate=1,
|
||||
ratetarget=None,
|
||||
)
|
||||
self.trait = self.traithandler.get("test1")
|
||||
|
||||
def _get_timer_data(self):
|
||||
return (self.trait.value, self.trait.current, self.trait.rate,
|
||||
self.trait._data["last_update"], self.trait.ratetarget)
|
||||
return (
|
||||
self.trait.value,
|
||||
self.trait.current,
|
||||
self.trait.rate,
|
||||
self.trait._data["last_update"],
|
||||
self.trait.ratetarget,
|
||||
)
|
||||
|
||||
@patch("evennia.contrib.traits.time")
|
||||
def test_timer_rate(self, mock_time):
|
||||
|
|
@ -875,18 +830,11 @@ class TestTraitGaugeTimed(_TraitHandlerBase):
|
|||
|
||||
class TestNumericTraitOperators(TestCase):
|
||||
"""Test case for numeric magic method implementations."""
|
||||
|
||||
def setUp(self):
|
||||
# direct instantiation for testing only; use TraitHandler in production
|
||||
self.st = traits.Trait({
|
||||
'name': 'Strength',
|
||||
'trait_type': 'trait',
|
||||
'value': 8,
|
||||
})
|
||||
self.at = traits.Trait({
|
||||
'name': 'Attack',
|
||||
'trait_type': 'trait',
|
||||
'value': 4,
|
||||
})
|
||||
self.st = traits.Trait({"name": "Strength", "trait_type": "trait", "value": 8,})
|
||||
self.at = traits.Trait({"name": "Attack", "trait_type": "trait", "value": 4,})
|
||||
|
||||
def tearDown(self):
|
||||
self.st, self.at = None, None
|
||||
|
|
|
|||
|
|
@ -336,8 +336,7 @@ from django.conf import settings
|
|||
from functools import total_ordering
|
||||
from evennia.utils.dbserialize import _SaverDict
|
||||
from evennia.utils import logger
|
||||
from evennia.utils.utils import (
|
||||
inherits_from, class_from_module, list_to_string, percent)
|
||||
from evennia.utils.utils import inherits_from, class_from_module, list_to_string, percent
|
||||
|
||||
|
||||
# Available Trait classes.
|
||||
|
|
@ -437,8 +436,7 @@ class TraitHandler:
|
|||
# no existing storage; initialize it, we then have to fetch it again
|
||||
# to retain the db connection
|
||||
obj.attributes.add(db_attribute_key, {}, category=db_attribute_category)
|
||||
self.trait_data = obj.attributes.get(
|
||||
db_attribute_key, category=db_attribute_category)
|
||||
self.trait_data = obj.attributes.get(db_attribute_key, category=db_attribute_category)
|
||||
self._cache = {}
|
||||
|
||||
def __len__(self):
|
||||
|
|
@ -459,8 +457,7 @@ class TraitHandler:
|
|||
trait_cls = self._get_trait_class(trait_key=trait_key)
|
||||
valid_keys = list_to_string(list(trait_cls.default_keys.keys()), endsep="or")
|
||||
raise TraitException(
|
||||
"Trait object not settable directly. "
|
||||
f"Assign to {trait_key}.{valid_keys}."
|
||||
"Trait object not settable directly. " f"Assign to {trait_key}.{valid_keys}."
|
||||
)
|
||||
|
||||
def __setitem__(self, trait_key, value):
|
||||
|
|
@ -524,7 +521,9 @@ class TraitHandler:
|
|||
trait = self._cache[trait_key] = trait_cls(_GA(self, "trait_data")[trait_key])
|
||||
return trait
|
||||
|
||||
def add(self, trait_key, name=None, trait_type=DEFAULT_TRAIT_TYPE, force=True, **trait_properties):
|
||||
def add(
|
||||
self, trait_key, name=None, trait_type=DEFAULT_TRAIT_TYPE, force=True, **trait_properties
|
||||
):
|
||||
"""
|
||||
Create a new Trait and add it to the handler.
|
||||
|
||||
|
|
@ -566,7 +565,6 @@ class TraitHandler:
|
|||
|
||||
self.trait_data[trait_key] = trait_properties
|
||||
|
||||
|
||||
def remove(self, trait_key):
|
||||
"""
|
||||
Remove a Trait from the handler's parent object.
|
||||
|
|
@ -592,6 +590,7 @@ class TraitHandler:
|
|||
|
||||
# Parent Trait class
|
||||
|
||||
|
||||
@total_ordering
|
||||
class Trait:
|
||||
"""Represents an object or Character trait. This simple base is just
|
||||
|
|
@ -605,6 +604,7 @@ class Trait:
|
|||
value
|
||||
|
||||
"""
|
||||
|
||||
# this is the name used to refer to this trait when adding
|
||||
# a new trait in the TraitHandler
|
||||
trait_type = "trait"
|
||||
|
|
@ -661,6 +661,7 @@ class Trait:
|
|||
TraitException: If finding unset keys without a default.
|
||||
|
||||
"""
|
||||
|
||||
def _raise_err(unset_required):
|
||||
"""Helper method to format exception."""
|
||||
raise TraitException(
|
||||
|
|
@ -668,6 +669,7 @@ class Trait:
|
|||
cls.trait_type, list_to_string(list(unset_required), addquote=True)
|
||||
)
|
||||
)
|
||||
|
||||
inp = set(trait_data.keys())
|
||||
|
||||
# separate check for name/trait_type, those are always required.
|
||||
|
|
@ -683,15 +685,13 @@ class Trait:
|
|||
|
||||
if MandatoryTraitKey in unset_defaults.values():
|
||||
# we have one or more unset keys that was mandatory
|
||||
_raise_err([key for key, value in unset_defaults.items()
|
||||
if value == MandatoryTraitKey])
|
||||
_raise_err([key for key, value in unset_defaults.items() if value == MandatoryTraitKey])
|
||||
# apply the default values
|
||||
trait_data.update(unset_defaults)
|
||||
|
||||
if not cls.allow_extra_properties:
|
||||
# don't allow any extra properties - remove the extra data
|
||||
for key in (key for key in inp.difference(req)
|
||||
if key not in ("name", "trait_type")):
|
||||
for key in (key for key in inp.difference(req) if key not in ("name", "trait_type")):
|
||||
del trait_data[key]
|
||||
|
||||
return trait_data
|
||||
|
|
@ -722,10 +722,8 @@ class Trait:
|
|||
except KeyError:
|
||||
raise AttributeError(
|
||||
"{!r} {} ({}) has no property {!r}.".format(
|
||||
self._data['name'],
|
||||
type(self).__name__,
|
||||
self.trait_type,
|
||||
key)
|
||||
self._data["name"], type(self).__name__, self.trait_type, key
|
||||
)
|
||||
)
|
||||
|
||||
def __setattr__(self, key, value):
|
||||
|
|
@ -746,14 +744,13 @@ class Trait:
|
|||
return
|
||||
else:
|
||||
# this is some other value
|
||||
if key in ("_data", ):
|
||||
if key in ("_data",):
|
||||
_SA(self, key, value)
|
||||
return
|
||||
if _GA(self, "allow_extra_properties"):
|
||||
_GA(self, "_data")[key] = value
|
||||
return
|
||||
raise AttributeError(f"Can't set attribute {key} on "
|
||||
f"{self.trait_type} Trait.")
|
||||
raise AttributeError(f"Can't set attribute {key} on " f"{self.trait_type} Trait.")
|
||||
|
||||
def __delattr__(self, key):
|
||||
"""
|
||||
|
|
@ -775,7 +772,8 @@ class Trait:
|
|||
if self.default_keys[key] == MandatoryTraitKey:
|
||||
raise TraitException(
|
||||
"Trait-Key {key} cannot be deleted: It's a mandatory property "
|
||||
"with no default value to fall back to.")
|
||||
"with no default value to fall back to."
|
||||
)
|
||||
# set to default
|
||||
self._data[key] = self.default_keys[key]
|
||||
elif key in self._data:
|
||||
|
|
@ -797,7 +795,11 @@ class Trait:
|
|||
return "{}({{{}}})".format(
|
||||
type(self).__name__,
|
||||
", ".join(
|
||||
["'{}': {!r}".format(k, self._data[k]) for k in self.default_keys if k in self._data]
|
||||
[
|
||||
"'{}': {!r}".format(k, self._data[k])
|
||||
for k in self.default_keys
|
||||
if k in self._data
|
||||
]
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -916,6 +918,7 @@ class Trait:
|
|||
|
||||
# Implementation of the respective Trait types
|
||||
|
||||
|
||||
class StaticTrait(Trait):
|
||||
"""
|
||||
Static Trait. This is a single value with a modifier,
|
||||
|
|
@ -924,12 +927,10 @@ class StaticTrait(Trait):
|
|||
value = base + mod
|
||||
|
||||
"""
|
||||
|
||||
trait_type = "static"
|
||||
|
||||
default_keys = {
|
||||
"base": 0,
|
||||
"mod": 0
|
||||
}
|
||||
default_keys = {"base": 0, "mod": 0}
|
||||
|
||||
def __str__(self):
|
||||
status = "{value:11}".format(value=self.value)
|
||||
|
|
@ -997,7 +998,7 @@ class CounterTrait(Trait):
|
|||
"max": None,
|
||||
"descs": None,
|
||||
"rate": 0,
|
||||
"ratetarget": None
|
||||
"ratetarget": None,
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
|
|
@ -1005,18 +1006,21 @@ class CounterTrait(Trait):
|
|||
"""Add extra validation for descs"""
|
||||
trait_data = Trait.validate_input(cls, trait_data)
|
||||
# validate descs
|
||||
descs = trait_data['descs']
|
||||
descs = trait_data["descs"]
|
||||
if isinstance(descs, dict):
|
||||
if any(not (isinstance(key, (int, float)) and isinstance(value, str))
|
||||
for key, value in descs.items()):
|
||||
if any(
|
||||
not (isinstance(key, (int, float)) and isinstance(value, str))
|
||||
for key, value in descs.items()
|
||||
):
|
||||
raise TraitException(
|
||||
f"Trait descs must be defined on the "
|
||||
f"form {{number:str}} (instead found {descs}).")
|
||||
f"form {{number:str}} (instead found {descs})."
|
||||
)
|
||||
# set up rate
|
||||
if trait_data['rate'] != 0:
|
||||
trait_data['last_update'] = time()
|
||||
if trait_data["rate"] != 0:
|
||||
trait_data["last_update"] = time()
|
||||
else:
|
||||
trait_data['last_update'] = None
|
||||
trait_data["last_update"] = None
|
||||
return trait_data
|
||||
|
||||
# Helpers
|
||||
|
|
@ -1024,8 +1028,8 @@ class CounterTrait(Trait):
|
|||
def _within_boundaries(self, value):
|
||||
"""Check if given value is within boundaries"""
|
||||
return not (
|
||||
(self.min is not None and value <= self.min) or
|
||||
(self.max is not None and value >= self.max)
|
||||
(self.min is not None and value <= self.min)
|
||||
or (self.max is not None and value >= self.max)
|
||||
)
|
||||
|
||||
def _enforce_boundaries(self, value):
|
||||
|
|
@ -1040,32 +1044,31 @@ class CounterTrait(Trait):
|
|||
|
||||
def _passed_ratetarget(self, value):
|
||||
"""Check if we passed the ratetarget in either direction."""
|
||||
ratetarget = self._data['ratetarget']
|
||||
return (ratetarget is not None and (
|
||||
(self.rate < 0 and value <= ratetarget) or
|
||||
(self.rate > 0 and value >= ratetarget)))
|
||||
ratetarget = self._data["ratetarget"]
|
||||
return ratetarget is not None and (
|
||||
(self.rate < 0 and value <= ratetarget) or (self.rate > 0 and value >= ratetarget)
|
||||
)
|
||||
|
||||
def _stop_timer(self):
|
||||
"""Stop rate-timer component."""
|
||||
if self.rate != 0 and self._data['last_update'] is not None:
|
||||
self._data['last_update'] = None
|
||||
if self.rate != 0 and self._data["last_update"] is not None:
|
||||
self._data["last_update"] = None
|
||||
|
||||
def _check_and_start_timer(self, value):
|
||||
"""Start timer if we are not at a boundary."""
|
||||
if self.rate != 0 and self._data['last_update'] is None:
|
||||
ratetarget = self._data['ratetarget']
|
||||
if self.rate != 0 and self._data["last_update"] is None:
|
||||
ratetarget = self._data["ratetarget"]
|
||||
if self._within_boundaries(value) and not self._passed_ratetarget(value):
|
||||
# we are not at a boundary [anymore].
|
||||
self._data['last_update'] = time()
|
||||
self._data["last_update"] = time()
|
||||
return value
|
||||
|
||||
|
||||
def _update_current(self, current):
|
||||
"""Update current value by scaling with rate and time passed."""
|
||||
rate = self.rate
|
||||
if rate != 0 and self._data['last_update'] is not None:
|
||||
if rate != 0 and self._data["last_update"] is not None:
|
||||
now = time()
|
||||
tdiff = now - self._data['last_update']
|
||||
tdiff = now - self._data["last_update"]
|
||||
current += rate * tdiff
|
||||
value = current + self.mod
|
||||
|
||||
|
|
@ -1073,15 +1076,15 @@ class CounterTrait(Trait):
|
|||
# even if .mod is included
|
||||
|
||||
if self._passed_ratetarget(value):
|
||||
current = self._data['ratetarget'] - self.mod
|
||||
current = self._data["ratetarget"] - self.mod
|
||||
self._stop_timer()
|
||||
elif not self._within_boundaries(value):
|
||||
current = self._enforce_boundaries(value) - self.mod
|
||||
self._stop_timer()
|
||||
else:
|
||||
self._data['last_update'] = now
|
||||
self._data["last_update"] = now
|
||||
|
||||
self._data['current'] = current
|
||||
self._data["current"] = current
|
||||
|
||||
return current
|
||||
|
||||
|
|
@ -1094,7 +1097,7 @@ class CounterTrait(Trait):
|
|||
@base.setter
|
||||
def base(self, value):
|
||||
if value is None:
|
||||
self._data["base"] = self.default_keys['base']
|
||||
self._data["base"] = self.default_keys["base"]
|
||||
if type(value) in (int, float):
|
||||
if self.min is not None and value + self.mod < self.min:
|
||||
value = self.min - self.mod
|
||||
|
|
@ -1110,7 +1113,7 @@ class CounterTrait(Trait):
|
|||
def mod(self, value):
|
||||
if value is None:
|
||||
# unsetting the boundary to default
|
||||
self._data["mod"] = self.default_keys['mod']
|
||||
self._data["mod"] = self.default_keys["mod"]
|
||||
elif type(value) in (int, float):
|
||||
if self.min is not None and value + self.base < self.min:
|
||||
value = self.min - self.base
|
||||
|
|
@ -1168,11 +1171,11 @@ class CounterTrait(Trait):
|
|||
|
||||
@property
|
||||
def ratetarget(self):
|
||||
return self._data['ratetarget']
|
||||
return self._data["ratetarget"]
|
||||
|
||||
@ratetarget.setter
|
||||
def ratetarget(self, value):
|
||||
self._data['ratetarget'] = self._enforce_boundaries(value)
|
||||
self._data["ratetarget"] = self._enforce_boundaries(value)
|
||||
self._check_and_start_timer(self.value)
|
||||
|
||||
def percent(self, formatting="{:3.1f}%"):
|
||||
|
|
@ -1268,24 +1271,24 @@ class GaugeTrait(CounterTrait):
|
|||
def _update_current(self, current):
|
||||
"""Update current value by scaling with rate and time passed."""
|
||||
rate = self.rate
|
||||
if rate != 0 and self._data['last_update'] is not None:
|
||||
if rate != 0 and self._data["last_update"] is not None:
|
||||
now = time()
|
||||
tdiff = now - self._data['last_update']
|
||||
tdiff = now - self._data["last_update"]
|
||||
current += rate * tdiff
|
||||
value = current
|
||||
|
||||
# we don't worry about .mod for gauges
|
||||
|
||||
if self._passed_ratetarget(value):
|
||||
current = self._data['ratetarget']
|
||||
current = self._data["ratetarget"]
|
||||
self._stop_timer()
|
||||
elif not self._within_boundaries(value):
|
||||
current = self._enforce_boundaries(value)
|
||||
self._stop_timer()
|
||||
else:
|
||||
self._data['last_update'] = now
|
||||
self._data["last_update"] = now
|
||||
|
||||
self._data['current'] = current
|
||||
self._data["current"] = current
|
||||
|
||||
return current
|
||||
|
||||
|
|
@ -1332,7 +1335,7 @@ class GaugeTrait(CounterTrait):
|
|||
def min(self, value):
|
||||
"""Limit so min can never be greater than base+mod."""
|
||||
if value is None:
|
||||
self._data["min"] = self.default_keys['min']
|
||||
self._data["min"] = self.default_keys["min"]
|
||||
elif type(value) in (int, float):
|
||||
self._data["min"] = min(value, self.base + self.mod)
|
||||
|
||||
|
|
@ -1343,18 +1346,22 @@ class GaugeTrait(CounterTrait):
|
|||
|
||||
@max.setter
|
||||
def max(self, value):
|
||||
raise TraitException("The .max property is not settable "
|
||||
"on GaugeTraits. Set .base instead.")
|
||||
raise TraitException(
|
||||
"The .max property is not settable " "on GaugeTraits. Set .base instead."
|
||||
)
|
||||
|
||||
@max.deleter
|
||||
def max(self):
|
||||
raise TraitException("The .max property cannot be reset "
|
||||
"on GaugeTraits. Reset .mod and .base instead.")
|
||||
raise TraitException(
|
||||
"The .max property cannot be reset " "on GaugeTraits. Reset .mod and .base instead."
|
||||
)
|
||||
|
||||
@property
|
||||
def current(self):
|
||||
"""The `current` value of the gauge."""
|
||||
return self._update_current(self._enforce_boundaries(
|
||||
self._data.get("current", self.base + self.mod)))
|
||||
return self._update_current(
|
||||
self._enforce_boundaries(self._data.get("current", self.base + self.mod))
|
||||
)
|
||||
|
||||
@current.setter
|
||||
def current(self, value):
|
||||
|
|
|
|||
|
|
@ -318,6 +318,7 @@ class TestPercent(TestCase):
|
|||
"""
|
||||
Test the utils.percentage function.
|
||||
"""
|
||||
|
||||
def test_ok_input(self):
|
||||
result = utils.percent(3, 0, 10)
|
||||
self.assertEqual(result, "30.0%")
|
||||
|
|
@ -332,4 +333,3 @@ class TestPercent(TestCase):
|
|||
self.assertEqual(utils.percent(3, 1, 1), "0.0%")
|
||||
self.assertEqual(utils.percent(3, 0, 1), "100.0%")
|
||||
self.assertEqual(utils.percent(-3, 0, 1), "0.0%")
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue