Skip to content

Commit

Permalink
ENH: Add _parent in namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
fumitoh committed Jul 13, 2024
1 parent 8a257c2 commit 70bdf70
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 2 deletions.
3 changes: 2 additions & 1 deletion modelx/core/space.py
Original file line number Diff line number Diff line change
Expand Up @@ -1377,7 +1377,8 @@ def __init__(
self._cells = CellsDict("cells", self)
self._named_spaces = SpaceDict("named_spaces", self)
self._sys_refs = LazyEvalDict("sys_refs",
{"_self": self, "_space": self, "_model": self.model})
{"_self": self, "_space": self,
"_model": self.model, "_parent": self.parent})
self._refs = self._init_refs(arguments)

NamespaceServer.__init__(
Expand Down
10 changes: 9 additions & 1 deletion modelx/tests/core/space/test_space.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
def testmodel():

model, space = new_model(name="testmodel"), new_space(name="testspace")
space.parameters = ("a",)

@defcells(space)
def foo(x):
Expand All @@ -19,6 +20,10 @@ def foo(x):
else:
return foo(x - 1)

@defcells(space)
def get_parent():
return _parent

space.bar = 3

yield model
Expand All @@ -31,13 +36,16 @@ def test_refs(testmodel):


def test_dir(testmodel):
assert {"foo", "bar", "_self", "_space", "__builtins__", "_model"} == set(
assert {"foo", "bar", "get_parent",
"_self", "_space", "__builtins__", "_model", "_parent"} == set(
dir(testmodel.testspace)
)


def test_parent(testmodel):
assert cur_space().parent == testmodel
assert cur_space().get_parent == testmodel
assert cur_space()[1].get_parent == cur_space()


def test_create(testmodel):
Expand Down
54 changes: 54 additions & 0 deletions modelx/tests/export/test_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,60 @@ def test_model_path(tmp_path_factory):
from ModelPath_nomx import mx_model
assert mx_model.Space1.foo() == nomx_path / 'ModelPath_nomx'

finally:
sys.path.pop(0)
m.close()


def test_parent(tmp_path_factory):
"""Test if _parent is available both in the mx and nomx model
Code modified from: https://github.com/fumitoh/modelx/discussions/129
"""

m = mx.new_model()
RA = m.new_space("RA")

# Parameterize Space RA with `calc_loop`.
# This means RA creates exact copies of itself parameterized by calc_loop on the fly,
# such as RA[0], RA[1], RA[2], etc.
# They are dynamic child spaces of RA.
RA.parameters = ("calc_loop",)
RA.calc_loop = 0 # In RA

# Define BEL_LAPSE in RA. In the formula, calc_loop is the value given to the parameter of RA[calc_loop].
# For example, calc_loop == 0 in RA[0].BEL_LAPSE(), calc_loop == 1 in RA[1].BEL_LAPSE(), and so on.
# In the formula, `_space` is a special name that represents the parent space of the Cells.
# For example, _space is RA[2] in RA[2].BEL_LAPSE(). _space.parent represents the parent space of RA[2], which is RA.
# So, _space.parent[1].BEL_LAPSE() means RA[1].BEL_LAPSE()

@mx.defcells(space=RA)
def BEL_LAPSE():
if calc_loop == 0:
return 0
elif calc_loop == 1:
return 120
else:
return _space._parent[1].BEL_LAPSE()

assert RA.BEL_LAPSE() == 0
assert RA[0].BEL_LAPSE() == 0

for i in range(1, 5):
RA[i].BEL_LAPSE() == 120

nomx_path = tmp_path_factory.mktemp('model')
m.export(nomx_path / 'Parent_nomx')

try:
sys.path.insert(0, str(nomx_path))
from Parent_nomx import mx_model as nomx

assert nomx.RA.BEL_LAPSE() == 0
assert nomx.RA[0].BEL_LAPSE() == 0
for i in range(1, 5):
nomx.RA[i].BEL_LAPSE() == 120

finally:
sys.path.pop(0)
m.close()

0 comments on commit 70bdf70

Please sign in to comment.