def test_weakkeydict_setdefault(key=C(), value1="v1", value2="v2"): d = WeakKeyIDDictionary() o = d.setdefault(key, value1) assert o is value1 assert key in d assert d.get(key) is value1 assert d[key] is value1 o = d.setdefault(key, value2) assert o is value1 assert key in d assert d.get(key) is value1 assert d[key] is value1
def test_weakkeydict_update(in_d={C(): 1, C(): 2, C(): 3}): """This exercises d.update(), len(d), d.keys(), in d, d.get(), d[].""" d = WeakKeyIDDictionary() d.update(in_d) assert len(d) == len(in_d) for k in d.keys(): assert k in in_d, "mysterious new key appeared in weak dict" v = in_d.get(k) assert v is d[k] assert v is d.get(k) for k in in_d.keys(): assert k in d, "original key disappeared in weak dict" v = in_d[k] assert v is d[k] assert v is d.get(k)
class Parameter(object): """Simple descriptor for storing configuration parameters. Parameters ---------- default : object The value returned if the parameter hasn't been explicitly set. optional : bool, optional Whether this parameter accepts the value None. By default, parameters are not optional (i.e., cannot be set to ``None``). readonly : bool, optional If true, the parameter can only be set once. By default, parameters can be set multiple times. """ equatable = False def __init__(self, name, default=Unconfigurable, optional=False, readonly=None): # freeze Unconfigurables by default readonly = default is Unconfigurable if readonly is None else readonly if not is_string(name): raise ValueError("'name' must be a string (got %r)" % name) if not isinstance(optional, bool): raise ValueError("'optional' must be boolean (got %r)" % optional) if not isinstance(readonly, bool): raise ValueError("'readonly' must be boolean (got %r)" % readonly) self.name = name self.default = default self.optional = optional self.readonly = readonly # default values set by config system self._defaults = WeakKeyIDDictionary() # param values set on objects self.data = WeakKeyIDDictionary() def __contains__(self, key): return key in self.data or key in self._defaults def __delete__(self, instance): del self.data[instance] def __get__(self, instance, type_): if instance is None: # Return self so default can be inspected return self if not self.configurable and instance not in self.data: raise ValidationError( "Unconfigurable parameters have no defaults. Please ensure the" " value of the parameter is set before trying to access it.", attr=self.name, obj=instance) return self.data.get(instance, self.default) def __set__(self, instance, value): self.validate(instance, value) self.data[instance] = value def __repr__(self): return "%s(default=%s, optional=%s, readonly=%s)" % ( self.__class__.__name__, self.default, self.optional, self.readonly) @property def configurable(self): return self.default is not Unconfigurable def del_default(self, obj): del self._defaults[obj] def get_default(self, obj): return self._defaults.get(obj, self.default) def set_default(self, obj, value): if not self.configurable: raise ConfigError("Parameter '%s' is not configurable" % self) self.validate(obj, value) self._defaults[obj] = value def equal(self, instance_a, instance_b): a = self.__get__(instance_a, None) b = self.__get__(instance_b, None) if self.equatable: # always use array_equal, in case one argument is an array return np.array_equal(a, b) else: return a is b def hashvalue(self, instance): """Returns a hashable value (`hash` can be called on the output).""" value = self.__get__(instance, None) if self.equatable: return value else: return id(value) def validate(self, instance, value): if isinstance(value, DefaultType): raise ValidationError( "Default is not a valid value. To reset a " "parameter, use 'del'.", attr=self.name, obj=instance) if self.readonly and instance in self.data: raise ReadonlyError(attr=self.name, obj=instance) if not self.optional and value is None: raise ValidationError( "Parameter is not optional; cannot set to " "None", attr=self.name, obj=instance)
class Parameter(object): """Simple descriptor for storing configuration parameters. Parameters ---------- default : object The value returned if the parameter hasn't been explicitly set. optional : bool, optional Whether this parameter accepts the value None. By default, parameters are not optional (i.e., cannot be set to ``None``). readonly : bool, optional If true, the parameter can only be set once. By default, parameters can be set multiple times. """ equatable = False def __init__(self, default=Unconfigurable, optional=False, readonly=None): self.default = default self.optional = optional if readonly is None: # freeze Unconfigurables by default readonly = default is Unconfigurable self.readonly = readonly # default values set by config system self._defaults = WeakKeyIDDictionary() # param values set on objects self.data = WeakKeyIDDictionary() def __contains__(self, key): return key in self.data or key in self._defaults def __delete__(self, instance): del self.data[instance] def __get__(self, instance, type_): if instance is None: # Return self so default can be inspected return self if not self.configurable and instance not in self.data: raise ValueError( "Unconfigurable parameters have no defaults. " "Please ensure the value of the parameter is " "set before trying to access it." ) return self.data.get(instance, self.default) def __set__(self, instance, value): self.validate(instance, value) self.data[instance] = value def __repr__(self): return "%s(default=%s, optional=%s, readonly=%s)" % ( self.__class__.__name__, self.default, self.optional, self.readonly, ) @property def configurable(self): return self.default is not Unconfigurable def get_default(self, obj): return self._defaults.get(obj, self.default) def set_default(self, obj, value): if not self.configurable: raise ValueError("Parameter '%s' is not configurable" % self) self.validate(obj, value) self._defaults[obj] = value def del_default(self, obj): del self._defaults[obj] def validate(self, instance, value): if isinstance(value, DefaultType): raise ValueError("Default is not a valid value. To reset a " "parameter, use `del`.") if self.readonly and instance in self.data: raise ValueError("Parameter is read-only; cannot be changed.") if not self.optional and value is None: raise ValueError("Parameter is not optional; cannot set to None") def equal(self, instance_a, instance_b): a = self.__get__(instance_a, None) b = self.__get__(instance_b, None) if self.equatable: # always use array_equal, in case one argument is an array return np.array_equal(a, b) else: return a is b def hashvalue(self, instance): """Returns a hashable value (`hash` can be called on the output).""" value = self.__get__(instance, None) if self.equatable: return value else: return id(value)
class Parameter: """Simple descriptor for storing configuration parameters. Parameters ---------- name : str Name of the parameter. default : object The value returned if the parameter hasn't been explicitly set. optional : bool, optional Whether this parameter accepts the value None. By default, parameters are not optional (i.e., cannot be set to ``None``). readonly : bool, optional If true, the parameter can only be set once. By default, parameters can be set multiple times. Attributes ---------- coerce_defaults : bool If True, validate values for this parameter when they are set in a `.Config` object. Setting a parameter directly on an object will always be validated. equatable : bool If True, parameter values can be compared for equality (``a==b``); otherwise equality checks will just compare object identity (``a is b``). """ coerce_defaults = True equatable = False def __init__(self, name, default=Unconfigurable, optional=False, readonly=None): # freeze Unconfigurables by default readonly = default is Unconfigurable if readonly is None else readonly if not isinstance(name, str): raise ValueError("'name' must be a string (got %r)" % name) if not isinstance(optional, bool): raise ValueError("'optional' must be boolean (got %r)" % optional) if not isinstance(readonly, bool): raise ValueError("'readonly' must be boolean (got %r)" % readonly) self.name = name self.default = default self.optional = optional self.readonly = readonly # default values set by config system self._defaults = WeakKeyIDDictionary() # param values set on objects self.data = WeakKeyIDDictionary() def __getstate__(self): state = {} state.update(self.__dict__) state["_defaults"] = dict(state["_defaults"].items()) state["data"] = dict(state["data"].items()) return state def __setstate__(self, state): for k, v in state.items(): if k in ["_defaults", "data"]: v = WeakKeyIDDictionary(v) setattr(self, k, v) def __contains__(self, key): return key in self.data or key in self._defaults def __delete__(self, instance): del self.data[instance] def __get__(self, instance, type_): if instance is None: # Return self so default can be inspected return self if not self.configurable and instance not in self.data: raise ValidationError( "Unconfigurable parameters have no defaults. Please ensure the" " value of the parameter is set before trying to access it.", attr=self.name, obj=instance, ) return self.data.get(instance, self.default) def __set__(self, instance, value): self.data[instance] = self.coerce(instance, value) def __repr__(self): return "%s(%r, default=%s, optional=%s, readonly=%s)" % ( type(self).__name__, self.name, self.default, self.optional, self.readonly, ) @property def configurable(self): return self.default is not Unconfigurable def del_default(self, obj): del self._defaults[obj] def get_default(self, obj): return self._defaults.get(obj, self.default) def set_default(self, obj, value): if not self.configurable: raise ConfigError("Parameter '%s' is not configurable" % self) self._defaults[obj] = self.coerce( obj, value) if self.coerce_defaults else value def check_type(self, instance, value, type_): if value is not None and not isinstance(value, type_): if isinstance(type_, tuple): type_str = " or ".join((t.__name__ for t in type_)) else: type_str = type_.__name__ raise ValidationError( "Must be of type %r (got type %r)." % (type_str, type(value).__name__), attr=self.name, obj=instance, ) def coerce(self, instance, value): if isinstance(value, DefaultType): raise ValidationError( "Default is not a valid value. To reset a parameter, use 'del'.", attr=self.name, obj=instance, ) if self.readonly and instance in self.data: raise ReadonlyError(attr=self.name, obj=instance) if not self.optional and value is None: raise ValidationError( "Parameter is not optional; cannot set to None", attr=self.name, obj=instance, ) return value def equal(self, instance_a, instance_b): a = self.__get__(instance_a, None) b = self.__get__(instance_b, None) if self.equatable: return equal(a, b) else: return a is b def hashvalue(self, instance): """Returns a hashable value (`hash` can be called on the output).""" value = self.__get__(instance, None) if self.equatable: return value else: return id(value)
class Parameter: """Simple descriptor for storing configuration parameters. Parameters ---------- name : str Name of the parameter. default : object The value returned if the parameter hasn't been explicitly set. optional : bool, optional Whether this parameter accepts the value None. By default, parameters are not optional (i.e., cannot be set to ``None``). readonly : bool, optional If true, the parameter can only be set once. By default, parameters can be set multiple times. Attributes ---------- coerce_defaults : bool (Default: True) If True, validate values for this parameter when they are set in a `.Config` object. Setting a parameter directly on an object will always be validated. equatable : bool (Default: False) If True, parameter values can be compared for equality (``a==b``); otherwise equality checks will just compare object identity (``a is b``). """ coerce_defaults = True equatable = False def __init__(self, name, default=Unconfigurable, optional=False, readonly=None): # freeze Unconfigurables by default readonly = default is Unconfigurable if readonly is None else readonly if not isinstance(name, str): raise ValueError("'name' must be a string (got %r)" % name) if not isinstance(optional, bool): raise ValueError("'optional' must be boolean (got %r)" % optional) if not isinstance(readonly, bool): raise ValueError("'readonly' must be boolean (got %r)" % readonly) self.name = name self.default = default self.optional = optional self.readonly = readonly # default values set by config system self._defaults = WeakKeyIDDictionary() # param values set on objects self.data = WeakKeyIDDictionary() def __getstate__(self): state = {} state.update(self.__dict__) state['_defaults'] = dict(state['_defaults'].items()) state['data'] = dict(state['data'].items()) return state def __setstate__(self, state): for k, v in state.items(): if k in ['_defaults', 'data']: v = WeakKeyIDDictionary(v) setattr(self, k, v) def __contains__(self, key): return key in self.data or key in self._defaults def __delete__(self, instance): del self.data[instance] def __get__(self, instance, type_): if instance is None: # Return self so default can be inspected return self if not self.configurable and instance not in self.data: raise ValidationError( "Unconfigurable parameters have no defaults. Please ensure the" " value of the parameter is set before trying to access it.", attr=self.name, obj=instance) return self.data.get(instance, self.default) def __set__(self, instance, value): self.data[instance] = self.coerce(instance, value) def __repr__(self): return "%s(%r, default=%s, optional=%s, readonly=%s)" % ( type(self).__name__, self.name, self.default, self.optional, self.readonly) @property def configurable(self): return self.default is not Unconfigurable def del_default(self, obj): del self._defaults[obj] def get_default(self, obj): return self._defaults.get(obj, self.default) def set_default(self, obj, value): if not self.configurable: raise ConfigError("Parameter '%s' is not configurable" % self) self._defaults[obj] = (self.coerce(obj, value) if self.coerce_defaults else value) def check_type(self, instance, value, type_): if value is not None and not isinstance(value, type_): if isinstance(type_, tuple): type_str = " or ".join((t.__name__ for t in type_)) else: type_str = type_.__name__ raise ValidationError("Must be of type %r (got type %r)." % (type_str, type(value).__name__), attr=self.name, obj=instance) def coerce(self, instance, value): if isinstance(value, DefaultType): raise ValidationError("Default is not a valid value. To reset a " "parameter, use 'del'.", attr=self.name, obj=instance) if self.readonly and instance in self.data: raise ReadonlyError(attr=self.name, obj=instance) if not self.optional and value is None: raise ValidationError("Parameter is not optional; cannot set to " "None", attr=self.name, obj=instance) return value def equal(self, instance_a, instance_b): a = self.__get__(instance_a, None) b = self.__get__(instance_b, None) if self.equatable: return equal(a, b) else: return a is b def hashvalue(self, instance): """Returns a hashable value (`hash` can be called on the output).""" value = self.__get__(instance, None) if self.equatable: return value else: return id(value)