Skip to content

Commit

Permalink
Refactor execution namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
davidesarra committed Apr 5, 2021
1 parent 535a22d commit 3152b22
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 72 deletions.
31 changes: 5 additions & 26 deletions jupyter_spaces/space.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import ast
import sys
from collections import ChainMap

from jupyter_spaces.errors import RegistryError

Expand Down Expand Up @@ -68,9 +69,7 @@ def __init__(self, name, outer_space):
outer_space (dict): Outer namespace.
"""
self._name = name
self._execution_namespace = ExecutionNamespace(
global_references=outer_space, local_references={}
)
self._execution_namespace = _ChainNamespace({}, outer_space)

def __repr__(self):
return "Space(name={name}, size={size:d})".format(
Expand All @@ -96,7 +95,7 @@ def namespace(self):
Returns:
dict: Namespace.
"""
return self._execution_namespace.local_references
return self._execution_namespace.maps[0]

def execute(self, source):
"""Execute source code inside the space namespace and outer namespace.
Expand All @@ -116,25 +115,5 @@ def execute(self, source):
exec(compiled_interactive_tree, self._execution_namespace)


class ExecutionNamespace(dict):
def __init__(self, global_references, local_references):
"""Instantiate ExecutionNamespace.
Args:
global_references (dict): Global namespace.
local_references (dict): Local namespace.
"""
self.global_references = global_references
self.local_references = local_references

def __getitem__(self, key):
try:
return self.local_references[key]
except KeyError:
return self.global_references[key]

def __setitem__(self, key, value):
self.local_references[key] = value

def __delitem__(self, key):
del self.local_references[key]
class _ChainNamespace(ChainMap, dict):
pass
47 changes: 1 addition & 46 deletions tests/test_space.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from pytest import raises

from jupyter_spaces.errors import RegistryError
from jupyter_spaces.space import ExecutionNamespace, Space, SpaceRegister
from jupyter_spaces.space import Space, SpaceRegister


class TestSpace:
Expand Down Expand Up @@ -135,48 +135,3 @@ def test_remove_all_spaces_given_empty_register(self):
space_register.remove_all_spaces()
expected_register = {}
assert space_register.register == expected_register


class TestExecutionNamespace:
def test_access_global_references(self):
namespace = ExecutionNamespace(global_references=dict(x=1), local_references={})
assert namespace["x"] == 1

def test_access_local_references(self):
namespace = ExecutionNamespace(global_references={}, local_references=dict(x=1))
assert namespace["x"] == 1

def test_priority_access_for_local_references(self):
namespace = ExecutionNamespace(
global_references=dict(x=1), local_references=dict(x=2)
)
assert namespace["x"] == 2

def test_alter_local_references(self):
namespace = ExecutionNamespace(global_references={}, local_references=dict(x=1))
namespace["x"] = 2
assert namespace["x"] == 2
assert namespace.local_references["x"] == 2

def test_local_assignments_do_not_affect_global_assignments(self):
namespace = ExecutionNamespace(global_references=dict(x=1), local_references={})
namespace["x"] = 2
assert namespace["x"] == 2
assert namespace.local_references["x"] == 2
assert namespace.global_references["x"] == 1

def test_deleting_local_references_do_not_affect_global_assignments(self):
namespace = ExecutionNamespace(
global_references=dict(x=1), local_references=dict(x=2)
)
del namespace["x"]
assert namespace["x"] == 1
assert "x" not in namespace.local_references
assert namespace.global_references["x"] == 1

def test_deleting_not_existing_local_references_raises(self):
namespace = ExecutionNamespace(global_references=dict(x=1), local_references={})
with raises(KeyError):
del namespace["x"]
assert namespace["x"] == 1
assert namespace.global_references["x"] == 1

0 comments on commit 3152b22

Please sign in to comment.