- Timestamp:
- 07/16/05 15:14:11 (8 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 4 edited
-
Makefile (modified) (2 diffs)
-
ext/_syckmodule.c (modified) (1 diff)
-
sandbox/syck-parser/syck-parser.c (modified) (2 diffs)
-
sandbox/syck-parser/test.yml (added)
-
sandbox/syck-parser/test_error.yml (added)
-
sandbox/syck-parser/test_my_typing.yml (added)
-
sandbox/syck-parser/test_typing.yml (added)
-
tests/test_syck.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Makefile
r3 r4 1 1 2 .PHONY: default build install test clean2 .PHONY: default build force install test clean 3 3 4 4 PYTHON=/usr/bin/python … … 10 10 ${PYTHON} setup.py build 11 11 12 force: 13 ${PYTHON} setup.py build -f 14 12 15 install: build 13 16 ${PYTHON} setup.py install 14 17 15 18 test: build 16 ${PYTHON} tests/test_build.py ${TEST}19 ${PYTHON} tests/test_build.py -v ${TEST} 17 20 18 21 clean: -
trunk/ext/_syckmodule.c
r3 r4 3 3 #include <syck.h> 4 4 5 static PyMethodDef _syck_methods[] = { 5 /* Global objects. */ 6 7 static PyObject *_syck_Error; 8 9 static PyObject *_syck_ScalarKind; 10 static PyObject *_syck_SeqKind; 11 static PyObject *_syck_MapKind; 12 13 /* Node type. */ 14 15 typedef struct { 16 PyObject_HEAD 17 PyObject *kind; 18 PyObject *type_id; 19 PyObject *value; 20 } _syck_Node; 21 22 static void 23 _syck_Node_dealloc(_syck_Node *self) 24 { 25 Py_XDECREF(self->kind); 26 Py_XDECREF(self->type_id); 27 Py_XDECREF(self->value); 28 PyObject_Del(self); 29 } 30 31 static PyObject * 32 _syck_Node_getattr(_syck_Node *self, char *name) 33 { 34 PyObject *value; 35 36 if (strcmp(name, "kind") == 0) 37 value = self->kind; 38 else if (strcmp(name, "type_id") == 0) 39 value = self->type_id; 40 else if (strcmp(name, "value") == 0) 41 value = self->value; 42 else { 43 PyErr_SetString(PyExc_AttributeError, name); 44 return NULL; 45 } 46 47 Py_INCREF(value); 48 return value; 49 } 50 51 static char _syck_Node_doc[] = 52 "Node object\n" 53 "\n" 54 "Attributes of the Node object:\n\n" 55 "kind -- 'scalar', 'seq', or 'map'.\n" 56 "type_id -- the tag of the node.\n" 57 "value -- the value of the node, a string, list or dict object.\n"; 58 59 static PyTypeObject _syck_NodeType = { 60 PyObject_HEAD_INIT(NULL) 61 0, /* ob_size */ 62 "_syck.Node", /* tp_name */ 63 sizeof(_syck_Node), /* tp_basicsize */ 64 0, /* tp_itemsize */ 65 (destructor)_syck_Node_dealloc, /* tp_dealloc */ 66 0, /* tp_print */ 67 (getattrfunc)_syck_Node_getattr, /* tp_getattr */ 68 0, /* tp_setattr */ 69 0, /* tp_compare */ 70 0, /* tp_repr */ 71 0, /* tp_as_number */ 72 0, /* tp_as_sequence */ 73 0, /* tp_as_mapping */ 74 0, /* tp_hash */ 75 0, /* tp_call */ 76 0, /* tp_str */ 77 0, /* tp_getattro */ 78 0, /* tp_setattro */ 79 0, /* tp_as_buffer */ 80 Py_TPFLAGS_DEFAULT, /* tp_flags */ 81 _syck_Node_doc, /* tp_doc */ 82 }; 83 84 static PyObject * 85 _syck_NewNode(PyObject *self, PyObject *args) 86 { 87 if (!PyArg_ParseTuple(args, ":_syck.Node")) 88 return NULL; 89 90 PyErr_SetString(PyExc_TypeError, "Node object cannot be created explicitly. Use _syck.Parser.parse() instead."); 91 return NULL; 92 } 93 94 static char _syck_NewNode_doc[] = 95 "Node object cannot be created explicitly. Use _syck.Parser.parse() instead."; 96 97 static PyObject * 98 _syck_NewNode_FromValue(char *type_id, PyObject *value) /* Note: steals the reference to the value. */ 99 { 100 _syck_Node *self; 101 PyObject *kind; 102 103 self = PyObject_NEW(_syck_Node, &_syck_NodeType); 104 if (!self) { 105 Py_XDECREF(value); 106 return NULL; 107 } 108 109 self->value = value; 110 111 if (PyList_Check(value)) 112 kind = _syck_SeqKind; 113 else if (PyDict_Check(value)) 114 kind = _syck_MapKind; 115 else 116 kind = _syck_ScalarKind; 117 Py_INCREF(kind); 118 self->kind = kind; 119 120 if (type_id) { 121 self->type_id = PyString_FromString(type_id); 122 if (!self->type_id) { 123 Py_DECREF(self); 124 return NULL; 125 } 126 } 127 else { 128 Py_INCREF(Py_None); 129 self->type_id = Py_None; 130 } 131 132 return (PyObject *)self; 133 } 134 135 /* Parser type. */ 136 137 typedef struct { 138 PyObject_HEAD 139 PyObject *source; 140 PyObject *resolver; 141 PyObject *symbols; 142 int error_state; 143 int mark; 144 SyckParser *parser; 145 } _syck_Parser; 146 147 static PyObject * 148 _syck_Parser_parse(_syck_Parser *self, PyObject *args) 149 { 150 SYMID index; 151 PyObject *value; 152 153 if (!PyArg_ParseTuple(args, ":parse")) 154 return NULL; 155 156 if (!self->parser) { 157 PyErr_SetString(PyExc_TypeError, "Parser object is closed"); 158 return NULL; 159 } 160 161 self->symbols = PyList_New(0); 162 if (!self->symbols) { 163 return NULL; 164 } 165 166 index = syck_parse(self->parser); 167 if (!self->error_state && !self->parser->eof) { 168 value = PyList_GetItem(self->symbols, index-1); 169 } 170 171 Py_DECREF(self->symbols); 172 173 if (self->error_state) { 174 self->error_state = 0; 175 return NULL; 176 } 177 178 if (self->parser->eof) { 179 Py_INCREF(Py_None); 180 return Py_None; 181 } 182 183 return value; 184 } 185 186 static char _syck_Parser_parse_doc[] = 187 "Parses the next document in the YAML stream, return the root Node object or None on EOF."; 188 189 static PyObject * 190 _syck_Parser_parse_documents(_syck_Parser *self, PyObject *args) 191 { 192 SYMID index; 193 PyObject *value = NULL; 194 PyObject *result = NULL; 195 196 if (!PyArg_ParseTuple(args, ":parse_document")) 197 return NULL; 198 199 if (!self->parser) { 200 PyErr_SetString(PyExc_TypeError, "Parser object is closed"); 201 return NULL; 202 } 203 204 result = PyList_New(0); 205 if (!result) return NULL; 206 207 while (1) { 208 209 self->symbols = PyList_New(0); 210 if (!self->symbols) { 211 Py_DECREF(result); 212 return NULL; 213 }; 214 215 index = syck_parse(self->parser); 216 217 if (!self->error_state && !self->parser->eof) { 218 value = PyList_GetItem(self->symbols, index-1); 219 if (!value) { 220 Py_DECREF(self->symbols); 221 Py_DECREF(result); 222 return NULL; 223 } 224 if (PyList_Append(result, value) < 0) { 225 Py_DECREF(self->symbols); 226 Py_DECREF(value); 227 Py_DECREF(result); 228 return NULL; 229 } 230 Py_DECREF(value); 231 } 232 233 Py_DECREF(self->symbols); 234 235 if (self->error_state) { 236 self->error_state = 0; 237 Py_DECREF(result); 238 return NULL; 239 } 240 241 if (self->parser->eof) break; 242 } 243 244 return result; 245 } 246 247 static char _syck_Parser_parse_documents_doc[] = 248 "Parses the entire YAML stream and returns list of documents."; 249 250 static PyObject * 251 _syck_Parser_close(_syck_Parser *self, PyObject *args) 252 { 253 if (!PyArg_ParseTuple(args, ":close")) 254 return NULL; 255 256 Py_XDECREF(self->source); 257 self->source = NULL; 258 259 if (self->parser) { 260 syck_free_parser(self->parser); 261 } 262 self->parser = NULL; 263 264 Py_INCREF(Py_None); 265 return Py_None; 266 } 267 268 static char _syck_Parser_close_doc[] = 269 "Closes the parser and frees memory"; 270 271 static PyMethodDef _syck_Parser_methods[] = { 272 {"parse", (PyCFunction)_syck_Parser_parse, METH_VARARGS, _syck_Parser_parse_doc}, 273 {"parse_documents", (PyCFunction)_syck_Parser_parse_documents, METH_VARARGS, _syck_Parser_parse_documents_doc}, 274 {"close", (PyCFunction)_syck_Parser_close, METH_VARARGS, _syck_Parser_close_doc}, 6 275 {NULL} /* Sentinel */ 7 276 }; 8 277 278 static void 279 _syck_Parser_dealloc(_syck_Parser *self) 280 { 281 Py_XDECREF(self->source); 282 if (self->parser) { 283 syck_free_parser(self->parser); 284 } 285 PyObject_Del(self); 286 } 287 288 static PyObject * 289 _syck_Parser_getattr(_syck_Parser *self, char *name) 290 { 291 return Py_FindMethod(_syck_Parser_methods, (PyObject *)self, name); 292 } 293 294 static char _syck_Parser_doc[] = 295 "_syck.Parser(yaml_string_or_file, implicit_typing=True, taguri_expansion=True) -> Parser object\n" 296 "\n" 297 "Methods of the Parser object:\n\n" 298 "parse() -- Parses the next document in the YAML stream, return the root Node object or None on EOF.\n" 299 "parse_documents() -- Parses the entire YAML stream and returns list of documents.\n" 300 "close() -- Closes the parser and frees memory.\n"; 301 302 static PyTypeObject _syck_ParserType = { 303 PyObject_HEAD_INIT(NULL) 304 0, /* ob_size */ 305 "_syck.Parser", /* tp_name */ 306 sizeof(_syck_Parser), /* tp_basicsize */ 307 0, /* tp_itemsize */ 308 (destructor)_syck_Parser_dealloc, /* tp_dealloc */ 309 0, /* tp_print */ 310 (getattrfunc)_syck_Parser_getattr, /* tp_getattr */ 311 0, /* tp_setattr */ 312 0, /* tp_compare */ 313 0, /* tp_repr */ 314 0, /* tp_as_number */ 315 0, /* tp_as_sequence */ 316 0, /* tp_as_mapping */ 317 0, /* tp_hash */ 318 0, /* tp_call */ 319 0, /* tp_str */ 320 0, /* tp_getattro */ 321 0, /* tp_setattro */ 322 0, /* tp_as_buffer */ 323 Py_TPFLAGS_DEFAULT, /* tp_flags */ 324 _syck_Parser_doc, /* tp_doc */ 325 }; 326 327 static long 328 _syck_Parser_io_file_read(char *buf, SyckIoFile *file, long max_size, long skip) 329 { 330 _syck_Parser *runtime = (_syck_Parser *)file->ptr; 331 332 PyObject *value; 333 334 char *str; 335 int length; 336 337 buf[skip] = '\0'; 338 339 if (runtime->error_state) { 340 return skip; 341 } 342 343 max_size -= skip; 344 345 value = PyObject_CallMethod(runtime->source, "read", "(i)", max_size); 346 if (!value) { 347 runtime->error_state = 1; 348 return skip; 349 } 350 351 if (!PyString_Check(value)) { 352 Py_DECREF(value); 353 PyErr_SetString(PyExc_TypeError, "file-like object should return a string"); 354 runtime->error_state = 1; 355 356 return skip; 357 } 358 359 str = PyString_AS_STRING(value); 360 length = PyString_GET_SIZE(value); 361 if (!length) { 362 Py_DECREF(value); 363 return skip; 364 } 365 366 if (length > max_size) { 367 Py_DECREF(value); 368 PyErr_SetString(PyExc_ValueError, "read returns an overly long string"); 369 runtime->error_state = 1; 370 return skip; 371 } 372 373 memcpy(buf+skip, str, length); 374 length += skip; 375 buf[length] = '\0'; 376 377 Py_DECREF(value); 378 379 return length; 380 } 381 382 static SYMID 383 _syck_Parser_node_handler(SyckParser *parser, SyckNode *node) 384 { 385 _syck_Parser *runtime = (_syck_Parser *)parser->bonus; 386 387 SYMID index; 388 PyObject *object = NULL; 389 390 PyObject *key, *value, *item; 391 int k; 392 393 if (runtime->error_state) 394 return 0; 395 396 switch (node->kind) { 397 398 case syck_str_kind: 399 object = PyString_FromStringAndSize(node->data.str->ptr, 400 node->data.str->len); 401 if (!object) goto error; 402 break; 403 404 case syck_seq_kind: 405 object = PyList_New(node->data.list->idx); 406 if (!object) goto error; 407 for (k = 0; k < node->data.list->idx; k++) { 408 index = syck_seq_read(node, k); 409 item = PyList_GetItem(runtime->symbols, index-1); 410 if (!item) goto error; 411 Py_INCREF(item); 412 PyList_SET_ITEM(object, k, item); 413 } 414 break; 415 416 case syck_map_kind: 417 object = PyDict_New(); 418 if (!object) goto error; 419 for (k = 0; k < node->data.pairs->idx; k++) 420 { 421 index = syck_map_read(node, map_key, k); 422 key = PyList_GetItem(runtime->symbols, index-1); 423 if (!key) goto error; 424 index = syck_map_read(node, map_value, k); 425 value = PyList_GetItem(runtime->symbols, index-1); 426 if (!value) goto error; 427 if (PyDict_SetItem(object, key, value) < 0) 428 goto error; 429 } 430 break; 431 } 432 433 object = _syck_NewNode_FromValue(node->type_id, object); 434 if (!object) goto error; 435 436 if (PyList_Append(runtime->symbols, object) < 0) 437 goto error; 438 439 index = PyList_Size(runtime->symbols); 440 return index; 441 442 error: 443 Py_XDECREF(object); 444 runtime->error_state = 1; 445 return 0; 446 } 447 448 static void 449 _syck_Parser_error_handler(SyckParser *parser, char *str) 450 { 451 _syck_Parser *runtime = (_syck_Parser *)parser->bonus; 452 PyObject *value; 453 454 if (runtime->error_state) return; 455 456 runtime->error_state = 1; 457 458 value = Py_BuildValue("(sii)", str, parser->linect, parser->cursor-parser->lineptr); 459 if (value) { 460 PyErr_SetObject(_syck_Error, value); 461 } 462 } 463 464 static PyObject * 465 _syck_NewParser(PyObject *self, PyObject *args, PyObject *kwds) 466 { 467 _syck_Parser *parser; 468 PyObject *source; 469 int implicit_typing = 1; 470 int taguri_expansion = 1; 471 472 static char *kwdlist[] = {"source", "implicit_typing", "taguri_expansion", NULL}; 473 474 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|ii", kwdlist, 475 &source, &implicit_typing, &taguri_expansion)) 476 return NULL; 477 478 parser = PyObject_NEW(_syck_Parser, &_syck_ParserType); 479 if (!parser) 480 return NULL; 481 482 Py_INCREF(source); 483 parser->source = source; 484 parser->error_state = 0; 485 486 parser->parser = syck_new_parser(); 487 parser->parser->bonus = parser; 488 489 if (PyString_Check(source)) { 490 syck_parser_str_auto(parser->parser, PyString_AS_STRING(source), NULL); 491 } 492 else { 493 syck_parser_file(parser->parser, (FILE *)parser, _syck_Parser_io_file_read); 494 } 495 syck_parser_implicit_typing(parser->parser, implicit_typing); 496 syck_parser_taguri_expansion(parser->parser, taguri_expansion); 497 498 syck_parser_handler(parser->parser, _syck_Parser_node_handler); 499 syck_parser_error_handler(parser->parser, _syck_Parser_error_handler); 500 /* 501 syck_parser_bad_anchor_handler(parser, _syck_Parser_bad_anchor_handler); 502 */ 503 504 return (PyObject *)parser; 505 } 506 507 static char _syck_NewParser_doc[] = 508 "Creates a new Parser object."; 509 510 /* The module definitions. */ 511 512 static PyMethodDef _syck_methods[] = { 513 {"Node", (PyCFunction)_syck_NewNode, METH_VARARGS, _syck_NewNode_doc}, 514 {"Parser", (PyCFunction)_syck_NewParser, METH_VARARGS|METH_KEYWORDS, _syck_NewParser_doc}, 515 {NULL} /* Sentinel */ 516 }; 517 9 518 static char _syck_doc[] = 10 519 "This module provides low-level access to the Syck parser and emitter.\n" 11 "Do not use this module directly, use the module 'syck' instead.\n";520 "Do not use this module directly, use the package 'syck' instead.\n"; 12 521 13 522 PyMODINIT_FUNC 14 523 init_syck(void) 15 524 { 16 Py_InitModule3("_syck", _syck_methods, _syck_doc); 17 } 18 525 PyObject *m; 526 527 _syck_NodeType.ob_type = &PyType_Type; 528 _syck_ParserType.ob_type = &PyType_Type; 529 530 _syck_Error = PyErr_NewException("_syck.error", NULL, NULL); 531 if (!_syck_Error) 532 return; 533 534 _syck_ScalarKind = PyString_FromString("scalar"); 535 if (!_syck_ScalarKind) 536 return; 537 _syck_SeqKind = PyString_FromString("seq"); 538 if (!_syck_SeqKind) 539 return; 540 _syck_MapKind = PyString_FromString("map"); 541 if (!_syck_MapKind) 542 return; 543 544 m = Py_InitModule3("_syck", _syck_methods, _syck_doc); 545 546 Py_INCREF(_syck_Error); 547 if (!PyModule_AddObject(m, "error", _syck_Error) < 0) 548 return; 549 550 Py_INCREF(&_syck_NodeType); 551 if (PyModule_AddObject(m, "NodeType", (PyObject *)&_syck_NodeType) < 0) 552 return; 553 554 Py_INCREF(&_syck_ParserType); 555 if (PyModule_AddObject(m, "ParserType", (PyObject *)&_syck_ParserType) < 0) 556 return; 557 } 558 -
trunk/sandbox/syck-parser/syck-parser.c
r2 r4 41 41 m->type_id = strdup(n->type_id); 42 42 } 43 else {43 /* else { 44 44 m->type_id = strdup(""); 45 } 45 }*/ 46 46 if (n->anchor) { 47 47 m->anchor = strdup(n->anchor); 48 48 } 49 else {49 /* else { 50 50 m->anchor = strdup(""); 51 } 51 }*/ 52 52 53 53 return m; … … 173 173 174 174 syck_parser_handler(p, node_handler); 175 syck_parser_error_handler(p, error_handler);175 // syck_parser_error_handler(p, error_handler); 176 176 syck_parser_bad_anchor_handler(p, bad_anchor_handler); 177 177 -
trunk/tests/test_syck.py
r3 r4 1 1 2 2 import unittest 3 4 3 import _syck, syck 5 6 7 class Test1(unittest.TestCase): 8 9 def testme(self): 10 pass 11 12 class Test2(unittest.TestCase): 13 14 def testmetoo(self): 15 pass 4 import StringIO 5 6 EXAMPLE = """ 7 - 8 avg: 0.278 9 hr: 65 10 name: Mark McGwire 11 - 12 avg: 0.288 13 hr: 63 14 name: Sammy Sosa 15 """ 16 17 INVALID = """ 18 - invalid 19 - document 20 """, 2, 0 21 22 COMPARE1 = """ 23 one: foo 24 two: bar 25 three: baz 26 """, { 27 'one': 'foo', 28 'two': 'bar', 29 'three': 'baz', 30 } 31 32 COMPARE2 = """ 33 - Mark McGwire 34 - Sammy Sosa 35 - Ken Griffey 36 """, [ 37 'Mark McGwire', 38 'Sammy Sosa', 39 'Ken Griffey', 40 ] 41 42 COMPARE3 = """ 43 american: 44 - Boston Red Sox 45 - Detroit Tigers 46 - New York Yankees 47 national: 48 - New York Mets 49 - Chicago Cubs 50 - Atlanta Braves 51 """, { 52 'american': [ 53 'Boston Red Sox', 54 'Detroit Tigers', 55 'New York Yankees', 56 ], 57 'national': [ 58 'New York Mets', 59 'Chicago Cubs', 60 'Atlanta Braves', 61 ], 62 } 63 64 DOCUMENTS0 = "" 65 66 DOCUMENTS1 = """ 67 --- 68 Time: 2001-11-23 15:01:42 -05:00 69 User: ed 70 Warning: > 71 This is an error message 72 for the log file 73 """ 74 75 DOCUMENTS2 = """ 76 --- 77 Time: 2001-11-23 15:01:42 -05:00 78 User: ed 79 Warning: > 80 This is an error message 81 for the log file 82 --- 83 Time: 2001-11-23 15:02:31 -05:00 84 User: ed 85 Warning: > 86 A slightly different error 87 message. 88 """ 89 90 DOCUMENTS3 = """ 91 --- 92 Time: 2001-11-23 15:01:42 -05:00 93 User: ed 94 Warning: > 95 This is an error message 96 for the log file 97 --- 98 Time: 2001-11-23 15:02:31 -05:00 99 User: ed 100 Warning: > 101 A slightly different error 102 message. 103 --- 104 Date: 2001-11-23 15:03:17 -05:00 105 User: ed 106 Fatal: > 107 Unknown variable "bar" 108 Stack: 109 - file: TopClass.py 110 line: 23 111 code: | 112 x = MoreObject("345\\n") 113 - file: MoreClass.py 114 line: 58 115 code: |- 116 foo = bar 117 """ 118 119 IMPLICIT_TYPING = """ 120 - 'foo' 121 - >- 122 bar 123 - baz 124 - 123 125 - 3.14 126 - true 127 - false 128 - [] 129 - {} 130 """, [ 131 ('str', True), 132 ('str', True), 133 ('str', False), 134 ('int', False), 135 ('float#fix', False), 136 ('bool#yes', False), 137 ('bool#no', False), 138 (None, False), 139 (None, False), 140 ] 141 142 EXPLICIT_TYPING = """ 143 - !int '123' 144 - !yamltype 'foo' 145 - !python/type 'bar' 146 - !domain.tld,2002/type 'baz' 147 - !!private 'private' 148 - !map {} 149 - !seq [] 150 """, [ 151 'tag:yaml.org,2002:int', 152 'tag:yaml.org,2002:yamltype', 153 'tag:python.yaml.org,2002:type', 154 'tag:domain.tld,2002:type', 155 'x-private:private', 156 'tag:yaml.org,2002:map', 157 'tag:yaml.org,2002:seq', 158 ] 159 160 class TestTypes(unittest.TestCase): 161 162 def testParserType(self): 163 parser = _syck.Parser(EXAMPLE) 164 self.assertEqual(type(parser), _syck.ParserType) 165 parser.close() 166 167 def testNodeType(self): 168 parser = _syck.Parser(EXAMPLE) 169 document = parser.parse() 170 self.assertEqual(type(document), _syck.NodeType) 171 parser.close() 172 173 def testNodeType2(self): 174 self.assertRaises(TypeError, (lambda: _syck.Node())) 175 176 class TestErrors(unittest.TestCase): 177 178 def testError(self): 179 parser = _syck.Parser(INVALID[0]) 180 self.assertRaises(_syck.error, (lambda: parser.parse())) 181 parser.close() 182 183 def testErrorLocation(self): 184 source, line, column = INVALID 185 parser = _syck.Parser(source) 186 try: 187 parser.parse() 188 raise Exception 189 except _syck.error, e: 190 self.assertEqual(e.args[1], line) 191 self.assertEqual(e.args[2], column) 192 193 class TestValuesAndSources(unittest.TestCase): 194 195 def testValues1(self): 196 self._testValues(COMPARE1) 197 198 def testValues2(self): 199 self._testValues(COMPARE2) 200 201 def testValues3(self): 202 self._testValues(COMPARE3) 203 204 def testFileValues1(self): 205 self._testFileValues(COMPARE1) 206 207 def testFileValues2(self): 208 self._testFileValues(COMPARE2) 209 210 def testFileValues3(self): 211 self._testFileValues(COMPARE3) 212 213 def testNonsense(self): 214 parser = _syck.Parser(None) 215 self.assertRaises(AttributeError, (lambda: parser.parse())) 216 parser.close() 217 218 def _testValues(self, (source, structure)): 219 parser = _syck.Parser(source) 220 document = parser.parse() 221 self.assertEqualStructure(document, structure) 222 parser.close() 223 224 def _testFileValues(self, (source, structure)): 225 parser = _syck.Parser(StringIO.StringIO(source)) 226 document = parser.parse() 227 self.assertEqualStructure(document, structure) 228 parser.close() 229 230 def assertEqualStructure(self, node, structure): 231 if node.kind == 'scalar': 232 self.assertEqual(type(structure), str) 233 self.assertEqual(node.value, structure) 234 elif node.kind == 'seq': 235 self.assertEqual(type(structure), list) 236 self.assertEqual(len(node.value), len(structure)) 237 for i, item in enumerate(node.value): 238 self.assertEqualStructure(item, structure[i]) 239 elif node.kind == 'map': 240 self.assertEqual(type(structure), dict) 241 self.assertEqual(len(node.value), len(structure)) 242 for key in node.value: 243 self.assert_(key.value in structure) 244 self.assertEqualStructure(node.value[key], structure[key.value]) 245 246 class TestDocuments(unittest.TestCase): 247 248 def testDocuments0(self): 249 self._testDocuments(DOCUMENTS0, 0) 250 251 def testDocuments1(self): 252 self._testDocuments(DOCUMENTS1, 1) 253 254 def testDocuments2(self): 255 self._testDocuments(DOCUMENTS2, 2) 256 257 def testDocuments3(self): 258 self._testDocuments(DOCUMENTS3, 3) 259 260 def _testDocuments(self, source, length): 261 parser = _syck.Parser(source) 262 documents = parser.parse_documents() 263 self.assertEqual(len(documents), length) 264 parser.close() 265 parser = _syck.Parser(source) 266 for k in range(length): 267 document = parser.parse() 268 self.assert_(document) 269 self.assertEqual(parser.parse(), None) 270 parser.close() 271 272 class TestImplicitTyping(unittest.TestCase): 273 274 def testImplicitAndExpansionTyping(self): 275 self._testTyping(True, True) 276 277 def testImplicitTyping(self): 278 self._testTyping(True, False) 279 280 def testExpansionTyping(self): 281 self._testTyping(False, True) 282 283 def testNoTyping(self): 284 self._testTyping(False, False) 285 286 def _testTyping(self, implicit_typing, taguri_expansion): 287 parser = _syck.Parser(IMPLICIT_TYPING[0], implicit_typing, taguri_expansion) 288 for node, (type_id, explicit) in zip(parser.parse().value, IMPLICIT_TYPING[1]): 289 if type_id is not None and taguri_expansion: 290 type_id = 'tag:yaml.org,2002:%s' % type_id 291 if implicit_typing or explicit: 292 self.assertEqual(node.type_id, type_id) 293 else: 294 self.assertEqual(node.type_id, None) 295 296 class TestExplicitTyping(unittest.TestCase): 297 298 def testExplicitTyping(self): 299 parser = _syck.Parser(EXPLICIT_TYPING[0]) 300 for node, type_id in zip(parser.parse().value, EXPLICIT_TYPING[1]): 301 self.assertEqual(node.type_id, type_id) 16 302 17 303 def main(module='__main__'):
Note: See TracChangeset
for help on using the changeset viewer.
