def _overwrite_colnames(self, frame, names): if frame.columns.nlevels > 1: raise ValueError("columns must not be MultiIndex") cells_names = list(frame.columns) if names is not None: is_overwritten = [is_valid_name(n) for n in names ] + [False] * max(len(cells_names) - len(names), 0) cells_names = [ names[i] if is_overwritten[i] else n for i, n in enumerate(cells_names) ] else: is_overwritten = [False] * len(cells_names) for name in cells_names: if not is_valid_name(name): raise ValueError("%s is not a valid name" % name) else: if name in self.namespace: raise ValueError("%s already exists" % name) return cells_names
def __init__(self, *, space, name=None, formula=None, data=None, base=None, source=None, is_derived=False): # Determine name if base: name = base.name elif is_valid_name(name): pass elif formula: name = Formula(formula).name if is_valid_name(name): pass else: name = space.cellsnamer.get_next(space.namespace) else: name = space.cellsnamer.get_next(space.namespace) Impl.__init__(self, system=space.system, parent=space, name=name) self.spacemgr = space.spacemgr Derivable.__init__(self, is_derived) self.source = source space._cells.set_item(name, self) # Set formula if base: self.formula = base.formula elif formula is None: self.formula = NullFormula(NULL_FORMULA, name=name) elif isinstance(formula, Formula): self.formula = formula.__class__(formula, name=name) else: self.formula = Formula(formula, name=name) # Set data self.data = {} if data is None: data = {} self.data.update(data) self.input_keys = set(data.keys()) CellsNamespaceReferrer.__init__(self, space) self._namespace = self.parent._namespace if base: self.altfunc = BoundFunction(self, base.altfunc.fresh) else: self.altfunc = BoundFunction(self)
def set_attr(self, name, value): """Implementation of attribute setting ``space.name = value`` by user script Called from ``Space.__setattr__`` """ if not is_valid_name(name): raise ValueError("Invalid name '%s'" % name) if name in self.namespace: if name in self.refs: if name in self.self_refs: self.new_ref(name, value) else: raise KeyError("Ref '%s' cannot be changed" % name) elif name in self.cells: if self.cells[name].is_scalar(): self.cells[name].set_value((), value) else: raise AttributeError("Cells '%s' is not a scalar." % name) else: raise ValueError else: self.new_ref(name, value)
def __init__(self, *, system, name): if not name: name = system._modelnamer.get_next(system.models) elif not is_valid_name(name): raise ValueError("Invalid name '%s'." % name) Impl.__init__(self, system=system, parent=None, name=name) EditableSpaceContainerImpl.__init__(self) TraceManager.__init__(self) self.spacemgr = SpaceManager(self) self.currentspace = None self._global_refs = RefDict(self) self._global_refs.set_item("__builtins__", builtins) self._named_spaces = SpaceDict(self) self._dynamic_bases = SpaceDict(self) self._all_spaces = ImplChainMap( self, SpaceView, [self._named_spaces, self._dynamic_bases]) self._dynamic_bases_inverse = {} self._dynamic_base_namer = AutoNamer("__Space") self._namespace = ImplChainMap(self, BaseView, [self._named_spaces, self._global_refs]) self.allow_none = False self.lazy_evals = self._namespace self.datarefmgr = DataClientReferenceManager()
def __init__(self, *, system, name): Impl.__init__(self, system=system) EditableSpaceContainerImpl.__init__(self) self.cellgraph = DependencyGraph() self.lexdep = DependencyGraph() # Lexical dependency self.spacegraph = SpaceGraph() self.currentspace = None if not name: self.name = system._modelnamer.get_next(system.models) elif is_valid_name(name): self.name = name else: raise ValueError("Invalid name '%s'." % name) data = {"__builtins__": builtins} self._global_refs = RefDict(self, data=data) self._spaces = ImplDict(self, SpaceView) self._dynamic_bases = {} self._dynamic_bases_inverse = {} self._dynamic_base_namer = AutoNamer("__Space") self._namespace = ImplChainMap(self, BaseView, [self._spaces, self._global_refs]) self.allow_none = False self.lazy_evals = self._namespace
def _new_cells_from_series(self, series, name, param, source): if is_valid_name(name): pass else: if is_valid_name(series.name): name = series.name cells = self.new_cells(name=name, formula=get_param_func( _get_param_names(series, param)), source=source) for i, v in series.items(): cells.set_value(tuplize_key(cells, i), v.item() if isinstance(v, np.generic) else v) return cells
def __init__(self, *, space, name=None, formula=None, data=None, base=None, source=None): Impl.__init__(self, system=space.system) Derivable.__init__(self) self._model = space.model self.space = self.parent = space self.source = source if base: self.name = base.name elif is_valid_name(name): self.name = name elif formula: name = Formula(formula).name if is_valid_name(name): self.name = name else: self.name = space.cellsnamer.get_next(space.namespace) else: self.name = space.cellsnamer.get_next(space.namespace) if base: self.formula = base.formula elif formula is None: self.formula = NullFormula(NULL_FORMULA, name=self.name) elif isinstance(formula, Formula): self.formula = formula.__class__(formula, name=self.name) else: self.formula = Formula(formula, name=self.name) self.data = {} if data is None: data = {} self.data.update(data) self._namespace_impl = self.space._namespace_impl self.altfunc = BoundFunction(self)
def new_space( self, name=None, bases=None, formula=None, *, refs=None, source=None, is_derived=False, prefix="", doc=None ): """Create a new child space. Args: name (str): Name of the space. If omitted, the space is created automatically. bases: If specified, the new space becomes a derived space of the `base` space. formula: Function whose parameters used to set space parameters. refs: a mapping of refs to be added. arguments: ordered dict of space parameter names to their values. source: A source module from which cell definitions are read. prefix: Prefix to the autogenerated name when name is None. """ from modelx.core.space import UserSpaceImpl if name is None: name = self.spacenamer.get_next(self.namespace, prefix) if name in self.namespace: raise ValueError("Name '%s' already exists." % name) if not prefix and not is_valid_name(name): raise ValueError("Invalid name '%s'." % name) space = self._new_space( name=name, formula=formula, refs=refs, source=source, doc=doc, is_derived=is_derived, ) self._set_space(space) self.model.spacegraph.add_space(space) # Set up direct base spaces and mro if bases is not None: if isinstance(bases, UserSpaceImpl): bases = [bases] space.add_bases(bases) return space
def rename(self, name): """Rename self. Must be called only by its system.""" if is_valid_name(name): if name not in self.system.models: self.name = name return True # Rename success else: # Model name already exists return False else: raise ValueError("Invalid name '%s'." % name)
def _get_param_names(obj, param): """Get list of param names from Series or DataFrame and ``param``""" param_len = obj.index.nlevels if param_len == 1 and isinstance(param, str): param = [param] param_names = list(obj.index.names) if param: param = param + [None] * max(param_len - len(param), 0) param_names = [ param[i] if is_valid_name(param[i]) else n for i, n in enumerate(param_names) ] if not all([is_valid_name(n) for n in param_names]): raise ValueError("invalid parameter names") return param_names
def test_new_cells_from_frame(sample_model, sample_frame): df, cells_names, param_names = sample_frame space = sample_model.new_space() space.new_cells_from_pandas(df, cells=cells_names, param=param_names) if int(pd.__version__.split(".")[0]) < 24: assert np.array_equal(space.frame.values, df.values) else: assert np.array_equal(space.frame.to_numpy(), df.to_numpy()) names = tuple(c if is_valid_name(c) else cells_names[i] for i, c in enumerate(df.columns)) params = tuple(p or param_names[i] for i, p in enumerate(df.index.names)) assert tuple(space.frame.columns) == names assert tuple(space.frame.index.names) == params
def restore_model(self, path, name, datapath): with open(path, "rb") as file: model = SystemUnpickler(file, self).load() model._impl.restore_state(datapath) if name is not None: if not is_valid_name(name): raise ValueError("Invalid name '%s'." % name) newname = name or model.name if newname in self.models: self._rename_samename(newname) if name is not None: if not model._impl.rename(name): raise RuntimeError("must not happen") self.models[newname] = model._impl self.currentmodel = model._impl return model
def _new_dynspace( self, name=None, bases=None, formula=None, refs=None, arguments=None, source=None, ): """Create a new dynamic root space.""" if name is None: name = self.spacenamer.get_next(self.namespace) if name in self.namespace: raise ValueError("Name '%s' already exists." % name) if not is_valid_name(name): raise ValueError("Invalid name '%s'." % name) space = RootDynamicSpaceImpl( parent=self, name=name, formula=formula, refs=refs, source=source, arguments=arguments, ) space.is_derived = False self._set_space(space) if bases: # i.e. not [] dynbase = self._get_dynamic_base(bases) space._dynbase = dynbase dynbase._dynamic_subs.append(space) return space
def new_space( self, parent, name=None, bases=None, formula=None, refs=None, source=None, is_derived=False, prefix="", doc=None, set_space=True ): """Create a new child space. Args: name (str): Name of the space. If omitted, the space is created automatically. bases: If specified, the new space becomes a derived space of the `base` space. formula: Function whose parameters used to set space parameters. refs: a mapping of refs to be added. source: A source module from which cell definitions are read. prefix: Prefix to the autogenerated name when name is None. """ if name is None: while True: name = parent.spacenamer.get_next(parent.namespace, prefix) if self.can_add(parent, name, UserSpaceImpl): break elif not self.can_add(parent, name, UserSpaceImpl): raise ValueError("Cannot create space '%s'" % name) if not prefix and not is_valid_name(name): raise ValueError("Invalid name '%s'." % name) if bases is None: bases = [] elif isinstance(bases, UserSpaceImpl): bases = [bases] if parent.is_model(): node = name pnode = [] else: node = parent.get_fullname(omit_model=True) + "." + name pnode = [parent.get_fullname(omit_model=True)] nodes = pnode + [ b.get_fullname(omit_model=True) for b in bases] subg_inh = self._inheritance.subgraph_from_nodes( nodes, self.backup_hook) subg = subg_inh.get_derived_graph() newsubg_inh = subg_inh.copy_as_spacegraph(subg_inh) space = UserSpaceImpl( parent, name, formula=formula, refs=refs, source=source, doc=doc) space.is_derived = is_derived if set_space: parent._set_space(space) newsubg_inh.add_node( node, mode="defined", state="created", space=space) for b in bases: base = b.get_fullname(omit_model=True) newsubg_inh.add_edge( base, node, mode="defined", index=newsubg_inh.max_index(node) ) if not nx.is_directed_acyclic_graph(newsubg_inh): raise ValueError("cyclic inheritance") if not newsubg_inh.check_cyclic(node, node): raise ValueError("cyclic inheritance through composition") newsubg_inh.get_mro(node) # Check if MRO is possible newsubg = newsubg_inh.get_derived_graph(on_edge=self.derive_hook) if not nx.is_directed_acyclic_graph(newsubg): raise ValueError("cyclic inheritance") # Check if MRO is possible for each node in sub graph for n in nx.descendants(newsubg, node): newsubg.get_mro(n) self.update_graphs(newsubg_inh, newsubg, subg_inh, subg) return space
def test_is_valid_name_invalid(name): assert not is_valid_name(name)
def test_is_valid_name_valid(name): assert is_valid_name(name)
def new_space(self, parent, name=None, bases=None, formula=None, refs=None, source=None, is_derived=False, prefix="", doc=None, container=None): """Create a new child space. Args: name (str): Name of the space. If omitted, the space is created automatically. bases: If specified, the new space becomes a derived space of the `base` space. formula: Function whose parameters used to set space parameters. refs: a mapping of refs to be added. source: A source module from which cell definitions are read. prefix: Prefix to the autogenerated name when name is None. """ if name is None: while True: name = parent.spacenamer.get_next(parent.namespace, prefix) if self._can_add(parent, name, UserSpaceImpl): break elif not self._can_add(parent, name, UserSpaceImpl): raise ValueError("Cannot create space '%s'" % name) if not prefix and not is_valid_name(name): raise ValueError("Invalid name '%s'." % name) if bases is None: bases = [] elif isinstance(bases, UserSpaceImpl): bases = [bases] if parent.is_model(): node = name pnode = [] else: node = parent.namedid + "." + name pnode = [parent.namedid] nodes = pnode + [b.namedid for b in bases] oldsubg_inherit = self._inheritance.subgraph_from_nodes(nodes) oldsubg = oldsubg_inherit.get_derived_graph() newsubg_inherit = oldsubg_inherit.copy_as_spacegraph(oldsubg_inherit) newsubg_inherit.add_node(node, mode="defined", state="defined") for b in bases: base = b.namedid newsubg_inherit.add_edge(base, node, mode="defined", index=newsubg_inherit.max_index(node)) if not nx.is_directed_acyclic_graph(newsubg_inherit): raise ValueError("cyclic inheritance") if not newsubg_inherit.check_cyclic(node, node): raise ValueError("cyclic inheritance through composition") newsubg_inherit.get_mro(node) # Check if MRO is possible for pnode in newsubg_inherit.get_parent_nodes(node): newsubg_inherit.nodes[pnode]["mode"] = "defined" start = [(tail, node) for tail in newsubg_inherit.ordered_preds(node)] newsubg = newsubg_inherit.get_derived_graph(on_edge=self._derive_hook, start=start) if not nx.is_directed_acyclic_graph(newsubg): raise ValueError("cyclic inheritance") # Check if MRO is possible for each node in sub graph for n in nx.descendants(newsubg, node): newsubg.get_mro(n) if not parent.is_model(): parent.set_defined() if container is None: container = parent._named_spaces space = UserSpaceImpl(parent, name, container, is_derived, formula=formula, refs=refs, source=source, doc=doc) newsubg.nodes[node]["space"] = space newsubg.nodes[node]["state"] = "created" self._instructions.execute() self._update_graphs(newsubg_inherit, newsubg, oldsubg_inherit, oldsubg) return space