Skip to content
This repository has been archived by the owner on Apr 23, 2021. It is now read-only.

Commit

Permalink
Merge pull request #346 from simphony/internalized-data
Browse files Browse the repository at this point in the history
Internalized data
  • Loading branch information
mehdisadeghi committed Nov 10, 2016
2 parents 696863b + 7b97853 commit dcfdfa3
Show file tree
Hide file tree
Showing 102 changed files with 1,057 additions and 2,037 deletions.
74 changes: 31 additions & 43 deletions scripts/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ def get_cuba_attribute():

return tuple(attr for attr in get_cuba_attribute())

def populate_system_code(self):
def _setup_system_code(self):
""" Populate code for system-managed (and read-only) attributes"""

for key, contents in chain(self.system_variables.items(),
Expand All @@ -337,7 +337,7 @@ def populate_system_code(self):
continue

# Populates self.methods with getter
self.populate_getter(key)
self._setup_getter(key)

# For CUBA attributes that are read-only, `content`
# should be a dict.
Expand All @@ -357,11 +357,11 @@ def populate_system_code(self):
if isinstance(default, str):
self.init_body[-1] += ' # noqa'

def populate_module_variables(self):
def _setup_module_variables(self):
''' Populate module-level variables '''
pass

def populate_class_variables(self):
def _setup_class_variables(self):
''' Populate class variables
These variables are requested by the user, but they are not
Expand All @@ -372,7 +372,7 @@ def populate_class_variables(self):
self.class_variables.append(
'cuba_key = CUBA.{}'.format(self.original_key))

def populate_meta_api(self):
def _setup_meta_api(self):
''' Populate API for interoperability '''

# Add a supported_parameters as a class method
Expand All @@ -390,7 +390,7 @@ def parents(cls):
return {!r}'''.format(tuple('CUBA.{}'.format(parent)
for parent in self.mro))))

def populate_user_variable_code(self):
def _setup_user_variable_code(self):
''' Populate code for user-defined attributes '''

# populate them in reverse, because we want the root base class
Expand Down Expand Up @@ -419,8 +419,8 @@ def populate_user_variable_code(self):
if isinstance(default, str) and default.startswith('CUBA.'):
# If default value is a CUBA key, it should be an instance
# of the corresponding meta class
self.populate_init_body_with_cuba_default(key,
contents['default'])
self._setup_init_body_with_cuba_default(key,
contents['default'])
elif isinstance(default, MutableSequence):
# The __init__ signature will replace the default with None
self.init_body.extend(('if {key} is None:'.format(key=key),
Expand All @@ -436,12 +436,12 @@ def populate_user_variable_code(self):
if (key in self.optional_user_defined or
key in self.required_user_defined):
# Getter
self.populate_getter(key)
self._setup_getter(key)

# Setter
self.populate_setter_with_validation(key, contents)
self._setup_setter_with_validation(key, contents)

def populate_getter(self, key, value=None, docstring=''):
def _setup_getter(self, key, value=None, docstring=''):
''' Populate getter descriptor
Parameters
Expand Down Expand Up @@ -480,7 +480,7 @@ def {key}(self):
def {key}(self):
return {value}'''.format(key=key, value=value))

def populate_setter(self, key, check_statements=()):
def _setup_setter(self, key, check_statements=()):
''' Populate setter descriptor
Parameters
Expand Down Expand Up @@ -519,7 +519,7 @@ def {key}(self, value):
{target} = value'''.format(key=key, target=target,
validation_code=validation_code))

def populate_setter_with_validation(self, key, contents):
def _setup_setter_with_validation(self, key, contents):
''' Populate setter descriptor with validation codes
Parameters
Expand Down Expand Up @@ -581,9 +581,9 @@ def populate_setter_with_validation(self, key, contents):
for statement in check_statements[1:])

# Populate setter
self.populate_setter(key, check_statements)
self._setup_setter(key, check_statements)

def populate_init_body_with_cuba_default(self, key, default):
def _setup_init_body_with_cuba_default(self, key, default):
''' Populate the body of `__init__` for an attribute
Parameters
Expand Down Expand Up @@ -612,6 +612,8 @@ def populate_init_body_with_cuba_default(self, key, default):
PATH_TO_CLASSES, default_key,
to_camel_case(default_key)))

# Populate methods: they handle special cases for some datatypes
# that require non-boilerplate setup.
def populate_uuid(self, contents):
"""Populate code for CUBA.UUID
Expand All @@ -630,37 +632,21 @@ def uid(self):
return self._uid''')

def populate_data(self, contents):
"""Populate code for CUBA.DATA
Parameters
----------
contents : dict
meta data for the attribute `data` (not currently used)
"""Sets up the internal self.data which is the DataContainer
storage for all non-system variables.
"""
if isinstance(contents, dict) and contents.get('default'):
# FIXME: contents is not being used, what should we expect there?
message = ("provided default value for DATA is currently ignored. "
"Given: {}")
warnings.warn(message.format(contents))

self.imports.append(IMPORT_PATHS['DataContainer'])

