Make options accept default kwarg, add new raise_exception. Fix datetime validatorfunc accoring to spec. Resolves #1967.

This commit is contained in:
Griatch 2020-01-20 23:20:05 +01:00
parent 6e561d95a1
commit bfe533441e
5 changed files with 38 additions and 14 deletions

View file

@ -42,6 +42,8 @@ without arguments starts a full interactive Python console.
- Improve performance of `find` and `objects` commands on large data sets (strikaco)
- New `CHANNEL_HANDLER_CLASS` setting allows for replacing the ChannelHandler entirely.
- Made `py` interactive mode support regular quit() and more verbose.
- Made `Account.options.get` accept `default=None` kwarg to mimic other uses of get. Set
the new `raise_exception` boolean if ranting to raise KeyError on a missing key.
## Evennia 0.9 (2018-2019)

View file

@ -105,9 +105,9 @@ class AccountDB(TypedObject, AbstractUser):
objects = AccountDBManager()
# defaults
__settingsclasspath__ = settings.BASE_SCRIPT_TYPECLASS
__defaultclasspath__ = "evennia.accounts.accounts.DefaultAccount"
__applabel__ = "accounts"
__settingsclasspath__ = settings.BASE_SCRIPT_TYPECLASS
class Meta(object):
verbose_name = "Account"

View file

@ -24,8 +24,7 @@ class InMemorySaveHandler(object):
class OptionHandler(object):
"""
This is a generic Option handler. It is commonly used
implements AttributeHandler. Retrieve options eithers as properties on
This is a generic Option handler. Retrieve options either as properties on
this handler or by using the .get method.
This is used for Account.options but it could be used by Scripts or Objects
@ -54,7 +53,7 @@ class OptionHandler(object):
It will be called as `savefunc(key, value, **save_kwargs)`. A common one
to pass would be AttributeHandler.add.
loadfunc (callable): A callable for all options to call when loading data into
itself. It will be called as `loadfunc(key, default=default, **load_kwargs)`.
itself. It will be called as `loadfunc(key, default=default, **load_kwargs)`.
A common one to pass would be AttributeHandler.get.
save_kwargs (any): Optional extra kwargs to pass into `savefunc` above.
load_kwargs (any): Optional extra kwargs to pass into `loadfunc` above.
@ -116,14 +115,16 @@ class OptionHandler(object):
self.options[key] = loaded_option
return loaded_option
def get(self, key, return_obj=False):
def get(self, key, default=None, return_obj=False, raise_error=False):
"""
Retrieves an Option stored in the handler. Will load it if it doesn't exist.
Args:
key (str): The option key to retrieve.
default (any): What to return if the option is defined.
return_obj (bool, optional): If True, returns the actual option
object instead of its value.
raise_error (bool, optional): Raise Exception if key is not found in options.
Returns:
option_value (any or Option): An option value the Option itself.
Raises:
@ -131,7 +132,10 @@ class OptionHandler(object):
"""
if key not in self.options_dict:
raise KeyError("Option not found!")
if raise_error:
raise KeyError("Option not found!")
return default
# get the options or load/recache it
op_found = self.options.get(key) or self._load_option(key)
return op_found if return_obj else op_found.value

View file

@ -32,6 +32,11 @@ class TestValidatorFuncs(TestCase):
self.assertTrue(
isinstance(validatorfuncs.datetime(dt, from_tz=pytz.UTC), datetime.datetime)
)
account = mock.MagicMock()
account.options.get = mock.MagicMock(return_value="America/Chicago")
expected = datetime.datetime(1492, 10, 12, 6, 51, tzinfo=pytz.UTC)
self.assertEqual(expected, validatorfuncs.datetime("Oct 12 1:00 1492", account=account))
account.options.get.assert_called_with("timezone", "UTC")
def test_datetime_raises_ValueError(self):
for dt in ["", "January 1, 2019", "1/1/2019", "Jan 1 2019"]:
@ -121,6 +126,7 @@ class TestValidatorFuncs(TestCase):
validatorfuncs.boolean(b)
def test_timezone_ok(self):
for tz in ["America/Chicago", "GMT", "UTC"]:
self.assertEqual(tz, validatorfuncs.timezone(tz).zone)

View file

@ -40,24 +40,36 @@ def color(entry, option_key="Color", **kwargs):
def datetime(entry, option_key="Datetime", account=None, from_tz=None, **kwargs):
"""
Process a datetime string in standard forms while accounting for the inputter's timezone.
Process a datetime string in standard forms while accounting for the inputer's timezone. Always
returns a result in UTC.
Args:
entry (str): A date string from a user.
option_key (str): Name to display this datetime as.
account (AccountDB): The Account performing this lookup. Unless from_tz is provided,
account's timezone will be used (if found) for local time and convert the results
to UTC.
from_tz (pytz): An instance of pytz from the user. If not provided, defaults to whatever
the Account uses. If neither one is provided, defaults to UTC.
account (AccountDB): The Account performing this lookup. Unless `from_tz` is provided,
the account's timezone option will be used.
from_tz (pytz.timezone): An instance of a pytz timezone object from the
user. If not provided, tries to use the timezone option of the `account'.
If neither one is provided, defaults to UTC.
Returns:
datetime in utc.
datetime in UTC.
Raises:
ValueError: If encountering a malformed timezone, date string or other format error.
"""
if not entry:
raise ValueError(f"No {option_key} entered!")
if not from_tz:
from_tz = _pytz.UTC
if account:
acct_tz = account.options.get("timezone", "UTC")
try:
from_tz = _pytz.timezone(acct_tz)
except Exception as err:
raise ValueError(f"Timezone string '{acct_tz}' is not a valid timezone ({err})")
else:
from_tz = _pytz.UTC
utc = _pytz.UTC
now = _dt.datetime.utcnow().replace(tzinfo=utc)
cur_year = now.strftime("%Y")