예제 #1
0
	def trace(self, obj, **kwargs):
		'''DictShapes are defined by a mapping from keys to the shapes of their values.
		The outline is stored as a frozendict since Shapes must be immutable and hashable.
		'''
		outline = {}
		for k,v in obj.items():
			outline[k] = factory(v, **kwargs)
		return frozendict(outline)
예제 #2
0
	def generator(cls, **kwargs):
		'''Generate a random DictShape'''
		output = {}
		no_keys = random.randint(1,3)
		keys = [value_generator(str) for _ in range(0,no_keys)]
		for key in keys:
			output[key] = random_shape(hashable=kwargs.get('hashable'))
		return DictShape(frozendict(output), from_outline=True)
예제 #3
0
	def shrink(self, **kwargs):
		'''Delete a random number of keys and shrink a random number of remaining values'''
		compression = {}
		no_keys_to_delete = random.randint(0,len(self) - 1)
		keys_to_keep = random.sample(self.keys(), len(self) - no_keys_to_delete)
		shrink_probability = min(0.5, 1/(len(keys_to_keep)+1))
		for key in keys_to_keep:
			if random.random() <= shrink_probability:
				compression[key] = self[key].shrink()
			else:
				compression[key] = self[key]
		return DictShape(frozendict(compression), from_outline=True)
예제 #4
0
	def __add__(self, other):
		'''Two DictShapes may be added if any keys that they share have the same shaped value. 
		The sum is comprised of all key/value pairs in both DictShapes.'''
		if isinstance(other, DictShape):
			output = {}
			shared_keys = set(self.keys()).intersection(other.keys())
			for key in shared_keys:
				if self[key] != other[key]:
					raise CouldNotAddError('You can not add these DictShapes as their shared keys have differing shapes for their values.')
			for key,value in set(self.items()).union(other.items()):
				output[key] = value
			return DictShape(frozendict(output), from_outline=True)
		return NotImplemented
예제 #5
0
	def extend(self, **kwargs):
		'''Extend the values of the current keys, and add a random number of new key/shape pairs'''
		extension = {}
		for k,v in self.items():
			extension[k] = v.extend(**kwargs)
		no_extra_keys = random.randint(0,1)
		for _ in range(0,no_extra_keys):
			while True:
				key = value_generator(str)
				if not key in self:
					break
				else:
					continue
			extension[key] = random_shape()
		return DictShape(frozendict(extension), from_outline=True)
예제 #6
0
    def _make_hashable(obj):
        # If we're a list or a tuple, make each object hashable.
        if isinstance(obj, list) or isinstance(obj, tuple):
            return tuple(_make_hashable(x) for x in obj)

        # If we're not a dictionary, no need to make hashable.
        if not isinstance(obj, dict):
            return obj

        # Dictionaries need to recursively freeze inner dictionaries.
        new_dict = dict()
        for (key, val) in obj.items():
            if isinstance(val, dict):
                val = _make_hashable(val)
            new_dict[key] = val
        return frozendict(new_dict)