- Location:
- /trunk
- Files:
-
- 6 deleted
- 13 edited
-
Makefile (modified) (2 diffs)
-
sandbox/syck-parser/test_my_tags.yml (deleted)
-
sandbox/emit-it/Makefile (modified) (1 diff)
-
sandbox/emit-it/emit-it.c (modified) (4 diffs)
-
sandbox/emit-it/complex-key-bug.c (deleted)
-
sandbox/emit-it/trailing-space-bug.c (deleted)
-
ext/_syckmodule.c (modified) (15 diffs)
-
tests/test_dumper.py (modified) (2 diffs)
-
tests/test_parser.py (modified) (1 diff)
-
tests/test_loader.py (modified) (5 diffs)
-
tests/test_emitter.py (modified) (3 diffs)
-
tests/test_syck.py (modified) (1 diff)
-
tests/test_pickle.py (deleted)
-
lib/syck/__init__.py (modified) (1 diff)
-
lib/syck/dumpers.py (modified) (10 diffs)
-
lib/syck/loaders.py (modified) (11 diffs)
-
setup.py (modified) (3 diffs)
-
MANIFEST.in (deleted)
-
README.txt (deleted)
Legend:
- Unmodified
- Added
- Removed
-
/trunk/Makefile
r29 r4 1 1 2 .PHONY: default build force install test clean \ 3 dist-src dist-win dist-win-2.2 dist-win-2.3 dist-win-2.4 2 .PHONY: default build force install test clean 4 3 5 4 PYTHON=/usr/bin/python 6 REST2HTML=/usr/bin/rest2html --embed-stylesheet --stylesheet-path=/usr/share/python-docutils/stylesheets/default.css7 5 TEST= 8 PARAMETERS=9 6 10 default: build README.html7 default: build 11 8 12 9 build: 13 ${PYTHON} setup.py build ${PARAMETERS}10 ${PYTHON} setup.py build 14 11 15 12 force: 16 ${PYTHON} setup.py build -f ${PARAMETERS}13 ${PYTHON} setup.py build -f 17 14 18 15 install: build 19 ${PYTHON} setup.py install ${PARAMETERS}16 ${PYTHON} setup.py install 20 17 21 18 test: build … … 25 22 ${PYTHON} setup.py clean -a 26 23 27 dist-src:28 ${PYTHON} setup.py sdist --formats=zip,gztar29 30 dist-win: dist-win-2.2 dist-win-2.3 dist-win-2.431 32 dist-win-2.2: PYTHON=/c/Python22/python33 dist-win-2.2: PARAMETERS=--compiler=mingw3234 dist-win-2.2:35 ${PYTHON} setup.py build ${PARAMETERS}36 ${PYTHON} setup.py bdist_wininst37 38 dist-win-2.3: PYTHON=/c/Python23/python39 dist-win-2.3: PARAMETERS=--compiler=mingw3240 dist-win-2.3:41 ${PYTHON} setup.py build ${PARAMETERS}42 ${PYTHON} setup.py bdist_wininst --skip-build --target-version=2.343 44 dist-win-2.4: PYTHON=/c/Python24/python45 dist-win-2.4: PARAMETERS=--compiler=mingw3246 dist-win-2.4:47 ${PYTHON} setup.py build ${PARAMETERS}48 ${PYTHON} setup.py bdist_wininst --skip-build --target-version=2.449 50 README.html: README.txt51 ${REST2HTML} README.txt README.html52 -
/trunk/sandbox/emit-it/Makefile
r25 r11 1 2 ALL = emit-it complex-key-bug trailing-space-bug3 1 4 2 .PHONY: default clean 5 3 6 default: $(ALL)4 default: emit-it 7 5 8 6 clean: 9 rm -f *.o10 rm -f $(ALL)7 rm -f emit-it 8 rm -f emit-it.o 11 9 12 %.o: %.c 13 gcc -c $< -o $@ -Wall -Wstrict-prototypes -I${HOME}/include10 emit-it: emit-it.o 11 gcc emit-it.o -o emit-it -lsyck -L${HOME}/lib -Wall -Wstrict-prototypes 14 12 15 $(ALL): %: %.o 16 gcc $< -o $@ -lsyck -L${HOME}/lib -Wall -Wstrict-prototypes 13 emit-it.o: emit-it.c 14 gcc -c emit-it.c -o emit-it.o -I${HOME}/include 15 -
/trunk/sandbox/emit-it/emit-it.c
r25 r17 16 16 { 17 17 switch (id) { 18 /*19 18 case 1: 20 19 syck_emit_seq(e, "tag:domainmyseq.tld,2002:zz", seq_none); … … 22 21 syck_emit_item(e, 3); 23 22 syck_emit_item(e, 4); 23 /* syck_emit_item(e, 2); 24 syck_emit_item(e, 1);*/ 24 25 syck_emit_end(e); 25 26 break; … … 33 34 syck_emit_scalar(e, "x-private:myowntype", scalar_none, 0, 0, 0, "Ken Griffey", strlen("Ken Griffey")); 34 35 break; 35 */36 37 case 1:38 syck_emit_map(e, NULL, map_none);39 syck_emit_item(e, 2);40 syck_emit_item(e, 3);41 syck_emit_end(e);42 break;43 44 case 2:45 syck_emit_map(e, "x-private:key", map_none);46 syck_emit_item(e, 4);47 syck_emit_item(e, 5);48 syck_emit_end(e);49 break;50 51 case 3:52 case 4:53 case 5:54 syck_emit_scalar(e, NULL, scalar_none, 0, 0, 0, "foo", 3);55 break;56 36 } 57 58 37 } 59 38 … … 69 48 syck_emitter_mark_node(e, 3); 70 49 syck_emitter_mark_node(e, 4); 71 syck_emitter_mark_node(e, 5);72 50 /* syck_emitter_mark_node(e, 2); 73 51 syck_emitter_mark_node(e, 1);*/ -
/trunk/ext/_syckmodule.c
r25 r20 43 43 PyDoc_STRVAR(PySyckNode_doc, 44 44 "_syck.Node() -> TypeError\n\n" 45 "_syck.Node is an abstract type. It is thebase type for _syck.Scalar,\n"45 "_syck.Node is an abstract type. It is a base type for _syck.Scalar,\n" 46 46 "_syck.Seq, and _syck.Map. You cannot create an instance of _syck.Node\n" 47 47 "directly. You may use _syck.Node for type checking or subclassing.\n"); … … 220 220 " -> a Scalar node\n\n" 221 221 "_syck.Scalar represents a scalar node in Syck parser and emitter\n" 222 " trees. A scalar node points to a single string value.\n");222 "graphs. A scalar node points to a single string value.\n"); 223 223 224 224 typedef struct { … … 549 549 "Seq(value=[], tag=None, inline=False) -> a Seq node\n\n" 550 550 "_syck.Seq represents a sequence node in Syck parser and emitter\n" 551 " trees. A sequence node points to an ordered set of subnodes.\n");551 "graphs. A sequence node points to an ordered set of subnodes.\n"); 552 552 553 553 typedef struct { … … 718 718 719 719 PyDoc_STRVAR(PySyckMap_doc, 720 "Map(value= {}, tag=None, inline=False) -> a Map node\n\n"720 "Map(value='', tag=None, inline=False) -> a Map node\n\n" 721 721 "_syck.Map represents a mapping node in Syck parser and emitter\n" 722 " trees. A mapping node points to an unordered collections of pairs.\n");722 "graphs. A mapping node points to an unordered collections of pairs.\n"); 723 723 724 724 typedef struct { … … 833 833 PyDoc_STR("the node kind, always 'map', read-only"), &PySyck_MapKind}, 834 834 {"value", (getter)PySyckNode_getvalue, (setter)PySyckMap_setvalue, 835 PyDoc_STR("the node value, a list of pairs or a dictionary"), NULL},835 PyDoc_STR("the node value, a mapping"), NULL}, 836 836 {"tag", (getter)PySyckNode_gettag, (setter)PySyckNode_settag, 837 837 PyDoc_STR("the node tag, a string or None"), NULL}, … … 893 893 " -> a Parser object\n\n" 894 894 "_syck.Parser is a low-lever wrapper of the Syck parser. It parses\n" 895 "a YAML stream and produces a treeof Nodes.\n");895 "a YAML stream and produces a graph of Nodes.\n"); 896 896 897 897 typedef struct { … … 1017 1017 static PyGetSetDef PySyckParser_getsetters[] = { 1018 1018 {"source", (getter)PySyckParser_getsource, NULL, 1019 PyDoc_STR("IO source, a string or afile-like object"), NULL},1019 PyDoc_STR("IO source, a string or file-like object"), NULL}, 1020 1020 {"implicit_typing", (getter)PySyckParser_getimplicit_typing, NULL, 1021 1021 PyDoc_STR("implicit typing of builtin YAML types"), NULL}, … … 1253 1253 1254 1254 if (self->parsing) { 1255 PyErr_SetString(PyExc_RuntimeError, 1256 "do not call Parser.parse while it is already running"); 1255 PyErr_SetString(PyExc_RuntimeError, "do not call Parser.parse while it is already parsing"); 1257 1256 return NULL; 1258 1257 } … … 1293 1292 PyDoc_STRVAR(PySyckParser_parse_doc, 1294 1293 "parse() -> the root Node object\n\n" 1295 "Parses the source and returns the root of the Node tree. Call it\n" 1296 "several times to retrieve all documents from the source. On EOF,\n" 1297 "returns None and sets the 'eof' attribute on.\n"); 1294 "Parses the source and returns the next document. On EOF, returns None\n" 1295 "and sets the 'eof' attribute on.\n"); 1298 1296 1299 1297 static PyMethodDef PySyckParser_methods[] = { … … 1350 1348 1351 1349 PyDoc_STRVAR(PySyckEmitter_doc, 1352 "Emitter(output, headless=False, use_header=False, use_version=False,\n" 1353 " explicit_typing=True, style=None, best_width=80, indent=2)\n" 1354 " -> an Emitter object\n\n" 1355 "_syck.Emitter is a low-lever wrapper of the Syck emitter. It emits\n" 1350 "Emitter(output, headless=False, use_header=True, explicit_typing=True," 1351 " style=None, best_width=80, indent=2) -> an Emitter object\n\n" 1352 "_syck.Emitter is a low-lever wrapper of the Syck emitter. It emit\n" 1356 1353 "a tree of Nodes into a YAML stream.\n"); 1357 1354 … … 1533 1530 PyDoc_STR("headerless document flag"), NULL}, 1534 1531 {"use_header", (getter)PySyckEmitter_getuse_header, NULL, 1535 PyDoc_STR("force header flag"), NULL},1532 PyDoc_STR("force header"), NULL}, 1536 1533 {"use_version", (getter)PySyckEmitter_getuse_version, NULL, 1537 PyDoc_STR("force version flag"), NULL},1534 PyDoc_STR("force version"), NULL}, 1538 1535 {"explicit_typing", (getter)PySyckEmitter_getexplicit_typing, NULL, 1539 1536 PyDoc_STR("explicit typing for all collections"), NULL}, … … 1755 1752 Py_INCREF(output); 1756 1753 self->output = output; 1754 1755 /* 1756 self->emitter = syck_new_emitter(); 1757 self->emitter->bonus = self; 1758 self->emitter->headless = self->headless; 1759 self->emitter->use_header = use_header; 1760 self->emitter->use_version = use_version; 1761 self->emitter->explicit_typing = explicit_typing; 1762 self->emitter->style = self->style; 1763 self->emitter->best_width = self->best_width; 1764 self->emitter->indent = self->indent; 1765 1766 syck_emitter_handler(self->emitter, PySyckEmitter_node_handler); 1767 syck_output_handler(self->emitter, PySyckEmitter_write_handler); 1768 */ 1757 1769 1758 1770 self->emitting = 0; … … 1962 1974 PyDoc_STRVAR(PySyckEmitter_emit_doc, 1963 1975 "emit(root_node) -> None\n\n" 1964 "Emit sthe Node tree to the output.\n");1976 "Emit the Node tree to the output.\n"); 1965 1977 1966 1978 static PyMethodDef PySyckEmitter_methods[] = { … … 2021 2033 2022 2034 PyDoc_STRVAR(PySyck_doc, 2023 "_syck is a low-level wrapper for the Syck YAML parser and emitter.\n" 2024 "Do not use it directly, use the module 'syck' instead.\n"); 2025 2026 static int 2027 add_slotnames(PyTypeObject *type) 2028 { 2029 PyObject *slotnames; 2030 PyObject *name; 2031 PyGetSetDef *getsetter; 2032 2033 if (!type->tp_getset) return 0; 2034 if (!type->tp_dict) return 0; 2035 2036 slotnames = PyList_New(0); 2037 if (!slotnames) return -1; 2038 2039 for (getsetter = type->tp_getset; getsetter->name; getsetter++) { 2040 if (!getsetter->set) continue; 2041 name = PyString_FromString(getsetter->name); 2042 if (!name) { 2043 Py_DECREF(slotnames); 2044 return -1; 2045 } 2046 if (PyList_Append(slotnames, name) < 0) { 2047 Py_DECREF(name); 2048 Py_DECREF(slotnames); 2049 return -1; 2050 } 2051 Py_DECREF(name); 2052 } 2053 2054 if (PyDict_SetItemString(type->tp_dict, "__slotnames__", slotnames) < 0) { 2055 Py_DECREF(slotnames); 2056 return -1; 2057 } 2058 2059 Py_DECREF(slotnames); 2060 return 0; 2061 } 2035 "low-level wrapper for the Syck YAML parser and emitter"); 2062 2036 2063 2037 PyMODINIT_FUNC … … 2070 2044 if (PyType_Ready(&PySyckScalar_Type) < 0) 2071 2045 return; 2072 if (add_slotnames(&PySyckScalar_Type) < 0)2073 return;2074 2046 if (PyType_Ready(&PySyckSeq_Type) < 0) 2075 2047 return; 2076 if (add_slotnames(&PySyckSeq_Type) < 0)2077 return;2078 2048 if (PyType_Ready(&PySyckMap_Type) < 0) 2079 return;2080 if (add_slotnames(&PySyckMap_Type) < 0)2081 2049 return; 2082 2050 if (PyType_Ready(&PySyckParser_Type) < 0) -
/trunk/tests/test_dumper.py
r23 r20 1 2 from __future__ import generators3 1 4 2 import unittest 5 3 import syck 6 import StringIO 4 import StringIO, datetime, sets 7 5 import test_emitter 8 9 try:10 import datetime11 except:12 class _datetime:13 def datetime(self, *args):14 return args15 datetime = _datetime()16 17 try:18 import sets19 except:20 class _sets:21 def Set(self, items):22 set = {}23 for items in items:24 set[items] = None25 return set26 sets = _sets()27 28 6 29 7 EXAMPLE = { … … 158 136 for a, b in zip(scalars, SCALARS): 159 137 self.assertEqual(type(a), type(b)) 160 if type(a) is float: 161 self.assertEqual(repr(a), repr(b)) 162 else: 163 self.assertEqual(a, b) 138 self.assertEqual(a, b) 164 139 165 140 class TestCollectionTypes(unittest.TestCase): -
/trunk/tests/test_parser.py
r23 r20 227 227 self.assertEqual(type(structure), list) 228 228 self.assertEqual(len(node.value), len(structure)) 229 for i in range(len(node.value)): 230 item = node.value[i] 229 for i, item in enumerate(node.value): 231 230 self.assertEqualStructure(item, structure[i]) 232 231 elif node.kind == 'map': -
/trunk/tests/test_loader.py
r23 r20 136 136 """ 137 137 138 MUTABLE_KEY = """139 ? []140 : []141 """142 143 138 class TestDocuments(test_parser.TestDocuments): 144 139 … … 186 181 187 182 def _testFileValues(self, (source, structure)): 188 tempfile = os.tmpfile() 189 tempfile.write(source) 190 tempfile.seek(0) 191 self.assertEqualStructure(syck.parse(tempfile), structure) 192 tempfile.seek(0) 193 self.assertEqual(syck.load(tempfile), structure) 194 tempfile.seek(0) 183 filename = os.tempnam('/tmp', '_syck_test_') 184 file(filename, 'wb').write(source) 185 try: 186 self.assertEqualStructure(syck.parse(file(filename)), structure) 187 self.assertEqual(syck.load(file(filename)), structure) 188 except: 189 os.remove(filename) 190 raise 195 191 196 192 class TestImplicitScalars(unittest.TestCase): … … 206 202 207 203 def testFloat(self): 208 self.assert Equal(syck.load('6.8523015e+5'), 685230.15)204 self.assertAlmostEqual(syck.load('6.8523015e+5'), 685230.15) 209 205 # Syck does not understand '_'. 210 206 #self.assertAlmostEqual(syck.load('685.230_15e+03'), 685230.15) 211 207 #self.assertAlmostEqual(syck.load('685_230.15'), 685230.15) 212 self.assert Equal(syck.load('685.23015e+03'), 685230.15)213 self.assert Equal(syck.load('685230.15'), 685230.15)214 self.assert Equal(syck.load('190:20:30.15'), 685230.15)215 self.assertEqual( repr(syck.load('-.inf')), repr(-INF))216 self.assertEqual( repr(syck.load('.nan')), repr(NAN))208 self.assertAlmostEqual(syck.load('685.23015e+03'), 685230.15) 209 self.assertAlmostEqual(syck.load('685230.15'), 685230.15) 210 self.assertAlmostEqual(syck.load('190:20:30.15'), 685230.15) 211 self.assertEqual(syck.load('-.inf'), -INF) 212 self.assertEqual(syck.load('.nan'), NAN) 217 213 218 214 def testInteger(self): … … 272 268 node = syck.parse(ALIASES) 273 269 values = node.value.values() 270 print values 271 print id(values[0]) 272 print id(values[1]) 274 273 self.assert_(values[0] is values[1]) 275 274 … … 278 277 self.assert_(document['foo'] is document['bar']) 279 278 280 class TestMutableKey(unittest.TestCase):281 282 def testMutableKey(self):283 document = syck.load(MUTABLE_KEY)284 self.assertEqual(type(document), list)285 self.assertEqual(len(document), 1)286 self.assertEqual(type(document[0]), tuple)287 self.assertEqual(len(document[0]), 2)288 self.assertEqual(document[0][0], document[0][1]) -
/trunk/tests/test_emitter.py
r23 r17 163 163 emitter = _syck.Emitter(StringIO.StringIO(), headless=False) 164 164 emitter.emit(CYCLE) 165 self.assert_( emitter.output.getvalue().find('---') != -1)165 self.assert_('---' in emitter.output.getvalue()) 166 166 emitter = _syck.Emitter(StringIO.StringIO(), headless=True) 167 167 emitter.emit(CYCLE) 168 self.assert_( emitter.output.getvalue().find('---') == -1)168 self.assert_('---' not in emitter.output.getvalue()) 169 169 170 170 def testUseHeader(self): 171 171 emitter = _syck.Emitter(StringIO.StringIO(), headless=True) 172 172 emitter.emit(EXAMPLE) 173 self.assert_( emitter.output.getvalue().find('---') == -1)173 self.assert_('---' not in emitter.output.getvalue()) 174 174 emitter = _syck.Emitter(StringIO.StringIO(), use_header=True) 175 175 emitter.emit(EXAMPLE) 176 self.assert_( emitter.output.getvalue().find('---') != -1)176 self.assert_('---' in emitter.output.getvalue()) 177 177 178 178 def testExplicitTyping(self): … … 235 235 document = parser.parse() 236 236 self.assertEqual(len(document.value), len(TAGS)) 237 for index in range(len(document.value)): 238 node = document.value[index] 237 for index, node in enumerate(document.value): 239 238 self.assertEqual(node.tag, TAGS[index]) 240 239 … … 283 282 284 283 285 #class TestSyckBugWithTrailingSpace(unittest.TestCase):286 # 287 #def testSyckBugWithTrailingSpace(self):288 #emitter = _syck.Emitter(StringIO.StringIO())289 #emitter.emit(_syck.Scalar('foo ', tag="tag:yaml.org,2002:str"))290 #parser = _syck.Parser(emitter.output.getvalue())291 #self.assertEqual(parser.parse().value, 'foo ')292 293 284 class TestSyckBugWithTrailingSpace(unittest.TestCase): 285 286 def testSyckBugWithTrailingSpace(self): 287 emitter = _syck.Emitter(StringIO.StringIO()) 288 emitter.emit(_syck.Scalar('foo ', tag="tag:yaml.org,2002:str")) 289 parser = _syck.Parser(emitter.output.getvalue()) 290 self.assertEqual(parser.parse().value, 'foo ') 291 292 -
/trunk/tests/test_syck.py
r21 r20 2 2 import unittest 3 3 4 from test_node import *4 #from test_node import * 5 5 from test_parser import * 6 6 from test_loader import * 7 7 from test_emitter import * 8 8 from test_dumper import * 9 from test_pickle import *10 9 11 10 def main(module='__main__'): -
/trunk/lib/syck/__init__.py
r25 r19 1 """2 YAML is a data serialization format designed for human readability and3 interaction with scripting languages.4 5 Syck is an extension for reading and writing YAML in scripting languages.6 7 PySyck provides Python bindings for Syck YAML parser and emitter.8 9 To start working with PySyck, import the package 'syck':10 >>> from syck import *11 12 To parse a YAML document into a Python object, use the function 'load()':13 >>> load('''14 ... - Mark McGwire15 ... - Sammy Sosa16 ... - Ken Griffey17 ... ''')18 ['Mark McGwire', 'Sammy Sosa', 'Ken Griffey']19 20 To emit a Python object into a YAML document, use the function 'dump()':21 >>> print dump(['Mark McGwire', 'Sammy Sosa', 'Ken Griffey'])22 ---23 - Mark McGwire24 - Sammy Sosa25 - Ken Griffey26 27 You may get access to the YAML parser tree using the function 'parse()':28 >>> root_node = parse('''29 ... - Mark McGwire30 ... - Sammy Sosa31 ... - Ken Griffey32 ... ''')33 >>> root_node34 <_syck.Seq object at 0xb7a1f874>35 >>> root_node.kind36 'seq'37 >>> root_node.value38 [<_syck.Scalar object at 0xb7a1e5fc>, <_syck.Scalar object at 0xb7a1e65c>, <_syck.Scalar object at 0xb7a1e6bc>]39 40 You may now use the function 'emit()' to obtain the YAML document again:41 >>> print emit(root_node)42 ---43 - Mark McGwire44 - Sammy Sosa45 - Ken Griffey46 47 What do you get if you apply the function 'dump()' to root_node? Let's try it:48 >>> print dump(root_node)49 --- !python/object:_syck.Seq50 value:51 - !python/object:_syck.Scalar52 value: Mark McGwire53 tag: tag:yaml.org,2002:str54 - !python/object:_syck.Scalar55 value: Sammy Sosa56 tag: tag:yaml.org,2002:str57 - !python/object:_syck.Scalar58 value: Ken Griffey59 tag: tag:yaml.org,2002:str60 61 As you can see, PySyck allow you to represent complex Python objects.62 63 You can also dump the generated YAML output into any file-like object:64 >>> import os65 >>> stream = os.tmpfile()66 >>> object = ['foo', 'bar', ['baz']]67 >>> dump(object, stream)68 >>> stream.seek(0)69 >>> print stream.read()70 ---71 - foo72 - bar73 - - baz74 75 To load several documents from a single YAML stream, use the function76 'load_documents()':77 >>> source = '''78 ... ---79 ... american:80 ... - Boston Red Sox81 ... - Detroit Tigers82 ... - New York Yankees83 ... national:84 ... - New York Mets85 ... - Chicago Cubs86 ... - Atlanta Braves87 ... ---88 ... - [name , hr, avg ]89 ... - [Mark McGwire, 65, 0.278]90 ... - [Sammy Sosa , 63, 0.288]91 ... '''92 >>> for document in load_documents(source):93 ... print document94 ...95 {'national': ['New York Mets', 'Chicago Cubs', 'Atlanta Braves'], 'american': ['Boston Red Sox', 'Detroit Tigers', 'New York Yankees']}96 [['name', 'hr', 'avg'], ['Mark McGwire', 65, 0.27800000000000002], ['Sammy Sosa', 63, 0.28799999999999998]]97 98 See the source code for more details.99 """100 101 1 102 2 from _syck import * -
/trunk/lib/syck/dumpers.py
r25 r20 1 """2 syck.dumpers is a high-level wrapper for the Syck YAML emitter.3 Do not use it directly, use the module 'syck' instead.4 """5 1 6 2 import _syck … … 14 10 'emit', 'dump', 'emit_documents', 'dump_documents'] 15 11 12 INF = 1e300000 13 NEGINF = -INF 14 NAN = INF/INF 15 16 16 17 class GenericDumper(_syck.Emitter): 17 """18 GenericDumper dumps native Python objects into YAML documents.19 """20 18 21 19 def dump(self, object): 22 """Dumps the given Python object as a YAML document."""23 20 self.emit(self._convert(object, {})) 24 21 25 22 def _convert(self, object, object_to_node): 26 23 if id(object) in object_to_node and self.allow_aliases(object): 27 return object_to_node[id(object)] [1]24 return object_to_node[id(object)] 28 25 node = self.represent(object) 29 object_to_node[id(object)] = object,node26 object_to_node[id(object)] = node 30 27 if node.kind == 'seq': 31 for index in range(len(node.value)): 32 item = node.value[index] 28 for index, item in enumerate(node.value): 33 29 node.value[index] = self._convert(item, object_to_node) 34 30 elif node.kind == 'map': 35 if isinstance(node.value, dict): 36 for key in node.value.keys(): 37 value = node.value[key] 38 del node.value[key] 39 node.value[self._convert(key, object_to_node)] = \ 40 self._convert(value, object_to_node) 41 elif isinstance(node.value, list): 42 for index in range(len(node.value)): 43 key, value = node.value[index] 44 node.value[index] = (self._convert(key, object_to_node), 45 self._convert(value, object_to_node)) 31 for key in node.value.keys(): 32 value = node.value[key] 33 del node.value[key] 34 node.value[self._convert(key, object_to_node)] = \ 35 self._convert(value, object_to_node) 46 36 # # Workaround against a Syck bug: 47 37 # if node.kind == 'scalar' and node.style not in ['1quote', '2quote'] \ … … 51 41 52 42 def represent(self, object): 53 """Represents the given Python object as a 'Node'."""54 43 if isinstance(object, dict): 55 44 return _syck.Map(object.copy(), tag="tag:yaml.org,2002:map") … … 60 49 61 50 def allow_aliases(self, object): 62 """Checks whether the given object can be aliased."""63 51 return True 64 52 65 53 class Dumper(GenericDumper): 66 """67 Dumper dumps native Python objects into YAML documents.68 """69 54 70 INF = 1e300000 71 inf_value = repr(INF) 72 neginf_value = repr(-INF) 73 nan_value = repr(INF/INF) 55 def __init__(self, *args, **kwds): 56 super(Dumper, self).__init__(*args, **kwds) 74 57 75 def find_representer(self, object): 76 """ 77 For the given object, find a method that can represent it as a 'Node' 78 object. 79 80 If the type of the object has the form 'package.module.type', 81 find_representer() returns the method 'represent_package_module_type'. 82 If this method does not exist, it checks the base types. 83 """ 58 def represent(self, object): 84 59 for object_type in type(object).__mro__: 85 60 if object_type.__module__ == '__builtin__': … … 87 62 else: 88 63 name = '%s.%s' % (object_type.__module__, object_type.__name__) 89 method = 'represent_ ' +name.replace('.', '_')64 method = 'represent_%s' % name.replace('.', '_') 90 65 if hasattr(self, method): 91 return getattr(self, method) 92 93 def represent(self, object): 94 """Represents the given Python object as a 'Node'.""" 95 representer = self.find_representer(object) 96 if representer: 97 return representer(object) 98 else: 99 return super(Dumper, self).represent(object) 66 return getattr(self, method)(object) 67 return super(Dumper, self).represent(object) 100 68 101 69 def represent_object(self, object): … … 120 88 return _syck.Scalar(repr(object), tag="tag:yaml.org,2002:int") 121 89 90 def represent_int(self, object): 91 return _syck.Scalar(repr(object), tag="tag:yaml.org,2002:int") 92 122 93 def represent_float(self, object): 123 94 value = repr(object) 124 if value == self.inf_value:95 if value == repr(INF): 125 96 value = '.inf' 126 elif value == self.neginf_value:97 elif value == repr(NEGINF): 127 98 value = '-.inf' 128 elif value == self.nan_value:99 elif value == repr(NAN): 129 100 value = '.nan' 130 101 return _syck.Scalar(value, tag="tag:yaml.org,2002:float") … … 132 103 def represent_sets_Set(self, object): 133 104 return _syck.Seq(list(object), tag="tag:yaml.org,2002:set") 134 represent_set = represent_sets_Set135 105 136 106 def represent_datetime_datetime(self, object): 137 107 return _syck.Scalar(object.isoformat(), tag="tag:yaml.org,2002:timestamp") 138 108 139 def represent_long(self, object):140 return _syck.Scalar(repr(object), tag="tag:python.yaml.org,2002:long")141 142 def represent_unicode(self, object):143 return _syck.Scalar(object.encode('utf-8'), tag="tag:python.yaml.org,2002:unicode")144 145 def represent_tuple(self, object):146 return _syck.Seq(list(object), tag="tag:python.yaml.org,2002:tuple")147 148 def represent_type(self, object):149 name = '%s.%s' % (object.__module__, object.__name__)150 return _syck.Scalar('', tag="tag:python.yaml.org,2002:name:"+name)151 represent_classobj = represent_type152 represent_class = represent_type153 # TODO: Python 2.2 does not provide the module name of a function154 represent_function = represent_type155 represent_builtin_function_or_method = represent_type156 157 def represent_instance(self, object):158 cls = object.__class__159 class_name = '%s.%s' % (cls.__module__, cls.__name__)160 args = ()161 state = {}162 if hasattr(object, '__getinitargs__'):163 args = object.__getinitargs__()164 if hasattr(object, '__getstate__'):165 state = object.__getstate__()166 elif not hasattr(object, '__getinitargs__'):167 state = object.__dict__.copy()168 if not args and isinstance(state, dict):169 return _syck.Map(state.copy(),170 tag="tag:python.yaml.org,2002:object:"+class_name)171 value = {}172 if args:173 value['args'] = list(args)174 if state or not isinstance(state, dict):175 value['state'] = state176 return _syck.Map(value,177 tag="tag:python.yaml.org,2002:new:"+class_name)178 179 def represent_object(self, object): # Do you understand this? I don't.180 cls = type(object)181 class_name = '%s.%s' % (cls.__module__, cls.__name__)182 args = ()183 state = {}184 if cls.__reduce__ is type.__reduce__:185 if hasattr(object, '__reduce_ex__'):186 reduce = object.__reduce_ex__(2)187 args = reduce[1][1:]188 else:189 reduce = object.__reduce__()190 if len(reduce) > 2:191 state = reduce[2]192 if state is None:193 state = {}194 if not args and isinstance(state, dict):195 return _syck.Map(state.copy(),196 tag="tag:python.yaml.org,2002:object:"+class_name)197 if not state and isinstance(state, dict):198 return _syck.Seq(list(args),199 tag="tag:python.yaml.org,2002:new:"+class_name)200 value = {}201 if args:202 value['args'] = list(args)203 if state or not isinstance(state, dict):204 value['state'] = state205 return _syck.Map(value,206 tag="tag:python.yaml.org,2002:new:"+class_name)207 else:208 reduce = object.__reduce__()209 cls = reduce[0]210 class_name = '%s.%s' % (cls.__module__, cls.__name__)211 args = reduce[1]212 state = None213 if len(reduce) > 2:214 state = reduce[2]215 if state is None:216 state = {}217 if not state and isinstance(state, dict):218 return _syck.Seq(list(args),219 tag="tag:python.yaml.org,2002:apply:"+class_name)220 value = {}221 if args:222 value['args'] = list(args)223 if state or not isinstance(state, dict):224 value['state'] = state225 return _syck.Map(value,226 tag="tag:python.yaml.org,2002:apply:"+class_name)227 228 def represent__syck_Node(self, object):229 object_type = type(object)230 type_name = '%s.%s' % (object_type.__module__, object_type.__name__)231 state = []232 if hasattr(object_type, '__slotnames__'):233 for name in object_type.__slotnames__:234 value = getattr(object, name)235 if value:236 state.append((name, value))237 return _syck.Map(state,238 tag="tag:python.yaml.org,2002:object:"+type_name)239 240 109 def allow_aliases(self, object): 241 """Checks whether the given object can be aliased."""242 110 if object is None or type(object) in [int, bool, float]: 243 111 return False 244 112 if type(object) is str and (not object or object.isalnum()): 245 113 return False 246 if type(object) is tuple and not object:247 return False248 114 return True 249 115 250 def emit(node, output=None, Dumper=Dumper, **parameters): 251 """ 252 Emits the given node to the output. 253 254 If output is None, returns the produced YAML document. 255 """ 116 def emit(node, output=None, **parameters): 256 117 if output is None: 257 118 dumper = Dumper(StringIO.StringIO(), **parameters) … … 262 123 return dumper.output.getvalue() 263 124 264 def dump(object, output=None, Dumper=Dumper, **parameters): 265 """ 266 Dumps the given object to the output. 267 268 If output is None, returns the produced YAML document. 269 """ 125 def dump(object, output=None, **parameters): 270 126 if output is None: 271 127 dumper = Dumper(StringIO.StringIO(), **parameters) … … 276 132 return dumper.output.getvalue() 277 133 278 def emit_documents(nodes, output=None, Dumper=Dumper, **parameters): 279 """ 280 Emits the list of nodes to the output. 281 282 If output is None, returns the produced YAML document. 283 """ 134 def emit_documents(nodes, output=None, **parameters): 284 135 if output is None: 285 136 dumper = Dumper(StringIO.StringIO(), **parameters) … … 291 142 return dumper.output.getvalue() 292 143 293 def dump_documents(objects, output=None, Dumper=Dumper, **parameters): 294 """ 295 Dumps the list of objects to the output. 296 297 If output is None, returns the produced YAML document. 298 """ 144 def dump_documents(objects, output=None, **parameters): 299 145 if output is None: 300 146 dumper = Dumper(StringIO.StringIO(), **parameters) -
/trunk/lib/syck/loaders.py
r25 r18 1 """2 syck.loaders is a high-level wrapper for the Syck YAML parser.3 Do not use it directly, use the module 'syck' instead.4 """5 1 6 2 # Python 2.2 compatibility … … 25 21 import _syck 26 22 27 import sys,re23 import re 28 24 29 25 __all__ = ['GenericLoader', 'Loader', … … 31 27 32 28 class GenericLoader(_syck.Parser): 33 """34 GenericLoader constructs primitive Python objects from YAML documents.35 """36 29 37 30 def load(self): 38 """39 Loads a YAML document from the source and return a native Python40 object. On EOF, returns None and set the eof attribute on.41 """42 31 node = self.parse() 43 32 if self.eof: … … 61 50 value_object = self._convert(node.value[key_node], 62 51 node_to_object) 52 if key_object in value: 53 value = None 54 break 63 55 try: 64 if key_object in value:65 value = None66 break67 56 value[key_object] = value_object 68 57 except TypeError: … … 72 61 value = [] 73 62 for key_node in node.value: 74 key_object = self ._convert(key_node, node_to_object)63 key_object = self_convert(key_node, node_to_object) 75 64 value_object = self._convert(node.value[key_node], 76 65 node_to_object) … … 82 71 83 72 def construct(self, node): 84 """Constructs a Python object by the given node."""85 73 return node.value 86 74 87 75 class Merge: 88 """Represents the merge key '<<'."""89 76 pass 90 77 91 78 class Default: 92 """Represents the default key '='."""93 79 pass 94 80 95 81 class Loader(GenericLoader): 96 """97 Loader constructs native Python objects from YAML documents.98 """99 82 100 83 inf_value = 1e300000 101 84 nan_value = inf_value/inf_value 102 85 86 ymd_expr = re.compile(r'(?P<year>\d\d\d\d)-(?P<month>\d\d)-(?P<day>\d\d)') 103 87 timestamp_expr = re.compile(r'(?P<year>\d\d\d\d)-(?P<month>\d\d)-(?P<day>\d\d)' 104 88 r'(?:' … … 111 95 default_key = Default() 112 96 113 non_ascii = [] 114 for i in range(256): 115 ch = chr(i) 116 if ch.isalnum(): 117 non_ascii.append(ch) 118 else: 119 non_ascii.append('_') 120 non_ascii = ''.join(non_ascii) 121 122 python_bools = {'True': True, 'False': False} 123 124 class python_class: 125 pass 126 127 def find_constructor(self, node): 128 """ 129 Returns the contructor for generating a Python object for the given 130 node. 131 132 The node tags are mapped to constructors by the following rule: 133 134 Tag Constructor 135 --- ----------- 136 tag:yaml.org,2002:type construct_type 137 tag:python.yaml.org,2002:type construct_python_type 138 x-private:type construct_private_type 139 tag:domain.tld,2002:type construct_domain_tld_2002_type 140 141 See the method code for more details. 142 """ 143 parts = [] 144 if node.tag: 145 parts = node.tag.split(':') 146 if parts: 147 if parts[0] == 'tag': 148 parts.pop(0) 149 if parts: 150 if parts[0] == 'yaml.org,2002': 151 parts.pop(0) 152 elif parts[0] == 'python.yaml.org,2002': 153 parts[0] = 'python' 154 elif parts[0] == 'x-private': 155 parts[0] = 'private' 156 parts = [part.translate(self.non_ascii) for part in parts] 157 while parts: 158 method = 'construct_'+'_'.join(parts) 159 if hasattr(self, method): 160 return getattr(self, method) 161 parts.pop() 97 def __init__(self, *args, **kwds): 98 super(Loader, self).__init__(*args, **kwds) 99 self.tags = {} 100 self.add_builtin_types() 101 102 def add_builtin_types(self): 103 self.add_builtin_type('null', lambda node: None) 104 self.add_builtin_type('bool#yes', lambda node: True) 105 self.add_builtin_type('bool#no', lambda node: False) 106 self.add_builtin_type('float#fix', lambda node: float(node.value)) 107 self.add_builtin_type('float#exp', lambda node: float(node.value)) 108 self.add_builtin_type('float#base60', 'construct_base60_float') 109 self.add_builtin_type('float#inf', lambda node: self.inf_value) 110 self.add_builtin_type('float#neginf', lambda node: -self.inf_value) 111 self.add_builtin_type('float#nan', lambda node: self.nan_value) 112 self.add_builtin_type('int', lambda node: int(node.value)) 113 self.add_builtin_type('int#hex', lambda node: int(node.value, 16)) 114 self.add_builtin_type('int#oct', lambda node: int(node.value, 8)) 115 self.add_builtin_type('int#base60', 'construct_base60_int') 116 self.add_builtin_type('binary', lambda node: node.value.decode('base64')) 117 self.add_builtin_type('timestamp#ymd', 'construct_timestamp') 118 self.add_builtin_type('timestamp#iso8601', 'construct_timestamp') 119 self.add_builtin_type('timestamp#spaced', 'construct_timestamp') 120 self.add_builtin_type('timestamp', 'construct_timestamp') 121 self.add_builtin_type('merge', 'construct_merge') 122 self.add_builtin_type('default', 'construct_default') 123 self.add_builtin_type('omap', 'construct_omap') 124 self.add_builtin_type('pairs', 'construct_pairs') 125 self.add_builtin_type('set', 'construct_set') 126 127 def add_type(self, type_tag, constuctor): 128 self.tags[type_tag] = constructor 129 130 def add_domain_type(self, domain, type_tag, constructor): 131 self.tags['tag:%s:%s' % (domain, type_tag)] = constructor 132 133 def add_builtin_type(self, type_tag, constructor): 134 self.tags['tag:yaml.org,2002:'+type_tag] = constructor 135 136 def add_python_type(self, type_tag, constructor): 137 self.tags['tag:python.yaml.org,2002:'+type_tag] = constructor 138 139 def add_private_type(self, type_tag, constructor): 140 self.tags['x-private:'+type_tag] = constructor 162 141 163 142 def construct(self, node): 164 """Constructs a Python object by the given node."""165 143 if node.kind == 'map' and self.merge_key in node.value: 166 144 self.merge_maps(node) 167 constructor = self.find_constructor(node) 168 if constructor: 145 if node.tag in self.tags: 146 constructor = self.tags[node.tag] 147 if isinstance(constructor, str): 148 constructor = getattr(self, constructor) 169 149 return constructor(node) 170 150 else: 171 151 return node.value 172 152 173 def construct_null(self, node): 174 return None 175 176 def construct_bool_yes(self, node): 177 return True 178 179 def construct_bool_no(self, node): 180 return False 181 182 def construct_numeric_base60(self, num_type, node): 153 def construct_base60_float(self, node): 154 return self.construct_base60(float, node) 155 156 def construct_base60_int(self, node): 157 return self.construct_base60(int, node) 158 159 def construct_base60(self, num_type, node): 183 160 digits = [num_type(part) for part in node.value.split(':')] 184 161 digits.reverse() … … 189 166 base *= 60 190 167 return value 191 192 def construct_int(self, node):193 return int(node.value)194 195 def construct_int_hex(self, node):196 return int(node.value, 16)197 198 def construct_int_oct(self, node):199 return int(node.value, 8)200 201 def construct_int_base60(self, node):202 return self.construct_numeric_base60(int, node)203 204 def construct_float(self, node):205 return float(node.value)206 construct_float_fix = construct_float207 construct_float_exp = construct_float208 209 def construct_float_base60(self, node):210 return self.construct_numeric_base60(float, node)211 212 def construct_float_inf(self, node):213 return self.inf_value214 215 def construct_float_neginf(self, node):216 return -self.inf_value217 218 def construct_float_nan(self, node):219 return self.nan_value220 221 def construct_binary(self, node):222 return node.value.decode('base64')223 168 224 169 def construct_timestamp(self, node): … … 238 183 diff = datetime.timedelta(hours=values['zhour'], minutes=values['zminute']) 239 184 return stamp-diff 240 construct_timestamp_ymd = construct_timestamp241 construct_timestamp_iso8601 = construct_timestamp242 construct_timestamp_spaced = construct_timestamp243 185 244 186 def construct_merge(self, node): … … 275 217 return sets.Set(node.value) 276 218 277 def construct_python_none(self, node): 278 return None 279 280 def construct_python_bool(self, node): 281 return self.python_bools[node.value] 282 283 def construct_python_int(self, node): 284 return int(node.value) 285 286 def construct_python_long(self, node): 287 return long(node.value) 288 289 def construct_python_float(self, node): 290 return float(node.value) 291 292 def construct_python_str(self, node): 293 return str(node.value) 294 295 def construct_python_unicode(self, node): 296 return unicode(node.value, 'utf-8') 297 298 def construct_python_list(self, node): 299 return node.value 300 301 def construct_python_tuple(self, node): 302 return tuple(node.value) 303 304 def construct_python_dict(self, node): 305 return node.value 306 307 def find_python_object(self, node): 308 full_name = node.tag.split(':')[3] 309 parts = full_name.split('.') 310 object_name = parts.pop() 311 module_name = '.'.join(parts) 312 if not module_name: 313 module_name = '__builtin__' 314 else: 315 __import__(module_name) 316 return getattr(sys.modules[module_name], object_name) 317 318 def find_python_state(self, node): 319 if node.kind == 'seq': 320 args = node.value 321 kwds = {} 322 state = {} 323 else: 324 args = node.value.get('args', []) 325 kwds = node.value.get('kwds', {}) 326 state = node.value.get('state', {}) 327 return args, kwds, state 328 329 def set_python_state(self, object, state): 330 if hasattr(object, '__setstate__'): 331 object.__setstate__(state) 332 else: 333 slotstate = {} 334 if isinstance(state, tuple) and len(state) == 2: 335 state, slotstate = state 336 if hasattr(object, '__dict__'): 337 object.__dict__.update(state) 338 elif state: 339 slotstate.update(state) 340 for key, value in slotstate.items(): 341 setattr(object, key, value) 342 343 def construct_python_name(self, node): 344 return self.find_python_object(node) 345 346 def construct_python_object(self, node): 347 cls = self.find_python_object(node) 348 if type(cls) is type(self.python_class): 349 if hasattr(cls, '__getnewargs__'): 350 object = cls() 351 else: 352 object = self.python_class() 353 object.__class__ = cls 354 else: 355 object = cls.__new__(cls) 356 self.set_python_state(object, node.value) 357 return object 358 359 def construct_python_new(self, node): 360 cls = self.find_python_object(node) 361 args, kwds, state = self.find_python_state(node) 362 if type(cls) is type(self.python_class): 363 object = cls(*args, **kwds) 364 else: 365 object = cls.__new__(cls, *args, **kwds) 366 self.set_python_state(object, state) 367 return object 368 369 def construct_python_apply(self, node): 370 constructor = self.find_python_object(node) 371 args, kwds, state = self.find_python_state(node) 372 object = constructor(*args, **kwds) 373 self.set_python_state(object, state) 374 return object 375 376 def parse(source, Loader=Loader, **parameters): 219 def parse(source): 377 220 """Parses 'source' and returns the root of the 'Node' graph.""" 378 loader = Loader(source , **parameters)221 loader = Loader(source) 379 222 return loader.parse() 380 223 381 def load(source , Loader=Loader, **parameters):224 def load(source): 382 225 """Parses 'source' and returns the root object.""" 383 loader = Loader(source , **parameters)226 loader = Loader(source) 384 227 return loader.load() 385 228 386 def parse_documents(source , Loader=Loader, **parameters):387 """Iterates over 'source' and yields the root 'Node' foreach document."""388 loader = Loader(source , **parameters)229 def parse_documents(source): 230 """Iterates over 'source' and yields the root node of each document.""" 231 loader = Loader(source) 389 232 while True: 390 233 node = loader.parse() … … 393 236 yield node 394 237 395 def load_documents(source , Loader=Loader, **parameters):396 """Iterates over 'source' and yields the root object foreach document."""397 loader = Loader(source , **parameters)238 def load_documents(source): 239 """Iterates over 'source' and yields the root object of each document.""" 240 loader = Loader(source) 398 241 while True: 399 242 object = loader.load() -
/trunk/setup.py
r27 r3 1 2 NAME = 'PySyck'3 VERSION = '0.55.1'4 DESCRIPTION = "Python bindings for the Syck YAML parser and emitter"5 LONG_DESCRIPTION = """\6 YAML is a data serialization format designed for human readability7 and interaction with scripting languages. Syck is an extension for8 reading and writing YAML in scripting languages. PySyck is aimed to9 update the current Python bindings for Syck."""10 AUTHOR = "Kirill Simonov"11 AUTHOR_EMAIL = 'xi@resolvent.net'12 LICENSE = "BSD"13 PLATFORMS = "Any"14 URL = "http://xitology.org/pysyck/"15 DOWNLOAD_URL = URL + "%s-%s.tar.gz" % (NAME, VERSION)16 CLASSIFIERS = [17 "Development Status :: 3 - Alpha",18 "Intended Audience :: Developers",19 "License :: OSI Approved :: BSD License",20 "Programming Language :: Python",21 "Topic :: Software Development :: Libraries :: Python Modules",22 "Topic :: Text Processing :: Markup",23 ]24 1 25 2 from distutils.core import setup, Extension … … 35 12 36 13 setup( 37 name=NAME, 38 version=VERSION, 39 description=DESCRIPTION, 40 long_description=LONG_DESCRIPTION, 41 author=AUTHOR, 42 author_email=AUTHOR_EMAIL, 43 license=LICENSE, 44 platforms=PLATFORMS, 45 url=URL, 46 download_url=DOWNLOAD_URL, 47 classifiers=CLASSIFIERS, 48 14 name='Syck', 15 version='0.55.1', 49 16 package_dir={'': 'lib'}, 50 17 packages=['syck'], … … 56 23 ), 57 24 ], 25 description="Python bindings for the Syck YAML parser", 26 author="Kirill Simonov", 27 author_email="xi@resolvent.net", 28 license="BSD", 29 url="http://xitology.org/python-syck/", 30 download_url="http://xitology.org/*FIXME*", 31 classifiers=[ 32 "Development Status :: 2 - Pre-Alpha", 33 "Intended Audience :: Developers", 34 "License :: OSI Approved :: BSD License", 35 "Programming Language :: Python", 36 "Topic :: Software Development :: Libraries :: Python Modules", 37 "Topic :: Text Processing :: Markup", 38 ], 58 39 ) 59 40
Note: See TracChangeset
for help on using the changeset viewer.