self.init_body.append('''if data:
internal_data = self.data
internal_data.update(data)
self.data = internal_data
''')
# Put it in front because other data depend on it.
self.init_body.insert(0, '''
self._data = DataContainer()
''')

self.methods.append('''
@property
def data(self):
try:
data_container = self._data
except AttributeError:
self._data = DataContainer()
data_container = self._data
return DataContainer(data_container)
return DataContainer(self._data)
''')

self.methods.append('''
Expand All @@ -669,6 +655,8 @@ def data(self, new_data):
self._data = DataContainer(new_data)
''')

# End populate methods

def collect_parents_to_mro(self, generators):
''' Recursively collect all the inherited into CodeGenerator.mro
Assume single inheritence, i.e. no multiple parents
Expand Down Expand Up @@ -875,11 +863,11 @@ def generate(self, file_out):
"""
# Populate codes before writing
self.populate_user_variable_code()
self.populate_system_code()
self.populate_module_variables()
self.populate_class_variables()
self.populate_meta_api()
self._setup_user_variable_code()
self._setup_system_code()
self._setup_module_variables()
self._setup_class_variables()
self._setup_meta_api()

# Now write to the file output
self.generate_class_import(file_out)
Expand Down
16 changes: 3 additions & 13 deletions scripts/tests/test_meta_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import uuid

from simphony.api import CUBA
from simphony.core import DataContainer
from simphony.cuds.meta import api as meta_class


Expand All @@ -23,8 +22,10 @@ def setUpClass(cls):
# Inspect the __init__ signature
init_spec = inspect.getargspec(klass.__init__)

defaults = init_spec.defaults if init_spec.defaults else []

# Number of required arguments
num_required = len(init_spec.args) - len(init_spec.defaults) - 1
num_required = (len(init_spec.args) - len(defaults) - 1)

if num_required > 0:
if not hasattr(cls, 'test_'+name):
Expand Down Expand Up @@ -127,17 +128,6 @@ def test_all_inherit_cuds_item(self):
if errors:
self.fail('\n'.join(errors))

def test_initialization_with_data(self):
errors = []

for name, klass in self.no_required_args_classes:
meta_obj = klass(data=DataContainer(NAME="foobar"))
self.check_cuds_item(meta_obj)
self.assertEqual(meta_obj.data[CUBA.NAME], "foobar")

if errors:
self.fail('\n'.join(errors))

def test_cuds_components_properties(self):
''' Test the properties of CUDSComponent '''
for name, klass in self.no_required_args_classes:
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
exclude = doc/*

[build_meta]
repotag=8cf2931faa40c3ac2c202e84dd0668532deadf2e
repotag=02c79cb19e9f580b6b5f0722717ba4fa47d1ec85
27 changes: 9 additions & 18 deletions simphony/cuds/meta/atom.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,13 @@ class Atom(Particle):

cuba_key = CUBA.ATOM

def __init__(self, data=None, position=None, mass=1.0):
def __init__(self, position=None, mass=1.0):

self._data = DataContainer()

self.mass = mass
if position is None:
self.position = [0, 0, 0]
if data:
internal_data = self.data
internal_data.update(data)
self.data = internal_data

# This is a system-managed, read-only attribute
self._definition = 'An atom' # noqa

Expand All @@ -37,23 +34,17 @@ def mass(self, value):
self.data = data

@property
def data(self):
try:
data_container = self._data
except AttributeError:
self._data = DataContainer()
data_container = self._data
def definition(self):
return self._definition

return DataContainer(data_container)
@property
def data(self):
return DataContainer(self._data)

@data.setter
def data(self, new_data):
self._data = DataContainer(new_data)

@property
def definition(self):
return self._definition

@property
def uid(self):
if not hasattr(self, '_uid') or self._uid is None:
Expand All @@ -62,7 +53,7 @@ def uid(self):

@classmethod
def supported_parameters(cls):
return (CUBA.POSITION, CUBA.MASS, CUBA.UUID)
return (CUBA.UUID, CUBA.MASS, CUBA.POSITION)

@classmethod
def parents(cls):
Expand Down
25 changes: 8 additions & 17 deletions simphony/cuds/meta/atomistic.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,36 +10,27 @@ class Atomistic(ComputationalModel):

cuba_key = CUBA.ATOMISTIC

def __init__(self, data=None, description="", name=""):
def __init__(self, description="", name=""):

self._data = DataContainer()

self.name = name
self.description = description
if data:
internal_data = self.data
internal_data.update(data)
self.data = internal_data

# This is a system-managed, read-only attribute
self._definition = 'Atomistic model category according to the RoMM' # noqa

@property
def data(self):
try:
data_container = self._data
except AttributeError:
self._data = DataContainer()
data_container = self._data
def definition(self):
return self._definition

return DataContainer(data_container)
@property
def data(self):
return DataContainer(self._data)

@data.setter
def data(self, new_data):
self._data = DataContainer(new_data)

@property
def definition(self):
return self._definition

@property
def uid(self):
if not hasattr(self, '_uid') or self._uid is None:
Expand Down

0 comments on commit dcfdfa3

Please sign in to comment.