Changeset 15


Ignore:
Timestamp:
07/28/05 19:40:56 (9 years ago)
Author:
xi
Message:

_syck.Parser works again.

Location:
trunk
Files:
2 edited
2 moved

Legend:

Unmodified
Added
Removed
  • trunk/ext/_syckmodule.c

    r14 r15  
    4242 
    4343PyDoc_STRVAR(PySyckNode_doc, 
    44     "The base Node type\n\n" 
     44    "_syck.Node() -> TypeError\n\n" 
    4545    "_syck.Node is an abstract type. It is a base type for _syck.Scalar,\n" 
    4646    "_syck.Seq, and _syck.Map. You cannot create an instance of _syck.Node\n" 
    47     "directly. You may use _syck.Node for type checking.\n"); 
     47    "directly. You may use _syck.Node for type checking or subclassing.\n"); 
    4848 
    4949typedef struct { 
     
    220220    "      -> a Scalar node\n\n" 
    221221    "_syck.Scalar represents a scalar node in Syck parser and emitter\n" 
    222     "graphs. A scalar node points to a single string value.\n\n" 
    223     "Attributes:\n\n" 
    224     "kind -- always 'scalar'; read-only\n" 
    225     "value -- the node value, a string\n" 
    226     "tag -- the node tag; a string or None\n" 
    227     "anchor -- the name of the node anchor or None; read-only\n" 
    228     "style -- the node style; None (means literal or plain),\n" 
    229     "         '1quote', '2quote', 'fold', 'literal', 'plain'\n" 
    230     "indent -- indentation, an integer; 0 means default\n" 
    231     "width -- the preferred width; 0 means default\n" 
    232     "chomp -- None (clip), '-' (strip), or '+' (keep)\n"); 
     222    "graphs. A scalar node points to a single string value.\n"); 
    233223 
    234224typedef struct { 
     
    489479static PyGetSetDef PySyckScalar_getsetters[] = { 
    490480    {"kind", (getter)PySyckNode_getkind, NULL, 
    491         "the node kind", &PySyck_ScalarKind}, 
     481        PyDoc_STR("the node kind, always 'scalar', read-only"), 
     482        &PySyck_ScalarKind}, 
    492483    {"value", (getter)PySyckNode_getvalue, (setter)PySyckScalar_setvalue, 
    493         "the node value", NULL}, 
     484        PyDoc_STR("the node value, a string"), NULL}, 
    494485    {"tag", (getter)PySyckNode_gettag, (setter)PySyckNode_settag, 
    495         "the node tag", NULL}, 
     486        PyDoc_STR("the node tag, a string or None"), NULL}, 
    496487    {"anchor", (getter)PySyckNode_getanchor, (setter)PySyckNode_setanchor, 
    497         "the node anchor", NULL}, 
     488        PyDoc_STR("the node anchor, a string or None"), NULL}, 
    498489    {"style", (getter)PySyckScalar_getstyle, (setter)PySyckScalar_setstyle, 
    499         "the node style", NULL}, 
     490        PyDoc_STR("the node style, values: None (means literal or plain),\n" 
     491            "'1quote', '2quote', 'fold', 'literal', 'plain'"), NULL}, 
    500492    {"indent", (getter)PySyckScalar_getindent, (setter)PySyckScalar_setindent, 
    501         "the field indentation", NULL}, 
     493        PyDoc_STR("the node indentation, an integer"), NULL}, 
    502494    {"width", (getter)PySyckScalar_getwidth, (setter)PySyckScalar_setwidth, 
    503         "the field width", NULL}, 
     495        PyDoc_STR("the node width, an integer"), NULL}, 
    504496    {"chomp", (getter)PySyckScalar_getchomp, (setter)PySyckScalar_setchomp, 
    505         "the chomping method", NULL}, 
     497        PyDoc_STR("the chomping method,\n" 
     498            "values: None (clip), '-' (strip), or '+' (keep)"), NULL}, 
    506499    {NULL}  /* Sentinel */ 
    507500}; 
     
    556549    "Seq(value=[], tag=None, inline=False) -> a Seq node\n\n" 
    557550    "_syck.Seq represents a sequence node in Syck parser and emitter\n" 
    558     "graphs. A sequence node points to an ordered set of subnodes.\n\n" 
    559     "Attributes:\n\n" 
    560     "kind -- always 'seq'; read-only\n" 
    561     "value -- the node value, a list\n" 
    562     "tag -- the node tag; a string or None\n" 
    563     "anchor -- the name of the node anchor or None; read-only\n" 
    564     "inline -- is the node inline? False or True\n"); 
     551    "graphs. A sequence node points to an ordered set of subnodes.\n"); 
    565552 
    566553typedef struct { 
     
    672659static PyGetSetDef PySyckSeq_getsetters[] = { 
    673660    {"kind", (getter)PySyckNode_getkind, NULL, 
    674         "the node kind", &PySyck_SeqKind}, 
     661        PyDoc_STR("the node kind, always 'seq', read-only"), &PySyck_SeqKind}, 
    675662    {"value", (getter)PySyckNode_getvalue, (setter)PySyckSeq_setvalue, 
    676         "the node value", NULL}, 
     663        PyDoc_STR("the node value, a sequence"), NULL}, 
    677664    {"tag", (getter)PySyckNode_gettag, (setter)PySyckNode_settag, 
    678         "the node tag", NULL}, 
     665        PyDoc_STR("the node tag, a string or None"), NULL}, 
    679666    {"anchor", (getter)PySyckNode_getanchor, (setter)PySyckNode_setanchor, 
    680         "the node anchor", NULL}, 
     667        PyDoc_STR("the node anchor, a string or None"), NULL}, 
    681668    {"inline", (getter)PySyckSeq_getinline, (setter)PySyckSeq_setinline, 
    682         "the node style", NULL}, 
     669        PyDoc_STR("the block/flow flag"), NULL}, 
    683670    {NULL}  /* Sentinel */ 
    684671}; 
     
    733720    "Map(value='', tag=None, inline=False) -> a Map node\n\n" 
    734721    "_syck.Map represents a mapping node in Syck parser and emitter\n" 
    735     "graphs. A mapping node points to an unordered collections of pairs.\n\n" 
    736     "Attributes:\n\n" 
    737     "kind -- always 'map'; read-only\n" 
    738     "value -- the node value, a dictionary\n" 
    739     "tag -- the node tag; a string or None\n" 
    740     "anchor -- the name of the node anchor or None; read-only\n" 
    741     "inline -- is the node inline? False or True\n"); 
     722    "graphs. A mapping node points to an unordered collections of pairs.\n"); 
    742723 
    743724typedef struct { 
     
    849830static PyGetSetDef PySyckMap_getsetters[] = { 
    850831    {"kind", (getter)PySyckNode_getkind, NULL, 
    851         "the node kind", &PySyck_MapKind}, 
     832        PyDoc_STR("the node kind, always 'map', read-only"), &PySyck_MapKind}, 
    852833    {"value", (getter)PySyckNode_getvalue, (setter)PySyckMap_setvalue, 
    853         "the node value", NULL}, 
     834        PyDoc_STR("the node value, a mapping"), NULL}, 
    854835    {"tag", (getter)PySyckNode_gettag, (setter)PySyckNode_settag, 
    855         "the node tag", NULL}, 
     836        PyDoc_STR("the node tag, a string or None"), NULL}, 
    856837    {"anchor", (getter)PySyckNode_getanchor, (setter)PySyckNode_setanchor, 
    857         "the node anchor", NULL}, 
     838        PyDoc_STR("the node anchor, a string or None"), NULL}, 
    858839    {"inline", (getter)PySyckMap_getinline, (setter)PySyckMap_setinline, 
    859         "the node style", NULL}, 
     840        PyDoc_STR("the block/flow flag"), NULL}, 
    860841    {NULL}  /* Sentinel */ 
    861842}; 
     
    903884}; 
    904885 
    905  
    906 /* 
     886/**************************************************************************** 
     887 * The type _syck.Parser. 
     888 ****************************************************************************/ 
     889 
     890PyDoc_STRVAR(PySyckParser_doc, 
     891    "Parser(source, implicit_typing=True, taguri_expansion=True)\n" 
     892    "      -> a Parser object\n\n" 
     893    "_syck.Parser is a low-lever wrapper of the Syck parser. It parses\n" 
     894    "a YAML stream and produces a graph of Nodes.\n"); 
     895 
    907896typedef struct { 
    908897    PyObject_HEAD 
    909     PyObject *kind; 
    910     PyObject *type_id; 
    911     PyObject *value; 
    912 } PySyckNodeObject; 
     898    /* Attributes: */ 
     899    PyObject *source;       /* a string or file-like object */ 
     900    int implicit_typing; 
     901    int taguri_expansion; 
     902    /* Internal fields: */ 
     903    PyObject *symbols;      /* symbol table, a list, NULL outside parse() */ 
     904    SyckParser *parser; 
     905    int parsing; 
     906    int halt; 
     907} PySyckParserObject; 
     908 
     909static PyObject * 
     910PySyckParser_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 
     911{ 
     912    PySyckParserObject *self; 
     913 
     914    self = (PySyckParserObject *)type->tp_alloc(type, 0); 
     915    if (!self) return NULL; 
     916 
     917    self->source = NULL; 
     918    self->implicit_typing = 0; 
     919    self->taguri_expansion = 0; 
     920    self->symbols = NULL; 
     921    self->parser = NULL; 
     922    self->parsing = 0; 
     923    self->halt = 1; 
     924 
     925    /* 
     926    self->symbols = PyList_New(0); 
     927    if (!self->symbols) { 
     928        Py_DECREF(self); 
     929        return NULL; 
     930    } 
     931    */ 
     932 
     933    return (PyObject *)self; 
     934} 
     935 
     936static int 
     937PySyckParser_clear(PySyckParserObject *self) 
     938{ 
     939    PyObject *tmp; 
     940 
     941    if (self->parser) { 
     942        syck_free_parser(self->parser); 
     943        self->parser = NULL; 
     944    } 
     945 
     946    tmp = self->source; 
     947    self->source = NULL; 
     948    Py_XDECREF(tmp); 
     949 
     950    tmp = self->symbols; 
     951    self->symbols = NULL; 
     952    Py_XDECREF(tmp); 
     953 
     954    return 0; 
     955} 
     956 
     957static int 
     958PySyckParser_traverse(PySyckParserObject *self, visitproc visit, void *arg) 
     959{ 
     960    int ret; 
     961 
     962    if (self->source) 
     963        if ((ret = visit(self->source, arg)) != 0) 
     964            return ret; 
     965 
     966    if (self->symbols) 
     967        if ((ret = visit(self->symbols, arg)) != 0) 
     968            return ret; 
     969 
     970    return 0; 
     971} 
    913972 
    914973static void 
    915 PySyckNode_dealloc(PySyckNodeObject *self) 
    916 { 
    917     Py_XDECREF(self->kind); 
    918     Py_XDECREF(self->type_id); 
    919     Py_XDECREF(self->value); 
    920     PyObject_Del(self); 
    921 } 
    922  
    923 static PyObject * 
    924 PySyckNode_getattr(PySyckNodeObject *self, char *name) 
    925 { 
    926     PyObject *value; 
    927  
    928     if (strcmp(name, "kind") == 0) 
    929         value = self->kind; 
    930     else if (strcmp(name, "type_id") == 0) 
    931         value = self->type_id; 
    932     else if (strcmp(name, "value") == 0) 
    933         value = self->value; 
    934     else { 
    935         PyErr_SetString(PyExc_AttributeError, name); 
    936         return NULL; 
    937     } 
     974PySyckParser_dealloc(PySyckParserObject *self) 
     975{ 
     976    PySyckParser_clear(self); 
     977    self->ob_type->tp_free((PyObject *)self); 
     978} 
     979 
     980static PyObject * 
     981PySyckParser_getsource(PySyckParserObject *self, void *closure) 
     982{ 
     983    PyObject *value = self->source ? self->source : Py_None; 
    938984 
    939985    Py_INCREF(value); 
     
    941987} 
    942988 
    943  
    944 */ 
     989static PyObject * 
     990PySyckParser_getimplicit_typing(PySyckParserObject *self, void *closure) 
     991{ 
     992    PyObject *value = self->implicit_typing ? Py_True : Py_False; 
     993 
     994    Py_INCREF(value); 
     995    return value; 
     996} 
     997 
     998static PyObject * 
     999PySyckParser_gettaguri_expansion(PySyckParserObject *self, void *closure) 
     1000{ 
     1001    PyObject *value = self->taguri_expansion ? Py_True : Py_False; 
     1002 
     1003    Py_INCREF(value); 
     1004    return value; 
     1005} 
     1006 
     1007static PyObject * 
     1008PySyckParser_geteof(PySyckParserObject *self, void *closure) 
     1009{ 
     1010    PyObject *value = self->halt ? Py_True : Py_False; 
     1011 
     1012    Py_INCREF(value); 
     1013    return value; 
     1014} 
     1015 
     1016static PyGetSetDef PySyckParser_getsetters[] = { 
     1017    {"source", (getter)PySyckParser_getsource, NULL, 
     1018        PyDoc_STR("IO source, a string or file-like object"), NULL}, 
     1019    {"implicit_typing", (getter)PySyckParser_getimplicit_typing, NULL, 
     1020        PyDoc_STR("implicit typing of builtin YAML types"), NULL}, 
     1021    {"taguri_expansion", (getter)PySyckParser_gettaguri_expansion, NULL, 
     1022        PyDoc_STR("expansion of types in full taguri"), NULL}, 
     1023    {"eof", (getter)PySyckParser_geteof, NULL, 
     1024        PyDoc_STR("EOF flag"), NULL}, 
     1025    {NULL}  /* Sentinel */ 
     1026}; 
     1027 
     1028static SYMID 
     1029PySyckParser_node_handler(SyckParser *parser, SyckNode *node) 
     1030{ 
     1031    PySyckParserObject *self = (PySyckParserObject *)parser->bonus; 
     1032 
     1033    SYMID index; 
     1034    PySyckNodeObject *object = NULL; 
     1035 
     1036    PyObject *key, *value; 
     1037    int k; 
     1038 
     1039    if (self->halt) 
     1040        return -1; 
     1041 
     1042    switch (node->kind) { 
     1043 
     1044        case syck_str_kind: 
     1045            object = (PySyckNodeObject *) 
     1046                PySyckScalar_new(&PySyckScalar_Type, NULL, NULL); 
     1047            if (!object) goto error; 
     1048            value = PyString_FromStringAndSize(node->data.str->ptr, 
     1049                    node->data.str->len); 
     1050            if (!value) goto error; 
     1051            Py_DECREF(object->value); 
     1052            object->value = value; 
     1053            break; 
     1054 
     1055        case syck_seq_kind: 
     1056            object = (PySyckNodeObject *) 
     1057                PySyckSeq_new(&PySyckSeq_Type, NULL, NULL); 
     1058            if (!object) goto error; 
     1059            for (k = 0; k < node->data.list->idx; k++) { 
     1060                index = syck_seq_read(node, k); 
     1061                value = PyList_GetItem(self->symbols, index); 
     1062                if (!value) goto error; 
     1063                if (PyList_Append(object->value, value) < 0) 
     1064                    goto error; 
     1065            } 
     1066            break; 
     1067 
     1068        case syck_map_kind: 
     1069            object = (PySyckNodeObject *) 
     1070                PySyckMap_new(&PySyckMap_Type, NULL, NULL); 
     1071            if (!object) goto error; 
     1072            for (k = 0; k < node->data.pairs->idx; k++) 
     1073            { 
     1074                index = syck_map_read(node, map_key, k); 
     1075                key = PyList_GetItem(self->symbols, index); 
     1076                if (!key) goto error; 
     1077                index = syck_map_read(node, map_value, k); 
     1078                value = PyList_GetItem(self->symbols, index); 
     1079                if (!value) goto error; 
     1080                if (PyDict_SetItem(object->value, key, value) < 0) 
     1081                    goto error; 
     1082            } 
     1083            break; 
     1084    } 
     1085 
     1086    if (node->type_id) { 
     1087        object->tag = PyString_FromString(node->type_id); 
     1088        if (!object->tag) goto error; 
     1089    } 
     1090 
     1091    if (node->anchor) { 
     1092        object->anchor = PyString_FromString(node->anchor); 
     1093        if (!object->anchor) goto error; 
     1094    } 
     1095 
     1096    if (PyList_Append(self->symbols, (PyObject *)object) < 0) 
     1097        goto error; 
     1098 
     1099    index = PyList_GET_SIZE(self->symbols)-1; 
     1100    return index; 
     1101 
     1102error: 
     1103    Py_XDECREF(object); 
     1104    self->halt = 1; 
     1105    return -1; 
     1106} 
     1107 
     1108static void 
     1109PySyckParser_error_handler(SyckParser *parser, char *str) 
     1110{ 
     1111    PySyckParserObject *self = (PySyckParserObject *)parser->bonus; 
     1112    PyObject *value; 
     1113 
     1114    if (self->halt) return; 
     1115 
     1116    self->halt = 1; 
     1117 
     1118    value = Py_BuildValue("(sii)", str, 
     1119            parser->linect, parser->cursor - parser->lineptr); 
     1120    if (value) { 
     1121        PyErr_SetObject(PySyck_Error, value); 
     1122    } 
     1123} 
     1124 
     1125static long 
     1126PySyckParser_read_handler(char *buf, SyckIoFile *file, long max_size, long skip) 
     1127{ 
     1128    PySyckParserObject *self = (PySyckParserObject *)file->ptr; 
     1129 
     1130    PyObject *value; 
     1131 
     1132    char *str; 
     1133    int length; 
     1134 
     1135    buf[skip] = '\0'; 
     1136 
     1137    if (self->halt) { 
     1138        return skip; 
     1139    } 
     1140     
     1141    max_size -= skip; 
     1142 
     1143    value = PyObject_CallMethod(self->source, "read", "(i)", max_size); 
     1144    if (!value) { 
     1145        self->halt = 1; 
     1146        return skip; 
     1147    } 
     1148 
     1149    if (!PyString_CheckExact(value)) { 
     1150        Py_DECREF(value); 
     1151        PyErr_SetString(PyExc_TypeError, "file-like object should return a string"); 
     1152        self->halt = 1; 
     1153         
     1154        return skip; 
     1155    } 
     1156 
     1157    str = PyString_AS_STRING(value); 
     1158    length = PyString_GET_SIZE(value); 
     1159    if (!length) { 
     1160        Py_DECREF(value); 
     1161        return skip; 
     1162    } 
     1163 
     1164    if (length > max_size) { 
     1165        Py_DECREF(value); 
     1166        PyErr_SetString(PyExc_ValueError, "read returns an overly long string"); 
     1167        self->halt = 1; 
     1168        return skip; 
     1169    } 
     1170 
     1171    memcpy(buf+skip, str, length); 
     1172    length += skip; 
     1173    buf[length] = '\0'; 
     1174 
     1175    Py_DECREF(value); 
     1176 
     1177    return length; 
     1178} 
     1179 
     1180static int 
     1181PySyckParser_init(PySyckParserObject *self, PyObject *args, PyObject *kwds) 
     1182{ 
     1183    PyObject *source = NULL; 
     1184    int implicit_typing = 1; 
     1185    int taguri_expansion = 1; 
     1186 
     1187    static char *kwdlist[] = {"source", "implicit_typing", "taguri_expansion", 
     1188        NULL}; 
     1189 
     1190    PySyckParser_clear(self); 
     1191 
     1192    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|ii", kwdlist, 
     1193                &source, &implicit_typing, &taguri_expansion)) 
     1194        return -1; 
     1195 
     1196    Py_INCREF(source); 
     1197    self->source = source; 
     1198 
     1199    self->implicit_typing = implicit_typing; 
     1200    self->taguri_expansion = taguri_expansion; 
     1201 
     1202    self->parser = syck_new_parser(); 
     1203    self->parser->bonus = self; 
     1204 
     1205    if (PyString_CheckExact(self->source)) { 
     1206        syck_parser_str(self->parser, 
     1207                PyString_AS_STRING(self->source), 
     1208                PyString_GET_SIZE(self->source), NULL); 
     1209    } 
     1210    /* 
     1211    else if (PyUnicode_CheckExact(self->source)) { 
     1212        syck_parser_str(self->parser, 
     1213                PyUnicode_AS_DATA(self->source), 
     1214                PyString_GET_DATA_SIZE(self->source), NULL); 
     1215    } 
     1216    */ 
     1217    else { 
     1218        syck_parser_file(self->parser, (FILE *)self, PySyckParser_read_handler); 
     1219    } 
     1220 
     1221    syck_parser_implicit_typing(self->parser, self->implicit_typing); 
     1222    syck_parser_taguri_expansion(self->parser, self->taguri_expansion); 
     1223 
     1224    syck_parser_handler(self->parser, PySyckParser_node_handler); 
     1225    syck_parser_error_handler(self->parser, PySyckParser_error_handler); 
     1226    /* 
     1227    syck_parser_bad_anchor_handler(parser, PySyckParser_bad_anchor_handler); 
     1228    */ 
     1229 
     1230    self->parsing = 0; 
     1231    self->halt = 0; 
     1232 
     1233    return 0; 
     1234} 
     1235 
     1236static PyObject * 
     1237PySyckParser_parse(PySyckParserObject *self) 
     1238{ 
     1239    SYMID index; 
     1240    PyObject *value; 
     1241 
     1242    if (self->parsing) { 
     1243        PyErr_SetString(PyExc_RuntimeError, "do not call Parser.parse while it is already parsing"); 
     1244        return NULL; 
     1245    } 
     1246 
     1247    if (self->halt) { 
     1248        Py_INCREF(Py_None); 
     1249        return Py_None; 
     1250    } 
     1251 
     1252    self->symbols = PyList_New(0); 
     1253    if (!self->symbols) { 
     1254        return NULL; 
     1255    } 
     1256 
     1257    self->parsing = 1; 
     1258    index = syck_parse(self->parser); 
     1259    self->parsing = 0; 
     1260 
     1261    if (self->halt || self->parser->eof) { 
     1262        Py_DECREF(self->symbols); 
     1263        self->symbols = NULL; 
     1264 
     1265        if (self->halt) return NULL; 
     1266 
     1267        self->halt = 1; 
     1268        Py_INCREF(Py_None); 
     1269        return Py_None; 
     1270    } 
     1271 
     1272    value = PyList_GetItem(self->symbols, index); 
     1273 
     1274    Py_DECREF(self->symbols); 
     1275    self->symbols = NULL; 
     1276 
     1277    return value; 
     1278} 
     1279 
     1280PyDoc_STRVAR(PySyckParser_parse_doc, 
     1281    "parse() -> the root Node object\n\n" 
     1282    "Parses the source and returns the next document. On EOF, returns None\n" 
     1283    "and sets the 'eof' attribute on.\n"); 
     1284 
     1285static PyMethodDef PySyckParser_methods[] = { 
     1286    {"parse",  (PyCFunction)PySyckParser_parse, 
     1287        METH_NOARGS, PySyckParser_parse_doc}, 
     1288    {NULL}  /* Sentinel */ 
     1289}; 
     1290 
     1291static PyTypeObject PySyckParser_Type = { 
     1292    PyObject_HEAD_INIT(NULL) 
     1293    0,                                          /* ob_size */ 
     1294    "_syck.Parser",                             /* tp_name */ 
     1295    sizeof(PySyckParserObject),                 /* tp_basicsize */ 
     1296    0,                                          /* tp_itemsize */ 
     1297    (destructor)PySyckParser_dealloc,           /* tp_dealloc */ 
     1298    0,                                          /* tp_print */ 
     1299    0,                                          /* tp_getattr */ 
     1300    0,                                          /* tp_setattr */ 
     1301    0,                                          /* tp_compare */ 
     1302    0,                                          /* tp_repr */ 
     1303    0,                                          /* tp_as_number */ 
     1304    0,                                          /* tp_as_sequence */ 
     1305    0,                                          /* tp_as_mapping */ 
     1306    0,                                          /* tp_hash */ 
     1307    0,                                          /* tp_call */ 
     1308    0,                                          /* tp_str */ 
     1309    0,                                          /* tp_getattro */ 
     1310    0,                                          /* tp_setattro */ 
     1311    0,                                          /* tp_as_buffer */ 
     1312    Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC,  /* tp_flags */ 
     1313    PySyckParser_doc,                           /* tp_doc */ 
     1314    (traverseproc)PySyckParser_traverse,        /* tp_traverse */ 
     1315    (inquiry)PySyckParser_clear,                /* tp_clear */ 
     1316    0,                                          /* tp_richcompare */ 
     1317    0,                                          /* tp_weaklistoffset */ 
     1318    0,                                          /* tp_iter */ 
     1319    0,                                          /* tp_iternext */ 
     1320    PySyckParser_methods,                       /* tp_methods */ 
     1321    0,                                          /* tp_members */ 
     1322    PySyckParser_getsetters,                    /* tp_getset */ 
     1323    0,                                          /* tp_base */ 
     1324    0,                                          /* tp_dict */ 
     1325    0,                                          /* tp_descr_get */ 
     1326    0,                                          /* tp_descr_set */ 
     1327    0,                                          /* tp_dictoffset */ 
     1328    (initproc)PySyckParser_init,                /* tp_init */ 
     1329    0,                                          /* tp_alloc */ 
     1330    PySyckParser_new,                           /* tp_new */ 
     1331}; 
     1332 
     1333 
     1334 
    9451335#if 0 
    9461336     
    947 static PyTypeObject PySyckNode_Type = { 
    948     PyObject_HEAD_INIT(NULL) 
    949     0,                                  /* ob_size */ 
    950     "_syck.Node",                       /* tp_name */ 
    951     sizeof(PySyckNodeObject),           /* tp_basicsize */ 
    952     0,                                  /* tp_itemsize */ 
    953     (destructor)PySyckNode_dealloc,     /* tp_dealloc */ 
    954     0,                                  /* tp_print */ 
    955     (getattrfunc)PySyckNode_getattr,    /* tp_getattr */ 
    956     0,                                  /* tp_setattr */ 
    957     0,                                  /* tp_compare */ 
    958     0,                                  /* tp_repr */ 
    959     0,                                  /* tp_as_number */ 
    960     0,                                  /* tp_as_sequence */ 
    961     0,                                  /* tp_as_mapping */ 
    962     0,                                  /* tp_hash */ 
    963     0,                                  /* tp_call */ 
    964     0,                                  /* tp_str */ 
    965     0,                                  /* tp_getattro */ 
    966     0,                                  /* tp_setattro */ 
    967     0,                                  /* tp_as_buffer */ 
    968     Py_TPFLAGS_DEFAULT,                 /* tp_flags */ 
    969     PySyckNode_doc,                     /* tp_doc */ 
    970 }; 
    9711337 
    9721338static PyObject * 
     
    10071373    return (PyObject *)self; 
    10081374} 
    1009  
    1010 static PyObject * 
    1011 PySyck_Node(PyObject *self, PyObject *args) 
    1012 { 
    1013     if (!PyArg_ParseTuple(args, ":_syck.Node")) 
    1014         return NULL; 
    1015  
    1016     PyErr_SetString(PyExc_TypeError, "Node object cannot be created explicitly. Use _syck.Parser.parse() instead."); 
    1017     return NULL; 
    1018 } 
    1019  
    1020 static char PySyck_Node_doc[] = 
    1021     "Node object cannot be created explicitly. Use _syck.Parser.parse() instead."; 
    1022  
    1023  
    1024 */ 
    10251375 
    10261376/* Parser type. */ 
     
    11661516}; 
    11671517 
    1168 static long 
    1169 PySyckParser_read_handler(char *buf, SyckIoFile *file, long max_size, long skip) 
    1170 { 
    1171     PySyckParserObject *parser = (PySyckParserObject *)file->ptr; 
    1172  
    1173     PyObject *value; 
    1174  
    1175     char *str; 
    1176     int length; 
    1177  
    1178     buf[skip] = '\0'; 
    1179  
    1180     if (parser->error) { 
    1181         return skip; 
    1182     } 
    1183      
    1184     max_size -= skip; 
    1185  
    1186     value = PyObject_CallMethod(parser->source, "read", "(i)", max_size); 
    1187     if (!value) { 
    1188         parser->error = 1; 
    1189         return skip; 
    1190     } 
    1191  
    1192     if (!PyString_Check(value)) { 
    1193         Py_DECREF(value); 
    1194         PyErr_SetString(PyExc_TypeError, "file-like object should return a string"); 
    1195         parser->error = 1; 
    1196          
    1197         return skip; 
    1198     } 
    1199  
    1200     str = PyString_AS_STRING(value); 
    1201     length = PyString_GET_SIZE(value); 
    1202     if (!length) { 
    1203         Py_DECREF(value); 
    1204         return skip; 
    1205     } 
    1206  
    1207     if (length > max_size) { 
    1208         Py_DECREF(value); 
    1209         PyErr_SetString(PyExc_ValueError, "read returns an overly long string"); 
    1210         parser->error = 1; 
    1211         return skip; 
    1212     } 
    1213  
    1214     memcpy(buf+skip, str, length); 
    1215     length += skip; 
    1216     buf[length] = '\0'; 
    1217  
    1218     Py_DECREF(value); 
    1219  
    1220     return length; 
    1221 } 
    12221518 
    12231519static SYMID 
     
    12941590} 
    12951591 
    1296 static void 
    1297 PySyckParser_error_handler(SyckParser *syck, char *str) 
    1298 { 
    1299     PySyckParserObject *parser = (PySyckParserObject *)syck->bonus; 
    1300     PyObject *value; 
    1301  
    1302     if (parser->error) return; 
    1303  
    1304     parser->error = 1; 
    1305  
    1306     value = Py_BuildValue("(sii)", str, syck->linect, syck->cursor-syck->lineptr); 
    1307     if (value) { 
    1308         PyErr_SetObject(PySyck_Error, value); 
    1309     } 
    1310 } 
    1311  
    1312 static PyObject * 
    1313 PySyck_Parser(PyObject *self, PyObject *args, PyObject *kwds) 
    1314 { 
    1315     PySyckParserObject *parser; 
    1316     PyObject *source; 
    1317     PyObject *resolver = NULL; 
    1318     int implicit_typing = 1; 
    1319     int taguri_expansion = 1; 
    1320  
    1321     static char *kwdlist[] = {"source", "resolver", "implicit_typing", "taguri_expansion", NULL}; 
    1322  
    1323     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|Oii", kwdlist, 
    1324                 &source, &resolver, &implicit_typing, &taguri_expansion)) 
    1325         return NULL; 
    1326  
    1327     parser = PyObject_NEW(PySyckParserObject, &PySyckParser_Type); 
    1328     if (!parser) 
    1329         return NULL; 
    1330  
    1331     parser->error = 0; 
    1332     parser->symbols = NULL; 
    1333  
    1334     Py_INCREF(source); 
    1335     parser->source = source; 
    1336  
    1337     if (resolver == Py_None) 
    1338         resolver = NULL; 
    1339     Py_XINCREF(resolver); 
    1340     parser->resolver = resolver; 
    1341  
    1342     parser->syck = syck_new_parser(); 
    1343     parser->syck->bonus = parser; 
    1344  
    1345     if (PyString_Check(source)) { 
    1346         syck_parser_str(parser->syck, PyString_AS_STRING(source), PyString_GET_SIZE(source), NULL); 
    1347     } 
    1348     else { 
    1349         syck_parser_file(parser->syck, (FILE *)parser, PySyckParser_read_handler); 
    1350     } 
    1351     syck_parser_implicit_typing(parser->syck, implicit_typing); 
    1352     syck_parser_taguri_expansion(parser->syck, taguri_expansion); 
    1353  
    1354     syck_parser_handler(parser->syck, PySyckParser_node_handler); 
    1355     syck_parser_error_handler(parser->syck, PySyckParser_error_handler); 
    1356     /* 
    1357     syck_parser_bad_anchor_handler(parser, PySyckParser_bad_anchor_handler); 
    1358     */ 
    1359  
    1360     return (PyObject *)parser; 
    1361 } 
    1362  
    1363 static char PySyck_Parser_doc[] = 
    1364     "Creates a new Parser object."; 
    1365  
    1366 /* The module definitions. */ 
    1367  
    1368 static PyMethodDef PySyck_methods[] = { 
    1369     {"Node",  (PyCFunction)PySyck_Node, METH_VARARGS, PySyck_Node_doc}, 
    1370     {"Parser",  (PyCFunction)PySyck_Parser, METH_VARARGS|METH_KEYWORDS, PySyck_Parser_doc}, 
    1371     {NULL}  /* Sentinel */ 
    1372 }; 
    1373  
    1374 static char PySyck_doc[] = 
    1375     "This module provides low-level access to the Syck parser and emitter.\n" 
    1376     "Do not use this module directly, use the package 'syck' instead.\n"; 
    1377  
    1378 /* PyMODINIT_FUNC - does not work with versions <2.3 */ 
    1379 void 
    1380 init_syck(void) 
    1381 { 
    1382     PyObject *m; 
    1383  
    1384     PySyckNode_Type.ob_type = &PyType_Type; 
    1385     PySyckParser_Type.ob_type = &PyType_Type; 
    1386  
    1387     PySyck_Error = PyErr_NewException("_syck.error", NULL, NULL); 
    1388     if (!PySyck_Error) 
    1389         return; 
    1390  
    1391     PySyck_ScalarKind = PyString_FromString("scalar"); 
    1392     if (!PySyck_ScalarKind) 
    1393         return; 
    1394     PySyck_SeqKind = PyString_FromString("seq"); 
    1395     if (!PySyck_SeqKind) 
    1396         return; 
    1397     PySyck_MapKind = PyString_FromString("map"); 
    1398     if (!PySyck_MapKind) 
    1399         return; 
    1400  
    1401     m = Py_InitModule3("_syck", PySyck_methods, PySyck_doc); 
    1402  
    1403     Py_INCREF(PySyck_Error); 
    1404     if (!PyModule_AddObject(m, "error", PySyck_Error) < 0) 
    1405         return; 
    1406  
    1407     Py_INCREF(&PySyckNode_Type); 
    1408     if (PyModule_AddObject(m, "NodeType", (PyObject *)&PySyckNode_Type) < 0) 
    1409         return; 
    1410  
    1411     Py_INCREF(&PySyckParser_Type); 
    1412     if (PyModule_AddObject(m, "ParserType", (PyObject *)&PySyckParser_Type) < 0) 
    1413         return; 
    1414 } 
    14151592 
    14161593#endif 
     
    14231600 
    14241601PyDoc_STRVAR(PySyck_doc, 
    1425     "The low-level wrapper for the Syck YAML parser and emitter\n\n" 
    1426     "Types:\n\n" 
    1427     "Node -- the base Node type\n"); 
     1602    "low-level wrapper for the Syck YAML parser and emitter"); 
    14281603 
    14291604PyMODINIT_FUNC 
     
    14391614        return; 
    14401615    if (PyType_Ready(&PySyckMap_Type) < 0) 
     1616        return; 
     1617    if (PyType_Ready(&PySyckParser_Type) < 0) 
    14411618        return; 
    14421619     
     
    14691646    m = Py_InitModule3("_syck", PySyck_methods, PySyck_doc); 
    14701647 
     1648    Py_INCREF(PySyck_Error); 
     1649    if (PyModule_AddObject(m, "error", (PyObject *)PySyck_Error) < 0) 
     1650        return; 
     1651 
    14711652    Py_INCREF(&PySyckNode_Type); 
    14721653    if (PyModule_AddObject(m, "Node", (PyObject *)&PySyckNode_Type) < 0) 
     
    14841665    if (PyModule_AddObject(m, "Map", (PyObject *)&PySyckMap_Type) < 0) 
    14851666        return; 
    1486 } 
    1487  
    1488  
     1667 
     1668    Py_INCREF(&PySyckParser_Type); 
     1669    if (PyModule_AddObject(m, "Parser", (PyObject *)&PySyckParser_Type) < 0) 
     1670        return; 
     1671} 
     1672 
  • trunk/tests/test_high_level_parser.py

    r9 r15  
    22import unittest 
    33import syck 
    4 import test_low_parser 
     4import test_low_level_parser 
    55import os 
    66 
     
    125125} 
    126126 
    127 class TestDocuments(test_low_parser.TestDocuments): 
     127class TestDocuments(test_low_level_parser.TestDocuments): 
    128128 
    129129    def _testDocuments(self, source, length): 
     
    137137        self.assertEqual(actual_length, length) 
    138138 
    139 class TestValuesAndSources(test_low_parser.TestValuesAndSources): 
     139class TestValuesAndSources(test_low_level_parser.TestValuesAndSources): 
    140140 
    141141    def testValues1(self): 
    142         self._testValues(test_low_parser.COMPARE1) 
     142        self._testValues(test_low_level_parser.COMPARE1) 
    143143 
    144144    def testValues2(self): 
    145         self._testValues(test_low_parser.COMPARE2) 
     145        self._testValues(test_low_level_parser.COMPARE2) 
    146146 
    147147    def testValues3(self): 
    148         self._testValues(test_low_parser.COMPARE3) 
     148        self._testValues(test_low_level_parser.COMPARE3) 
    149149 
    150150    def testFileValues1(self): 
    151         self._testFileValues(test_low_parser.COMPARE1) 
     151        self._testFileValues(test_low_level_parser.COMPARE1) 
    152152 
    153153    def testFileValues2(self): 
    154         self._testFileValues(test_low_parser.COMPARE2) 
     154        self._testFileValues(test_low_level_parser.COMPARE2) 
    155155 
    156156    def testFileValues3(self): 
    157         self._testFileValues(test_low_parser.COMPARE3) 
     157        self._testFileValues(test_low_level_parser.COMPARE3) 
    158158 
    159159    def testNonsense(self): 
  • trunk/tests/test_low_level_parser.py

    r7 r15  
    44import _syck 
    55 
    6 import StringIO 
     6import StringIO, gc 
    77 
    88EXAMPLE = """ 
     
    160160] 
    161161 
    162 class TestTypes(unittest.TestCase): 
    163  
    164     def testParserType(self): 
     162class TestAttributes(unittest.TestCase): 
     163 
     164    def testAttributes(self): 
    165165        parser = _syck.Parser(EXAMPLE) 
    166         self.assertEqual(type(parser), _syck.ParserType) 
    167  
    168     def testNodeType(self): 
    169         parser = _syck.Parser(EXAMPLE) 
    170         document = parser.parse() 
    171         self.assertEqual(type(document), _syck.NodeType) 
    172  
    173     def testNodeType2(self): 
    174         self.assertRaises(TypeError, (lambda: _syck.Node())) 
     166        self.assertEqual(type(parser), _syck.Parser) 
     167        self.assertEqual(parser.source, EXAMPLE) 
     168        self.assertEqual(parser.implicit_typing, True) 
     169        self.assertEqual(parser.taguri_expansion, True) 
     170        self.assertEqual(parser.eof, False) 
     171        node = parser.parse() 
     172        self.assert_(isinstance(node, _syck.Node)) 
     173        self.assertEqual(parser.source, EXAMPLE) 
     174        self.assertEqual(parser.implicit_typing, True) 
     175        self.assertEqual(parser.taguri_expansion, True) 
     176        self.assertEqual(parser.eof, False) 
     177        self.assertEqual(parser.parse(), None) 
     178        self.assertEqual(parser.eof, True) 
     179 
     180class TestGarbage(unittest.TestCase): 
     181 
     182    def testGarbage(self): 
     183        gc.collect() 
     184        source = [] 
     185        parser = _syck.Parser(source) 
     186        source.append(parser) 
     187        del source, parser 
     188        self.assertEqual(gc.collect(), 2) 
    175189 
    176190class TestErrors(unittest.TestCase): 
     
    178192    def testError(self): 
    179193        parser = _syck.Parser(INVALID[0]) 
    180         self.assertRaises(_syck.error, (lambda: parser.parse())) 
     194        self.assertRaises(_syck.error, lambda: parser.parse()) 
    181195 
    182196    def testErrorLocation(self): 
     
    230244    def testNonsense(self): 
    231245        parser = _syck.Parser(None) 
    232         self.assertRaises(AttributeError, (lambda: parser.parse())) 
     246        self.assertRaises(AttributeError, lambda: parser.parse()) 
     247 
     248    def testCallMeNot(self): 
     249        class Source: 
     250            def __init__(self): 
     251                self.parser = None 
     252            def read(self, size=None): 
     253                if self.parser: 
     254                    self.parser.parse() 
     255                    return 
     256        source = Source() 
     257        parser = _syck.Parser(source) 
     258        source.parser = parser 
     259        self.assertRaises(RuntimeError, lambda: parser.parse()) 
     260 
     261    def testAbsoluteHorror(self): 
     262        class Source: 
     263            def __init__(self): 
     264                self.parser = None 
     265            def read(self, size=None): 
     266                if self.parser: 
     267                    self.parser = None 
     268                return '' 
     269        source = Source() 
     270        parser = _syck.Parser(source) 
     271        source.parser = parser 
     272        del parser 
     273        self.assertEqual(None, source.parser.parse()) 
    233274 
    234275    def _testValues(self, (source, structure)): 
     
    242283        self.assertEqualStructure(document, structure) 
    243284 
    244 class TestResolver(unittest.TestCase, EqualStructure): 
    245  
    246     object = 12345 
    247  
    248     def object_resolver(self, node): 
    249         return self.object 
    250  
    251     def simple_resolver(self, node): 
    252         return node.value 
    253  
    254     def default_resolver(self, node): 
    255         return node 
    256  
    257     def call_me_not_resolver(self, node): 
    258         self.call_me_not_parser.parse() 
    259         return node 
    260  
    261     def testResolver1(self): 
    262         self._testResolver(COMPARE1) 
    263  
    264     def testResolver2(self): 
    265         self._testResolver(COMPARE2) 
    266  
    267     def testResolver3(self): 
    268         self._testResolver(COMPARE3) 
    269  
    270     def testCallMeNot(self): 
    271         self.call_me_not_parser = _syck.Parser(EXAMPLE, self.call_me_not_resolver) 
    272         self.assertRaises(RuntimeError, (lambda: self.call_me_not_parser.parse())) 
    273         del self.call_me_not_parser 
    274  
    275     def _testResolver(self, compare): 
    276         self._testObject(compare) 
    277         self._testSimple(compare) 
    278         self._testDefault(compare) 
    279         self._testNone(compare) 
    280  
    281     def _testObject(self, (source, structure)): 
    282         parser = _syck.Parser(source, self.object_resolver) 
    283         document = parser.parse() 
    284         self.assert_(document is self.object) 
    285  
    286     def _testSimple(self, (source, structure)): 
    287         parser = _syck.Parser(source, self.simple_resolver) 
    288         document = parser.parse() 
    289         self.assert_(document, structure) 
    290  
    291     def _testDefault(self, (source, structure)): 
    292         parser = _syck.Parser(source, resolver=self.default_resolver) 
    293         document = parser.parse() 
    294         self.assertEqualStructure(document, structure) 
    295  
    296     def _testNone(self, (source, structure)): 
    297         parser = _syck.Parser(source, resolver=None) 
    298         document = parser.parse() 
    299         self.assertEqualStructure(document, structure) 
    300  
    301285class TestDocuments(unittest.TestCase): 
    302286 
     
    318302        while True: 
    319303            document = parser.parse() 
    320             if parser.eof(): 
     304            if parser.eof: 
    321305                self.assertEqual(document, None) 
    322306                break 
     
    324308        self.assertEqual(actual_length, length) 
    325309        self.assertEqual(parser.parse(), None) 
    326         self.assert_(parser.eof()) 
     310        self.assert_(parser.eof) 
    327311        self.assertEqual(parser.parse(), None) 
    328         self.assert_(parser.eof()) 
     312        self.assert_(parser.eof) 
     313        self.assert_(parser.eof) 
    329314 
    330315class TestImplicitTyping(unittest.TestCase): 
     
    343328 
    344329    def _testTyping(self, implicit_typing, taguri_expansion): 
    345         parser = _syck.Parser(IMPLICIT_TYPING[0], None, implicit_typing, taguri_expansion) 
    346         for node, (type_id, explicit) in zip(parser.parse().value, IMPLICIT_TYPING[1]): 
    347             if type_id is not None and taguri_expansion: 
    348                 type_id = 'tag:yaml.org,2002:%s' % type_id 
     330        parser = _syck.Parser(IMPLICIT_TYPING[0], implicit_typing, taguri_expansion) 
     331        for node, (tag, explicit) in zip(parser.parse().value, IMPLICIT_TYPING[1]): 
     332            if tag is not None and taguri_expansion: 
     333                tag = 'tag:yaml.org,2002:%s' % tag 
    349334            if implicit_typing or explicit: 
    350                 self.assertEqual(node.type_id, type_id) 
     335                self.assertEqual(node.tag, tag) 
    351336            else: 
    352                 self.assertEqual(node.type_id, None) 
     337                self.assertEqual(node.tag, None) 
    353338 
    354339class TestExplicitTyping(unittest.TestCase): 
     
    356341    def testExplicitTyping(self): 
    357342        parser = _syck.Parser(EXPLICIT_TYPING[0]) 
    358         for node, type_id in zip(parser.parse().value, EXPLICIT_TYPING[1]): 
    359             self.assertEqual(node.type_id, type_id) 
    360  
     343        for node, tag in zip(parser.parse().value, EXPLICIT_TYPING[1]): 
     344            self.assertEqual(node.tag, tag) 
     345 
  • trunk/tests/test_syck.py

    r12 r15  
    22import unittest 
    33 
    4 from test_low_level_node import * 
    5 #from test_low_parser import * 
    6 #from test_high_parser import * 
     4#from test_low_level_node import * 
     5#from test_low_level_parser import * 
     6from test_high_level_parser import * 
    77 
    88def main(module='__main__'): 
Note: See TracChangeset for help on using the changeset viewer.