def __convert_and_store(self, item, value): if self._box_config["conversion_box"]: safe_key = self._safe_attr(item) self._box_config["__safe_keys"][safe_key] = item if isinstance(value, (int, float, str, bytes, bytearray, bool, complex, set, frozenset)): return super().__setitem__(item, value) # If the value has already been converted or should not be converted, return it as-is if self._box_config["box_intact_types"] and isinstance( value, self._box_config["box_intact_types"]): return super().__setitem__(item, value) # This is the magic sauce that makes sub dictionaries into new box objects if isinstance(value, dict): # We always re-create even if it was already a Box object to pass down configurations correctly value = self._box_config["box_class"](value, **self.__box_config()) elif isinstance(value, list) and not isinstance(value, box.BoxList): if self._box_config["frozen_box"]: value = _recursive_tuples( value, recreate_tuples=self._box_config["modify_tuples_box"], **self.__box_config()) else: value = box.BoxList(value, **self.__box_config()) elif isinstance(value, box.BoxList): value.box_options.update(self.__box_config()) elif self._box_config["modify_tuples_box"] and isinstance( value, tuple): value = _recursive_tuples(value, recreate_tuples=True, **self.__box_config()) super().__setitem__(item, value)
def __convert_and_store(self, item, value, force_conversion=False): # If the value has already been converted or should not be converted, return it as-is if ((item in self._box_config['__converted'] and not force_conversion) or (self._box_config['box_intact_types'] and isinstance(value, self._box_config['box_intact_types']))): return value value = self.__recast(item, value) # This is the magic sauce that makes sub dictionaries into new box objects if isinstance(value, dict) and not isinstance(value, Box): value = self.__class__(value, **self.__box_config()) super(Box, self).__setitem__(item, value) elif isinstance(value, list) and not isinstance(value, box.BoxList): if self._box_config['frozen_box']: value = _recursive_tuples( value, self.__class__, recreate_tuples=self._box_config['modify_tuples_box'], **self.__box_config()) else: value = box.BoxList(value, box_class=self.__class__, **self.__box_config()) elif self._box_config['modify_tuples_box'] and isinstance( value, tuple): value = _recursive_tuples(value, self.__class__, recreate_tuples=True, **self.__box_config()) super(Box, self).__setitem__(item, value) self._box_config['__converted'].add(item)
def __convert_and_store(self, item, value): if self._box_config['conversion_box']: safe_key = self._safe_attr(item) self._box_config['__safe_keys'][safe_key] = item if isinstance(value, (int, float, str, bytes, bytearray, bool, complex, set, frozenset)): return super().__setitem__(item, value) # If the value has already been converted or should not be converted, return it as-is if self._box_config['box_intact_types'] and isinstance( value, self._box_config['box_intact_types']): return super().__setitem__(item, value) # This is the magic sauce that makes sub dictionaries into new box objects if isinstance(value, dict) and not isinstance(value, Box): value = self.__class__(value, **self.__box_config()) elif isinstance(value, list) and not isinstance(value, box.BoxList): if self._box_config['frozen_box']: value = _recursive_tuples( value, self.__class__, recreate_tuples=self._box_config['modify_tuples_box'], **self.__box_config()) else: value = box.BoxList(value, box_class=self.__class__, **self.__box_config()) elif self._box_config['modify_tuples_box'] and isinstance( value, tuple): value = _recursive_tuples(value, self.__class__, recreate_tuples=True, **self.__box_config()) super().__setitem__(item, value)
def setdefault(self, item, default=None): if item in self: return self[item] if isinstance(default, dict): default = self._box_config["box_class"](default, **self.__box_config()) if isinstance(default, list): default = box.BoxList(default, **self.__box_config()) self[item] = default return self[item]
def convert_and_set(k, v): intact_type = self._box_config["box_intact_types"] and isinstance( v, self._box_config["box_intact_types"]) if isinstance(v, dict) and not intact_type: # Box objects must be created in case they are already # in the `converted` box_config set v = self._box_config["box_class"](v, **self.__box_config()) if k in self and isinstance(self[k], dict): self[k].merge_update(v) return if isinstance(v, list) and not intact_type: v = box.BoxList(v, **self.__box_config()) self.__setitem__(k, v)
def get(self, key, default=NO_DEFAULT): if key not in self: if default is NO_DEFAULT: if self._box_config["default_box"] and self._box_config["default_box_none_transform"]: return self.__get_default(key) else: return None if isinstance(default, dict) and not isinstance(default, Box): return Box(default) if isinstance(default, list) and not isinstance(default, box.BoxList): return box.BoxList(default) return default return self[key]
def convert_and_set(k, v): intact_type = (self._box_config['box_intact_types'] and isinstance( v, self._box_config['box_intact_types'])) if isinstance(v, dict) and not intact_type: # Box objects must be created in case they are already # in the `converted` box_config set v = self.__class__(v, **self.__box_config()) if k in self and isinstance(self[k], dict): self[k].update(v) return if isinstance(v, list) and not intact_type: v = box.BoxList(v, **self.__box_config()) try: self.__setattr__(k, v) except (AttributeError, TypeError): self.__setitem__(k, v)
def __get_default(self, item): default_value = self._box_config['default_box_attr'] if default_value in (self.__class__, dict): value = self.__class__(**self.__box_config()) elif isinstance(default_value, dict): value = self.__class__(**self.__box_config(), **default_value) elif isinstance(default_value, list): value = box.BoxList(**self.__box_config()) elif isinstance(default_value, Callable): value = default_value() elif hasattr(default_value, 'copy'): value = default_value.copy() else: value = default_value self.__convert_and_store(item, value) return value
def __get_default(self, item, attr=False): default_value = self._box_config["default_box_attr"] if default_value in (self._box_config["box_class"], dict): value = self._box_config["box_class"](**self.__box_config()) elif isinstance(default_value, dict): value = self._box_config["box_class"](**self.__box_config(), **default_value) elif isinstance(default_value, list): value = box.BoxList(**self.__box_config()) elif isinstance(default_value, Callable): value = default_value() elif hasattr(default_value, "copy"): value = default_value.copy() else: value = default_value if not attr or (not item.startswith("_") and not item.endswith("_")): super().__setitem__(item, value) return value
def convert_and_set(k, v): intact_type = self._box_config["box_intact_types"] and isinstance(v, self._box_config["box_intact_types"]) if isinstance(v, dict) and not intact_type: # Box objects must be created in case they are already # in the `converted` box_config set v = self._box_config["box_class"](v, **self.__box_config()) if k in self and isinstance(self[k], dict): self[k].merge_update(v) return if isinstance(v, list) and not intact_type: v = box.BoxList(v, **self.__box_config()) merge_type = kwargs.get('box_merge_lists') if merge_type == "extend" and k in self and isinstance(self[k], list): self[k].extend(v) return if merge_type == "unique" and k in self and isinstance(self[k], list): for item in v: if item not in self[k]: self[k].append(item) return self.__setitem__(k, v)