Changeset 6 for trunk


Ignore:
Timestamp:
07/17/05 12:08:23 (9 years ago)
Author:
xi
Message:

Remove methods Parser.parse_documents() and Parser.close(); add method Parser.eof() (closes #6).
Add resolver to Parser() (closes #4).

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/ext/_syckmodule.c

    r5 r6  
    138138    PyObject_HEAD 
    139139    PyObject *source; 
    140 /*    PyObject *resolver;*/ 
     140    PyObject *resolver; 
    141141    PyObject *symbols; 
    142142    SyckParser *syck; 
     
    144144} PySyckParserObject; 
    145145 
     146static void 
     147PySyckParser_free(PySyckParserObject *parser) 
     148{ 
     149    Py_XDECREF(parser->source); 
     150    parser->source = NULL; 
     151    Py_XDECREF(parser->resolver); 
     152    parser->resolver = NULL; 
     153    Py_XDECREF(parser->symbols); 
     154    parser->symbols = NULL; 
     155    if (parser->syck) { 
     156        syck_free_parser(parser->syck); 
     157        parser->syck = NULL; 
     158    } 
     159} 
     160 
    146161static PyObject * 
    147162PySyckParser_parse(PySyckParserObject *parser, PyObject *args) 
     
    154169 
    155170    if (!parser->syck) { 
    156         PyErr_SetString(PyExc_TypeError, "Parser object is closed"); 
     171        Py_INCREF(Py_None); 
     172        return Py_None; 
     173    } 
     174 
     175    if (parser->symbols) { 
     176        PyErr_SetString(PyExc_RuntimeError, "do not call Parser.parse while it is running"); 
    157177        return NULL; 
    158178    } 
     
    164184 
    165185    index = syck_parse(parser->syck); 
    166     if (!parser->error && !parser->syck->eof) { 
    167         value = PyList_GetItem(parser->symbols, index-1); 
    168     } 
    169  
    170     Py_DECREF(parser->symbols); 
    171186 
    172187    if (parser->error) { 
    173         parser->error = 0; 
     188        PySyckParser_free(parser); 
    174189        return NULL; 
    175190    } 
    176191 
    177192    if (parser->syck->eof) { 
     193        PySyckParser_free(parser); 
    178194        Py_INCREF(Py_None); 
    179195        return Py_None; 
    180196    } 
    181      
     197 
     198    value = PyList_GetItem(parser->symbols, index); 
     199 
     200    Py_DECREF(parser->symbols); 
     201    parser->symbols = NULL; 
     202 
    182203    return value; 
    183204} 
     
    187208 
    188209static PyObject * 
    189 PySyckParser_parse_documents(PySyckParserObject *parser, PyObject *args) 
    190 { 
    191     SYMID index; 
    192     PyObject *value = NULL; 
    193     PyObject *documents = NULL; 
    194  
    195     if (!PyArg_ParseTuple(args, ":parse_document")) 
    196         return NULL; 
    197  
    198     if (!parser->syck) { 
    199         PyErr_SetString(PyExc_TypeError, "Parser object is closed"); 
    200         return NULL; 
    201     } 
    202  
    203     documents = PyList_New(0); 
    204     if (!documents) return NULL; 
    205  
    206     while (1) { 
    207  
    208         parser->symbols = PyList_New(0); 
    209         if (!parser->symbols) { 
    210             Py_DECREF(documents); 
    211             return NULL; 
    212         }; 
    213  
    214         index = syck_parse(parser->syck); 
    215  
    216         if (!parser->error && !parser->syck->eof) { 
    217             value = PyList_GetItem(parser->symbols, index-1); 
    218             if (!value) { 
    219                 Py_DECREF(parser->symbols); 
    220                 Py_DECREF(documents); 
    221                 return NULL; 
    222             } 
    223             if (PyList_Append(documents, value) < 0) { 
    224                 Py_DECREF(parser->symbols); 
    225                 Py_DECREF(value); 
    226                 Py_DECREF(documents); 
    227                 return NULL; 
    228             } 
    229             Py_DECREF(value); 
    230         } 
    231  
    232         Py_DECREF(parser->symbols); 
    233  
    234         if (parser->error) { 
    235             parser->error = 0; 
    236             Py_DECREF(documents); 
    237             return NULL; 
    238         } 
    239  
    240         if (parser->syck->eof) break; 
    241     } 
    242  
    243     return documents; 
    244 } 
    245  
    246 static char PySyckParser_parse_documents_doc[] = 
    247     "Parses the entire YAML stream and returns list of documents."; 
    248  
    249 static PyObject * 
    250 PySyckParser_close(PySyckParserObject *parser, PyObject *args) 
    251 { 
    252     if (!PyArg_ParseTuple(args, ":close")) 
    253         return NULL; 
    254  
    255     Py_XDECREF(parser->source); 
    256     parser->source = NULL; 
    257  
    258     if (parser->syck) { 
    259         syck_free_parser(parser->syck); 
    260     } 
    261     parser->syck = NULL; 
    262  
    263     Py_INCREF(Py_None); 
    264     return Py_None; 
    265 } 
    266  
    267 static char PySyckParser_close_doc[] = 
    268     "Closes the parser and frees memory"; 
     210PySyckParser_eof(PySyckParserObject *parser, PyObject *args) 
     211{ 
     212    PyObject *value; 
     213 
     214    if (!PyArg_ParseTuple(args, ":eof")) 
     215        return NULL; 
     216 
     217    value = parser->syck ? Py_False : Py_True; 
     218 
     219    Py_INCREF(value); 
     220    return value; 
     221} 
     222 
     223static char PySyckParser_eof_doc[] = 
     224    "Checks if the parser is stopped."; 
    269225 
    270226static PyMethodDef PySyckParser_methods[] = { 
    271227    {"parse",  (PyCFunction)PySyckParser_parse, METH_VARARGS, PySyckParser_parse_doc}, 
    272     {"parse_documents",  (PyCFunction)PySyckParser_parse_documents, METH_VARARGS, PySyckParser_parse_documents_doc}, 
    273     {"close",  (PyCFunction)PySyckParser_close, METH_VARARGS, PySyckParser_close_doc}, 
     228    {"eof",  (PyCFunction)PySyckParser_eof, METH_VARARGS, PySyckParser_eof_doc}, 
    274229    {NULL}  /* Sentinel */ 
    275230}; 
     
    278233PySyckParser_dealloc(PySyckParserObject *parser) 
    279234{ 
    280     Py_XDECREF(parser->source); 
    281     if (parser->syck) { 
    282         syck_free_parser(parser->syck); 
    283     } 
     235    PySyckParser_free(parser); 
    284236    PyObject_Del(parser); 
    285237} 
     
    391343 
    392344    if (parser->error) 
    393         return 0; 
     345        return -1; 
    394346 
    395347    switch (node->kind) { 
     
    406358            for (k = 0; k < node->data.list->idx; k++) { 
    407359                index = syck_seq_read(node, k); 
    408                 item = PyList_GetItem(parser->symbols, index-1); 
     360                item = PyList_GetItem(parser->symbols, index); 
    409361                if (!item) goto error; 
    410362                Py_INCREF(item); 
     
    419371            { 
    420372                index = syck_map_read(node, map_key, k); 
    421                 key = PyList_GetItem(parser->symbols, index-1); 
     373                key = PyList_GetItem(parser->symbols, index); 
    422374                if (!key) goto error; 
    423375                index = syck_map_read(node, map_value, k); 
    424                 value = PyList_GetItem(parser->symbols, index-1); 
     376                value = PyList_GetItem(parser->symbols, index); 
    425377                if (!value) goto error; 
    426378                if (PyDict_SetItem(object, key, value) < 0) 
     
    433385    if (!object) goto error; 
    434386 
     387    if (parser->resolver) { 
     388        value = PyObject_CallFunction(parser->resolver, "(O)", object); 
     389        if (!value) goto error; 
     390        Py_DECREF(object); 
     391        object = value; 
     392    } 
     393 
    435394    if (PyList_Append(parser->symbols, object) < 0) 
    436395        goto error; 
    437396 
    438     index = PyList_Size(parser->symbols); 
     397    index = PyList_Size(parser->symbols)-1; 
    439398    return index; 
    440399 
     
    442401    Py_XDECREF(object); 
    443402    parser->error = 1; 
    444     return 0; 
     403    return -1; 
    445404} 
    446405 
     
    466425    PySyckParserObject *parser; 
    467426    PyObject *source; 
     427    PyObject *resolver = NULL; 
    468428    int implicit_typing = 1; 
    469429    int taguri_expansion = 1; 
    470430 
    471     static char *kwdlist[] = {"source", "implicit_typing", "taguri_expansion", NULL}; 
    472  
    473     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|ii", kwdlist, 
    474                 &source, &implicit_typing, &taguri_expansion)) 
     431    static char *kwdlist[] = {"source", "resolver", "implicit_typing", "taguri_expansion", NULL}; 
     432 
     433    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|Oii", kwdlist, 
     434                &source, &resolver, &implicit_typing, &taguri_expansion)) 
    475435        return NULL; 
    476436 
     
    479439        return NULL; 
    480440 
     441    parser->error = 0; 
     442    parser->symbols = NULL; 
     443 
    481444    Py_INCREF(source); 
    482445    parser->source = source; 
    483     parser->error = 0; 
     446 
     447    if (resolver == Py_None) 
     448        resolver = NULL; 
     449    Py_XINCREF(resolver); 
     450    parser->resolver = resolver; 
    484451 
    485452    parser->syck = syck_new_parser(); 
     
    498465    syck_parser_error_handler(parser->syck, PySyckParser_error_handler); 
    499466    /* 
    500     syck_parser_bad_anchor_handler(parser, _syck_Parser_bad_anchor_handler); 
     467    syck_parser_bad_anchor_handler(parser, PySyckParser_bad_anchor_handler); 
    501468    */ 
    502469 
  • trunk/tests/test_syck.py

    r4 r6  
    163163        parser = _syck.Parser(EXAMPLE) 
    164164        self.assertEqual(type(parser), _syck.ParserType) 
    165         parser.close() 
    166165 
    167166    def testNodeType(self): 
     
    169168        document = parser.parse() 
    170169        self.assertEqual(type(document), _syck.NodeType) 
    171         parser.close() 
    172170 
    173171    def testNodeType2(self): 
     
    179177        parser = _syck.Parser(INVALID[0]) 
    180178        self.assertRaises(_syck.error, (lambda: parser.parse())) 
    181         parser.close() 
    182179 
    183180    def testErrorLocation(self): 
     
    191188            self.assertEqual(e.args[2], column) 
    192189 
    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() 
     190class EqualStructure: 
    229191 
    230192    def assertEqualStructure(self, node, structure): 
     
    244206                self.assertEqualStructure(node.value[key], structure[key.value]) 
    245207 
     208class TestValuesAndSources(unittest.TestCase, EqualStructure): 
     209 
     210    def testValues1(self): 
     211        self._testValues(COMPARE1) 
     212 
     213    def testValues2(self): 
     214        self._testValues(COMPARE2) 
     215 
     216    def testValues3(self): 
     217        self._testValues(COMPARE3) 
     218 
     219    def testFileValues1(self): 
     220        self._testFileValues(COMPARE1) 
     221 
     222    def testFileValues2(self): 
     223        self._testFileValues(COMPARE2) 
     224 
     225    def testFileValues3(self): 
     226        self._testFileValues(COMPARE3) 
     227 
     228    def testNonsense(self): 
     229        parser = _syck.Parser(None) 
     230        self.assertRaises(AttributeError, (lambda: parser.parse())) 
     231 
     232    def _testValues(self, (source, structure)): 
     233        parser = _syck.Parser(source) 
     234        document = parser.parse() 
     235        self.assertEqualStructure(document, structure) 
     236 
     237    def _testFileValues(self, (source, structure)): 
     238        parser = _syck.Parser(StringIO.StringIO(source)) 
     239        document = parser.parse() 
     240        self.assertEqualStructure(document, structure) 
     241 
     242class TestResolver(unittest.TestCase, EqualStructure): 
     243 
     244    object = 12345 
     245 
     246    def object_resolver(self, node): 
     247        return self.object 
     248 
     249    def simple_resolver(self, node): 
     250        return node.value 
     251 
     252    def default_resolver(self, node): 
     253        return node 
     254 
     255    def call_me_not_resolver(self, node): 
     256        self.call_me_not_parser.parse() 
     257        return node 
     258 
     259    def testResolver1(self): 
     260        self._testResolver(COMPARE1) 
     261 
     262    def testResolver2(self): 
     263        self._testResolver(COMPARE2) 
     264 
     265    def testResolver3(self): 
     266        self._testResolver(COMPARE3) 
     267 
     268    def testCallMeNot(self): 
     269        self.call_me_not_parser = _syck.Parser(EXAMPLE, self.call_me_not_resolver) 
     270        self.assertRaises(RuntimeError, (lambda: self.call_me_not_parser.parse())) 
     271        del self.call_me_not_parser 
     272 
     273    def _testResolver(self, compare): 
     274        self._testObject(compare) 
     275        self._testSimple(compare) 
     276        self._testDefault(compare) 
     277        self._testNone(compare) 
     278 
     279    def _testObject(self, (source, structure)): 
     280        parser = _syck.Parser(source, self.object_resolver) 
     281        document = parser.parse() 
     282        self.assert_(document is self.object) 
     283 
     284    def _testSimple(self, (source, structure)): 
     285        parser = _syck.Parser(source, self.simple_resolver) 
     286        document = parser.parse() 
     287        self.assert_(document, structure) 
     288 
     289    def _testDefault(self, (source, structure)): 
     290        parser = _syck.Parser(source, resolver=self.default_resolver) 
     291        document = parser.parse() 
     292        self.assertEqualStructure(document, structure) 
     293 
     294    def _testNone(self, (source, structure)): 
     295        parser = _syck.Parser(source, resolver=None) 
     296        document = parser.parse() 
     297        self.assertEqualStructure(document, structure) 
     298 
    246299class TestDocuments(unittest.TestCase): 
    247300 
     
    260313    def _testDocuments(self, source, length): 
    261314        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): 
     315        actual_length = 0 
     316        while True: 
    267317            document = parser.parse() 
    268             self.assert_(document) 
     318            if parser.eof(): 
     319                self.assertEqual(document, None) 
     320                break 
     321            actual_length += 1 
     322        self.assertEqual(actual_length, length) 
    269323        self.assertEqual(parser.parse(), None) 
    270         parser.close() 
     324        self.assert_(parser.eof()) 
     325        self.assertEqual(parser.parse(), None) 
     326        self.assert_(parser.eof()) 
    271327 
    272328class TestImplicitTyping(unittest.TestCase): 
     
    285341 
    286342    def _testTyping(self, implicit_typing, taguri_expansion): 
    287         parser = _syck.Parser(IMPLICIT_TYPING[0], implicit_typing, taguri_expansion) 
     343        parser = _syck.Parser(IMPLICIT_TYPING[0], None, implicit_typing, taguri_expansion) 
    288344        for node, (type_id, explicit) in zip(parser.parse().value, IMPLICIT_TYPING[1]): 
    289345            if type_id is not None and taguri_expansion: 
Note: See TracChangeset for help on using the changeset viewer.