diff --git a/yaltik_dsl/__init__.py b/yaltik_dsl/__init__.py index 0f65d9f..ee86a92 100644 --- a/yaltik_dsl/__init__.py +++ b/yaltik_dsl/__init__.py @@ -1,24 +1,3 @@ -#!/usr/bin/env python2 -# -*- coding: utf-8 -*- -# __coconut_hash__ = 0x73d2bb80 - -# Compiled with Coconut version 1.4.3 [Ernest Scribbler] - -# Coconut Header: ------------------------------------------------------------- - -from __future__ import print_function, absolute_import, unicode_literals, division -import sys as _coconut_sys, os.path as _coconut_os_path -_coconut_file_path = _coconut_os_path.dirname(_coconut_os_path.abspath(__file__)) -_coconut_cached_module = _coconut_sys.modules.get(b"__coconut__") -if _coconut_cached_module is not None and _coconut_os_path.dirname(_coconut_cached_module.__file__) != _coconut_file_path: - del _coconut_sys.modules[b"__coconut__"] -_coconut_sys.path.insert(0, _coconut_file_path) -from __coconut__ import * -from __coconut__ import _coconut, _coconut_MatchError, _coconut_igetitem, _coconut_base_compose, _coconut_forward_compose, _coconut_back_compose, _coconut_forward_star_compose, _coconut_back_star_compose, _coconut_forward_dubstar_compose, _coconut_back_dubstar_compose, _coconut_pipe, _coconut_back_pipe, _coconut_star_pipe, _coconut_back_star_pipe, _coconut_dubstar_pipe, _coconut_back_dubstar_pipe, _coconut_bool_and, _coconut_bool_or, _coconut_none_coalesce, _coconut_minus, _coconut_map, _coconut_partial, _coconut_get_function_match_error, _coconut_base_pattern_func, _coconut_addpattern, _coconut_sentinel, _coconut_assert, _coconut_mark_as_match - - -# Compiled Coconut: ----------------------------------------------------------- - # -*- coding: utf-8 -*- # Copyright 2019-2020 Fabien Bourgeois diff --git a/yaltik_dsl/test_xml_base.py b/yaltik_dsl/test_xml_base.py index 572379d..dbfd10b 100644 --- a/yaltik_dsl/test_xml_base.py +++ b/yaltik_dsl/test_xml_base.py @@ -1,26 +1,3 @@ -#!/usr/bin/env python2 -# -*- coding: utf-8 -*- -# __coconut_hash__ = 0x84c101a5 - -# Compiled with Coconut version 1.4.3 [Ernest Scribbler] - -""" XML Helpers tests """ - -# Coconut Header: ------------------------------------------------------------- - -from __future__ import print_function, absolute_import, unicode_literals, division -import sys as _coconut_sys, os.path as _coconut_os_path -_coconut_file_path = _coconut_os_path.dirname(_coconut_os_path.abspath(__file__)) -_coconut_cached_module = _coconut_sys.modules.get(b"__coconut__") -if _coconut_cached_module is not None and _coconut_os_path.dirname(_coconut_cached_module.__file__) != _coconut_file_path: - del _coconut_sys.modules[b"__coconut__"] -_coconut_sys.path.insert(0, _coconut_file_path) -from __coconut__ import * -from __coconut__ import _coconut, _coconut_MatchError, _coconut_igetitem, _coconut_base_compose, _coconut_forward_compose, _coconut_back_compose, _coconut_forward_star_compose, _coconut_back_star_compose, _coconut_forward_dubstar_compose, _coconut_back_dubstar_compose, _coconut_pipe, _coconut_back_pipe, _coconut_star_pipe, _coconut_back_star_pipe, _coconut_dubstar_pipe, _coconut_back_dubstar_pipe, _coconut_bool_and, _coconut_bool_or, _coconut_none_coalesce, _coconut_minus, _coconut_map, _coconut_partial, _coconut_get_function_match_error, _coconut_base_pattern_func, _coconut_addpattern, _coconut_sentinel, _coconut_assert, _coconut_mark_as_match - - -# Compiled Coconut: ----------------------------------------------------------- - # -*- coding: utf-8 -*- # # Copyright 2020 Fabien Bourgeois @@ -38,108 +15,105 @@ from __coconut__ import _coconut, _coconut_MatchError, _coconut_igetitem, _cocon # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +""" XML Helpers tests """ - +from functools import partial import unittest import xml.etree.ElementTree as ET from os import unlink -from xml_base import xmln -from xml_base import xmlroot -from xml_base import xmlchild -from xml_base import xml_write +from xml_base import xmln, xmlroot, xmlchild, xml_write class TestXMLBase(unittest.TestCase): """ XML Helpers tests """ def test_xmln(self): -# Tags - (self.assertEquals)(*(xmln()._asdict(), {'tag': '', 'attrs': {}, 'children': []})) - (self.assertEquals)(*((_coconut_partial(getattr, {1: 'tag'}, 2))((xmln)('a tag')), 'a tag')) - -# Attrs - (self.assertEquals)(*(xmln(attrs={'a good': 'one'}).attrs, {'a good': 'one'})) - (self.assertEquals)(*((_coconut_partial(getattr, {1: 'attrs'}, 2))((xmln)(**{'attrs': {'a good': 'one'}})), {'a good': 'one'})) - -# Childrens - attrs = {'children': [1, 2, 3]} - (self.assertTrue)(((_coconut_partial(getattr, {1: 'children'}, 2))((xmln)(**attrs)) == [1, 2, 3])) - - attrs = {'children': 'Some text'} - (self.assertTrue)(((_coconut_partial(getattr, {1: 'children'}, 2))((xmln)(**attrs)) == ['Some text'])) + """ Text xmln """ + # Tags + self.assertDictEqual(xmln()._asdict(), {'tag': '', 'attrs': {}, 'children': []}) + self.assertEqual(xmln('a tag').tag, 'a tag') + # Attrs + self.assertDictEqual(xmln(attrs={'a good': 'one'}).attrs, {'a good': 'one'}) + # Childrens + self.assertListEqual(xmln(children=[1, 2, 3]).children, [1, 2, 3]) + self.assertListEqual(xmln(children='Some text').children, ['Some text']) with self.assertRaisesRegexp(TypeError, 'Invalid arguments'): - (xmln)(**{'children': False}) + xmln(children=False) -# Ensure that only children after tags is managed - element = (xmln)(*('tag', {'something': 'inside'})) - (self.assertIsInstance)(element.attrs, dict) - (self.assertIsInstance)(element.children, list) + # Ensure that only children after tags is managed + element = xmln('tag', {'something': 'inside'}) + self.assertIsInstance(element.attrs, dict) + self.assertIsInstance(element.children, list) - element = (xmln)(*('tag', ['something', 'inside'])) - (self.assertIsInstance)(element.attrs, dict) - (self.assertIsInstance)(element.children, list) + element = xmln('tag', ['something', 'inside']) + self.assertIsInstance(element.attrs, dict) + self.assertIsInstance(element.children, list) def test_xmlchild(self): - parent = (xmlroot)({'tag': 'root', 'attrs': {}, 'children': []}) - xmlc_par = (_coconut.functools.partial(_coconut.functools.partial, xmlchild))(parent) + """ Test xmlchild """ + parent = xmlroot({'tag': 'root', 'attrs': {}, 'children': []}) + xmlc_par = partial(xmlchild, parent) -# Bad arguments + # Bad arguments with self.assertRaisesRegexp(TypeError, 'Invalid arguments for xmlchild'): - (xmlc_par)(False) -# Need XMLDictElement, not dict + xmlc_par(False) + # Need XMLDictElement, not dict with self.assertRaisesRegexp(TypeError, 'Invalid arguments for xmlchild'): - (xmlc_par)([{'tag': 't', 'attrs': {'a': 'b'}, 'children': []}]) + xmlc_par([{'tag': 't', 'attrs': {'a': 'b'}, 'children': []}]) - (xmlc_par)(['some text']) - (self.assertEquals)(parent.text, 'some text') + xmlc_par(['some text']) + self.assertEqual(parent.text, 'some text') - (xmlc_par)([(xmln)(**{'tag': 't', 'attrs': {'a': 'b'}, 'children': []})]) - child = (next)((parent.iter)('t')) - (self.assertEquals)(child.tag, 't') - (self.assertEquals)(child.attrib, {'a': 'b'}) - (self.assertEquals)(((list)(child)), []) + xmlc_par([xmln('t', {'a': 'b'}, [])]) + child = parent.iter('t').next() + self.assertEqual(child.tag, 't') + self.assertDictEqual(child.attrib, {'a': 'b'}) + self.assertListEqual(list(child), []) - (xmlc_par)([(xmln)(**{'tag': 't2', 'attrs': {1: 2}, 'children': []})]) - child = (next)((parent.iter)('t2')) - (self.assertEquals)(child.attrib, {'1': '2'}) + xmlc_par([xmln('t2', {1: 2}, [])]) + child = parent.iter('t2').next() + self.assertDictEqual(child.attrib, {'1': '2'}) - (xmlc_par)([(xmln)(**{'tag': 'tchildren', 'attrs': {}, 'children': [(xmln)(**{'tag': 'subchild', 'attrs': {}, 'children': []})]})]) - child = (next)((parent.iter)('tchildren')) - subchildren = ((list)(child)) - (self.assertEquals)(((len)(subchildren)), 1) - (self.assertEquals)(subchildren[0].tag, 'subchild') + xmlc_par([xmln('tchildren', {}, [xmln('subchild', {}, [])])]) + child = parent.iter('tchildren').next() + subchildren = list(child) + self.assertEqual(len(subchildren), 1) + self.assertEqual(subchildren[0].tag, 'subchild') def test_xmlroot(self): - root = (xmlroot)({'tag': 'root', 'attrs': {}, 'children': []}) - (self.assertTrue)((isinstance)(*(root, ET.Element))) + """ Test xmlroot """ + root = xmlroot({'tag': 'root', 'attrs': {}, 'children': []}) + self.assertIsInstance(root, ET.Element) with self.assertRaisesRegexp(TypeError, 'has no attribute'): - (xmlroot)(False) + xmlroot(False) with self.assertRaisesRegexp(KeyError, 'tag'): - (xmlroot)({}) + xmlroot({}) with self.assertRaisesRegexp(KeyError, 'attrs'): - (xmlroot)({'tag': 'root'}) + xmlroot({'tag': 'root'}) def test_xml_write(self): - children = [(xmln)(*('child1', {'attr': 'value'}, [])), (xmln)(*('child2', {}, "Some text"))] + """ test xml_write """ + children = [xmln('child1', {'attr': 'value'}, []), + xmln('child2', {}, "Some text")] tree = xmlroot({'tag': 'root', 'attrs': {}, 'children': children}) - xmlw = _coconut_partial(xml_write, {1: tree}, 2) + xmlw = lambda p: xml_write(p, tree) - (self.assertEquals)(((xmlw)('/badpath')), None) - (self.assertEquals)(((xmlw)('/bad.ext')), None) + self.assertIsNone(xmlw('/badpath')) + self.assertIsNone(xmlw('/bad.ext')) xmlw(__file__) filepath = __file__.replace('.py', '_views.xml') with open(filepath, 'r') as output_file: output_xml = output_file.read() - (self.assertIn)('', output_xml) - (self.assertIn)('', output_xml) - (self.assertIn)('Some text', output_xml) + self.assertIn('', output_xml) + self.assertIn('', output_xml) + self.assertIn('Some text', output_xml) unlink(filepath) if __name__ == '__main__': diff --git a/yaltik_dsl/xml_base.py b/yaltik_dsl/xml_base.py index d950a7f..9bbaa2b 100644 --- a/yaltik_dsl/xml_base.py +++ b/yaltik_dsl/xml_base.py @@ -1,26 +1,3 @@ -#!/usr/bin/env python2 -# -*- coding: utf-8 -*- -# __coconut_hash__ = 0x178765c5 - -# Compiled with Coconut version 1.4.3 [Ernest Scribbler] - -""" XML helpers and macros """ - -# Coconut Header: ------------------------------------------------------------- - -from __future__ import print_function, absolute_import, unicode_literals, division -import sys as _coconut_sys, os.path as _coconut_os_path -_coconut_file_path = _coconut_os_path.dirname(_coconut_os_path.abspath(__file__)) -_coconut_cached_module = _coconut_sys.modules.get(b"__coconut__") -if _coconut_cached_module is not None and _coconut_os_path.dirname(_coconut_cached_module.__file__) != _coconut_file_path: - del _coconut_sys.modules[b"__coconut__"] -_coconut_sys.path.insert(0, _coconut_file_path) -from __coconut__ import * -from __coconut__ import _coconut, _coconut_MatchError, _coconut_igetitem, _coconut_base_compose, _coconut_forward_compose, _coconut_back_compose, _coconut_forward_star_compose, _coconut_back_star_compose, _coconut_forward_dubstar_compose, _coconut_back_dubstar_compose, _coconut_pipe, _coconut_back_pipe, _coconut_star_pipe, _coconut_back_star_pipe, _coconut_dubstar_pipe, _coconut_back_dubstar_pipe, _coconut_bool_and, _coconut_bool_or, _coconut_none_coalesce, _coconut_minus, _coconut_map, _coconut_partial, _coconut_get_function_match_error, _coconut_base_pattern_func, _coconut_addpattern, _coconut_sentinel, _coconut_assert, _coconut_mark_as_match - - -# Compiled Coconut: ----------------------------------------------------------- - # -*- coding: utf-8 -*- # # Copyright 2019-2020 Fabien Bourgeois @@ -38,107 +15,58 @@ from __coconut__ import _coconut, _coconut_MatchError, _coconut_igetitem, _cocon # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . - +""" XML helpers and macros """ from os import path import xml.etree.ElementTree as ET from xml.dom import minidom -from typing import Dict -from typing import List -from typing import Union -from typing import Text -from typing import Any +from collections import namedtuple +from functools import partial + +XMLDictElement = namedtuple('XMLDictElement', ['tag', 'attrs', 'children']) -# TODO: fix MyPy / typing - -class XMLDictElement(_coconut.typing.NamedTuple("XMLDictElement", [("tag", 'Text'), ("attrs", 'XMLAttrs'), ("children", 'List[Any]')]), _coconut.object): - __slots__ = () - __ne__ = _coconut.object.__ne__ - def __eq__(self, other): - return self.__class__ is other.__class__ and _coconut.tuple.__eq__(self, other) - def __hash__(self): - return _coconut.tuple.__hash__(self) ^ hash(self.__class__) - - -XMLAttrs = Dict[Text, Text] -XMLChild = Union[XMLDictElement, Text, List] - - -def xmlroot(tree # type: Dict[str, Any] - ): -# type: (...) -> ET.Element +def xmlroot(tree): """ Special process for root XML Node """ - rootel = (ET.Element)(*(tree['tag'], tree['attrs'])) + rootel = ET.Element(tree['tag'], tree['attrs']) if 'children' in tree: - (xmlchild)(*(rootel, tree['children'])) + xmlchild(rootel, tree['children']) return rootel -def xmlchild(parent, # type: ET.Element - children # type: XMLDictElement - ): -# type: (...) -> None +def xmlchild(parent, children): """ Handling of children (ie non root) XML Nodes with/o text and subchildren (recursive) """ - _coconut_match_to = children - _coconut_case_check_0 = False - if _coconut.isinstance(_coconut_match_to, Text): - _coconut_case_check_0 = True - if _coconut_case_check_0: + if isinstance(children, str): parent.text = children - if not _coconut_case_check_0: - if _coconut.isinstance(_coconut_match_to, XMLDictElement): - _coconut_case_check_0 = True - if _coconut_case_check_0: - attrs = dict(((unicode(k)), (unicode(v))) for [k, v] in children.attrs.items()) - new_parent = (ET.SubElement)(*(parent, children.tag, attrs)) - subchildren = children.children - if subchildren: - (xmlchild)(*(new_parent, subchildren)) - if not _coconut_case_check_0: - if _coconut.isinstance(_coconut_match_to, List): - _coconut_case_check_0 = True - if _coconut_case_check_0: - (consume)((map)(*(((_coconut.functools.partial(_coconut.functools.partial, xmlchild))(parent)), children))) - if not _coconut_case_check_0: + elif isinstance(children, XMLDictElement): + attrs = {unicode(k): unicode(v) for [k, v] in children.attrs.items()} + new_parent = ET.SubElement(parent, children.tag, attrs) + subchildren = children.children + if subchildren: + xmlchild(new_parent, subchildren) + elif isinstance(children, list): + map(partial(xmlchild, parent), children) + else: raise TypeError('Invalid arguments for xmlchild') -def xmln(tag='', # type: Text - attrs={}, # type: XMLAttrs - children=[] # type: Union[Text, List] - ): -# type: (...) -> XMLDictElement +def xmln(tag='', attrs={}, children=[]): """ XMLDictElement building from dict object, with defaults """ - _coconut_match_to = attrs - _coconut_case_check_1 = False - if _coconut.isinstance(_coconut_match_to, list): - _coconut_case_check_1 = True - if _coconut_case_check_1: + if isinstance(attrs, list): children = attrs attrs = {} - xmldictel = (_coconut.functools.partial(_coconut.functools.partial, XMLDictElement))(*(tag, attrs)) - _coconut_match_to = children - _coconut_case_check_2 = False - if _coconut.isinstance(_coconut_match_to, Text): - c = _coconut_match_to - _coconut_case_check_2 = True - if _coconut_case_check_2: - return (xmldictel)([c]) - if not _coconut_case_check_2: - if _coconut.isinstance(_coconut_match_to, list): - c = _coconut_match_to - _coconut_case_check_2 = True - if _coconut_case_check_2: - return (xmldictel)(c) - if not _coconut_case_check_2: - raise TypeError('Invalid arguments for xmln') + xmldictel = partial(XMLDictElement, tag, attrs) + if isinstance(children, str): + return xmldictel([children]) + if isinstance(children, list): + return xmldictel(children) + raise TypeError('Invalid arguments for xmln') def xml_write(filepath, tree): """ Write XML file according to filename and given tree """ - if (filepath.endswith)('.py'): # if .pyc, no need to generate XML - output_xml = ((minidom.parseString)((ET.tostring)(tree))).toprettyxml(indent=' ') - output_path = (path.dirname)((path.abspath)(filepath)) - fpath = (('/'.join)([output_path, (path.basename)(filepath)])).replace('.py', '_views.xml') + if filepath.endswith('.py'): # if .pyc, no need to generate XML + output_xml = minidom.parseString(ET.tostring(tree)).toprettyxml(indent=' ') + output_path = path.dirname(path.abspath(filepath)) + fpath = u'/'.join([output_path, path.basename(filepath)]).replace('.py', '_views.xml') with open(fpath, 'w') as output_file: output_file.write(output_xml)