Skip to content
Snippets Groups Projects
Commit 9b63e31b authored by James Graham's avatar James Graham
Browse files

Working JSON config reader with includes

parent 78508b67
Branches
No related tags found
No related merge requests found
import json import json
import os
class DuplicateSectionError(Exception):
"""
Exception used to indicate that a section has appeared twice in a file.
"""
def __repr__(self):
return "Section {0} appears twice in file {1}.".format(*self.args)
class Record(dict): class Record(dict):
...@@ -18,21 +11,28 @@ class Record(dict): ...@@ -18,21 +11,28 @@ class Record(dict):
class CFG: class CFG:
def __init__(self, filename): def __init__(self, filename, from_section=None):
with open(filename) as f: with open(filename) as f:
try:
self._json = json.load(f, object_hook=Record) self._json = json.load(f, object_hook=Record)
except ValueError:
raise DuplicateSectionError()
def __getitem__(self, item): while self._json.include:
return Record(self._json[item]) include_file = os.path.join(os.path.dirname(filename), self._json.include.pop())
with open(include_file) as include_file:
include_json = json.load(include_file, object_hook=Record)
def __contains__(self, item): for curr, incl in zip(self._json.values(), include_json.values()):
return item in self._json try:
curr += incl
except TypeError:
curr.update(incl)
if from_section is not None:
self._records = self._json[from_section]
else:
self._records = self._json
def __enter__(self): def __getitem__(self, item):
return self return self._records[item]
def __exit__(self, type, value, traceback): def __contains__(self, item):
pass return item in self._records
{
"include":["martini_lipids.json", "martini_aminoacids.json"],
"molecules":{}
}
{
"include":[],
"molecules":{
"GLY":{
"beads":[],
"bonds":[]
}
}
}
{
"include":[],
"molecules":{
"DOPC":{
"beads":[],
"bonds":[]
}
}
}
{"SOL":{
"beads":[
{"name":"W", "type":"P4", "atoms":["OW", "HW1", "HW2"]}
],
"bonds":[
]
}}
{"SOL":{
"beads":[
{"name":"W", "type":"P4", "atoms":["OW", "HW1", "HW2"]}
],
"bonds":[
]
}}
{"SOL":{ {
"include":[],
"molecules":{
"SOL":{
"beads":[ "beads":[
{"name":"W", "type":"P4", "atoms":["OW", "HW1", "HW2"]} {"name":"W", "type":"P4", "atoms":["OW", "HW1", "HW2"]}
], ],
"bonds":[ "bonds":[]
] }
}} }
}
import unittest import unittest
from pycgtool.parsers.json import CFG, DuplicateSectionError from pycgtool.parsers.json import CFG
class TestParsersJson(unittest.TestCase): class TestParsersJson(unittest.TestCase):
def test_cfg_with(self): def test_json_water(self):
with CFG("test/data/water.json"): cfg = CFG("test/data/water.json", "molecules")
pass
def test_cfg_get_section(self):
with CFG("test/data/water.json") as cfg:
self.assertTrue("SOL" in cfg) self.assertTrue("SOL" in cfg)
self.assertEqual(1, len(cfg["SOL"].beads)) self.assertEqual(1, len(cfg["SOL"].beads))
bead = cfg["SOL"].beads[0] bead = cfg["SOL"].beads[0]
...@@ -18,13 +15,37 @@ class TestParsersJson(unittest.TestCase): ...@@ -18,13 +15,37 @@ class TestParsersJson(unittest.TestCase):
self.assertEqual(["OW", "HW1", "HW2"], bead.atoms) self.assertEqual(["OW", "HW1", "HW2"], bead.atoms)
self.assertEqual(0, len(cfg["SOL"].bonds)) self.assertEqual(0, len(cfg["SOL"].bonds))
def test_cfg_duplicate_error(self): def test_json_sugar(self):
with self.assertRaises(DuplicateSectionError): cfg = CFG("test/data/sugar.json", "molecules")
CFG("test/data/twice.json")
ref_beads = [["C1", "P3", "C1", "O1"],
["C2", "P3", "C2", "O2"],
["C3", "P3", "C3", "O3"],
["C4", "P3", "C4", "O4"],
["C5", "P2", "C5", "C6", "O6"],
["O5", "P4", "O5"]]
ref_bonds = [["C1", "C2"],
["C2", "C3"],
["C3", "C4"],
["C4", "C5"],
["C5", "O5"],
["O5", "C1"]]
self.assertTrue("ALLA" in cfg)
self.assertEqual(6, len(cfg["ALLA"].beads))
for ref_bead, bead in zip(ref_beads, cfg["ALLA"].beads):
self.assertEqual(ref_bead[0], bead.name)
self.assertEqual(ref_bead[1], bead.type)
self.assertEqual(ref_bead[2:], bead.atoms)
self.assertEqual(6, len(cfg["ALLA"].bonds))
for ref_bond, bond in zip(ref_bonds, cfg["ALLA"].bonds):
self.assertEqual(ref_bond, bond)
@unittest.expectedFailure
def test_include_file(self): def test_include_file(self):
with CFG("test/data/martini.json") as cfg: cfg = CFG("test/data/martini.json", "molecules")
self.assertTrue("DOPC" in cfg) self.assertTrue("DOPC" in cfg)
self.assertTrue("GLY" in cfg) self.assertTrue("GLY" in cfg)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment