11from __future__ import annotations
22
33import os
4+ from logging import getLogger
45from typing import Any , Callable , Generic , TypeVar , cast
56
67
78_O = TypeVar ("_O" )
9+ logger = getLogger (__name__ )
810
911
1012class Option (Generic [_O ]):
@@ -17,11 +19,18 @@ def __init__(
1719 mutable : bool = True ,
1820 validator : Callable [[Any ], _O ] = lambda x : cast (_O , x ),
1921 ) -> None :
20- self .name = name
22+ self ._name = name
2123 self ._default = default
2224 self ._mutable = mutable
2325 self ._validator = validator
24- self ._value = validator (os .environ .get (name , default ))
26+ if name in os .environ :
27+ self ._value = validator (os .environ [name ])
28+ logger .debug (f"{ self ._name } ={ self .get ()} " )
29+
30+ @property
31+ def name (self ) -> str :
32+ """The name of this option (used to load environment variables)"""
33+ return self ._name
2534
2635 @property
2736 def mutable (self ) -> bool :
@@ -33,24 +42,48 @@ def default(self) -> _O:
3342 """This option's default value"""
3443 return self ._default
3544
45+ def is_set (self ) -> bool :
46+ """Whether this option has a value other than its default."""
47+ return hasattr (self , "_value" )
48+
3649 def get (self ) -> _O :
3750 """Get the current value of this option."""
38- return self . _value
51+ return getattr ( self , " _value" , self . _default )
3952
40- def set (self , new : _O ) -> _O :
41- """Set the value of this configuration option
53+ def set (self , new : _O ) -> None :
54+ """Set the value of this option
4255
4356 Raises a ``TypeError`` if this option is not :attr:`Option.mutable`.
4457 """
4558 if not self ._mutable :
4659 raise TypeError (f"{ self } cannot be modified after initial load" )
47- old = self ._value
4860 self ._value = self ._validator (new )
49- return old
61+ logger .debug (f"{ self ._name } ={ self ._value } " )
62+
63+ def set_default (self , new : _O ) -> _O :
64+ """Set the value of this option if :meth:`Option.is_default`
65+
66+ Returns the current value (a la :meth:`dict.set_default`)
67+ """
68+ if not hasattr (self , "_value" ):
69+ self .set (new )
70+ return self ._value
5071
51- def reset (self ) -> _O :
52- """Reset the value of this option to its default setting"""
53- return self .set (self ._default )
72+ def reload (self ) -> None :
73+ """Reload this option from its environment variable
74+
75+ Returns the old value of the option.
76+ """
77+ self .set (os .environ .get (self ._name , self ._default ))
78+
79+ def reset (self ) -> None :
80+ """Reset the value of this option to its default setting
81+
82+ Returns the old value of the option.
83+ """
84+ if not self ._mutable :
85+ raise TypeError (f"{ self } cannot be modified after initial load" )
86+ delattr (self , "_value" )
5487
5588 def __repr__ (self ) -> str :
56- return f"Option({ self .name } ={ self ._value !r} )"
89+ return f"Option({ self ._name } ={ self .get () !r} )"
0 commit comments