_yaml.pyx 58 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396
  1. import yaml
  2. def get_version_string():
  3. cdef const char *value
  4. value = yaml_get_version_string()
  5. return PyUnicode_FromString(value)
  6. def get_version():
  7. cdef int major, minor, patch
  8. yaml_get_version(&major, &minor, &patch)
  9. return (major, minor, patch)
  10. #Mark = yaml.error.Mark
  11. YAMLError = yaml.error.YAMLError
  12. ReaderError = yaml.reader.ReaderError
  13. ScannerError = yaml.scanner.ScannerError
  14. ParserError = yaml.parser.ParserError
  15. ComposerError = yaml.composer.ComposerError
  16. ConstructorError = yaml.constructor.ConstructorError
  17. EmitterError = yaml.emitter.EmitterError
  18. SerializerError = yaml.serializer.SerializerError
  19. RepresenterError = yaml.representer.RepresenterError
  20. StreamStartToken = yaml.tokens.StreamStartToken
  21. StreamEndToken = yaml.tokens.StreamEndToken
  22. DirectiveToken = yaml.tokens.DirectiveToken
  23. DocumentStartToken = yaml.tokens.DocumentStartToken
  24. DocumentEndToken = yaml.tokens.DocumentEndToken
  25. BlockSequenceStartToken = yaml.tokens.BlockSequenceStartToken
  26. BlockMappingStartToken = yaml.tokens.BlockMappingStartToken
  27. BlockEndToken = yaml.tokens.BlockEndToken
  28. FlowSequenceStartToken = yaml.tokens.FlowSequenceStartToken
  29. FlowMappingStartToken = yaml.tokens.FlowMappingStartToken
  30. FlowSequenceEndToken = yaml.tokens.FlowSequenceEndToken
  31. FlowMappingEndToken = yaml.tokens.FlowMappingEndToken
  32. KeyToken = yaml.tokens.KeyToken
  33. ValueToken = yaml.tokens.ValueToken
  34. BlockEntryToken = yaml.tokens.BlockEntryToken
  35. FlowEntryToken = yaml.tokens.FlowEntryToken
  36. AliasToken = yaml.tokens.AliasToken
  37. AnchorToken = yaml.tokens.AnchorToken
  38. TagToken = yaml.tokens.TagToken
  39. ScalarToken = yaml.tokens.ScalarToken
  40. StreamStartEvent = yaml.events.StreamStartEvent
  41. StreamEndEvent = yaml.events.StreamEndEvent
  42. DocumentStartEvent = yaml.events.DocumentStartEvent
  43. DocumentEndEvent = yaml.events.DocumentEndEvent
  44. AliasEvent = yaml.events.AliasEvent
  45. ScalarEvent = yaml.events.ScalarEvent
  46. SequenceStartEvent = yaml.events.SequenceStartEvent
  47. SequenceEndEvent = yaml.events.SequenceEndEvent
  48. MappingStartEvent = yaml.events.MappingStartEvent
  49. MappingEndEvent = yaml.events.MappingEndEvent
  50. ScalarNode = yaml.nodes.ScalarNode
  51. SequenceNode = yaml.nodes.SequenceNode
  52. MappingNode = yaml.nodes.MappingNode
  53. cdef class Mark:
  54. cdef readonly object name
  55. cdef readonly size_t index
  56. cdef readonly size_t line
  57. cdef readonly size_t column
  58. cdef readonly buffer
  59. cdef readonly pointer
  60. def __init__(self, object name, size_t index, size_t line, size_t column,
  61. object buffer, object pointer):
  62. self.name = name
  63. self.index = index
  64. self.line = line
  65. self.column = column
  66. self.buffer = buffer
  67. self.pointer = pointer
  68. def get_snippet(self):
  69. return None
  70. def __str__(self):
  71. where = " in \"%s\", line %d, column %d" \
  72. % (self.name, self.line+1, self.column+1)
  73. return where
  74. #class YAMLError(Exception):
  75. # pass
  76. #
  77. #class MarkedYAMLError(YAMLError):
  78. #
  79. # def __init__(self, context=None, context_mark=None,
  80. # problem=None, problem_mark=None, note=None):
  81. # self.context = context
  82. # self.context_mark = context_mark
  83. # self.problem = problem
  84. # self.problem_mark = problem_mark
  85. # self.note = note
  86. #
  87. # def __str__(self):
  88. # lines = []
  89. # if self.context is not None:
  90. # lines.append(self.context)
  91. # if self.context_mark is not None \
  92. # and (self.problem is None or self.problem_mark is None
  93. # or self.context_mark.name != self.problem_mark.name
  94. # or self.context_mark.line != self.problem_mark.line
  95. # or self.context_mark.column != self.problem_mark.column):
  96. # lines.append(str(self.context_mark))
  97. # if self.problem is not None:
  98. # lines.append(self.problem)
  99. # if self.problem_mark is not None:
  100. # lines.append(str(self.problem_mark))
  101. # if self.note is not None:
  102. # lines.append(self.note)
  103. # return '\n'.join(lines)
  104. #
  105. #class ReaderError(YAMLError):
  106. #
  107. # def __init__(self, name, position, character, encoding, reason):
  108. # self.name = name
  109. # self.character = character
  110. # self.position = position
  111. # self.encoding = encoding
  112. # self.reason = reason
  113. #
  114. # def __str__(self):
  115. # if isinstance(self.character, str):
  116. # return "'%s' codec can't decode byte #x%02x: %s\n" \
  117. # " in \"%s\", position %d" \
  118. # % (self.encoding, ord(self.character), self.reason,
  119. # self.name, self.position)
  120. # else:
  121. # return "unacceptable character #x%04x: %s\n" \
  122. # " in \"%s\", position %d" \
  123. # % (ord(self.character), self.reason,
  124. # self.name, self.position)
  125. #
  126. #class ScannerError(MarkedYAMLError):
  127. # pass
  128. #
  129. #class ParserError(MarkedYAMLError):
  130. # pass
  131. #
  132. #class EmitterError(YAMLError):
  133. # pass
  134. #
  135. #cdef class Token:
  136. # cdef readonly Mark start_mark
  137. # cdef readonly Mark end_mark
  138. # def __init__(self, Mark start_mark, Mark end_mark):
  139. # self.start_mark = start_mark
  140. # self.end_mark = end_mark
  141. #
  142. #cdef class StreamStartToken(Token):
  143. # cdef readonly object encoding
  144. # def __init__(self, Mark start_mark, Mark end_mark, encoding):
  145. # self.start_mark = start_mark
  146. # self.end_mark = end_mark
  147. # self.encoding = encoding
  148. #
  149. #cdef class StreamEndToken(Token):
  150. # pass
  151. #
  152. #cdef class DirectiveToken(Token):
  153. # cdef readonly object name
  154. # cdef readonly object value
  155. # def __init__(self, name, value, Mark start_mark, Mark end_mark):
  156. # self.name = name
  157. # self.value = value
  158. # self.start_mark = start_mark
  159. # self.end_mark = end_mark
  160. #
  161. #cdef class DocumentStartToken(Token):
  162. # pass
  163. #
  164. #cdef class DocumentEndToken(Token):
  165. # pass
  166. #
  167. #cdef class BlockSequenceStartToken(Token):
  168. # pass
  169. #
  170. #cdef class BlockMappingStartToken(Token):
  171. # pass
  172. #
  173. #cdef class BlockEndToken(Token):
  174. # pass
  175. #
  176. #cdef class FlowSequenceStartToken(Token):
  177. # pass
  178. #
  179. #cdef class FlowMappingStartToken(Token):
  180. # pass
  181. #
  182. #cdef class FlowSequenceEndToken(Token):
  183. # pass
  184. #
  185. #cdef class FlowMappingEndToken(Token):
  186. # pass
  187. #
  188. #cdef class KeyToken(Token):
  189. # pass
  190. #
  191. #cdef class ValueToken(Token):
  192. # pass
  193. #
  194. #cdef class BlockEntryToken(Token):
  195. # pass
  196. #
  197. #cdef class FlowEntryToken(Token):
  198. # pass
  199. #
  200. #cdef class AliasToken(Token):
  201. # cdef readonly object value
  202. # def __init__(self, value, Mark start_mark, Mark end_mark):
  203. # self.value = value
  204. # self.start_mark = start_mark
  205. # self.end_mark = end_mark
  206. #
  207. #cdef class AnchorToken(Token):
  208. # cdef readonly object value
  209. # def __init__(self, value, Mark start_mark, Mark end_mark):
  210. # self.value = value
  211. # self.start_mark = start_mark
  212. # self.end_mark = end_mark
  213. #
  214. #cdef class TagToken(Token):
  215. # cdef readonly object value
  216. # def __init__(self, value, Mark start_mark, Mark end_mark):
  217. # self.value = value
  218. # self.start_mark = start_mark
  219. # self.end_mark = end_mark
  220. #
  221. #cdef class ScalarToken(Token):
  222. # cdef readonly object value
  223. # cdef readonly object plain
  224. # cdef readonly object style
  225. # def __init__(self, value, plain, Mark start_mark, Mark end_mark, style=None):
  226. # self.value = value
  227. # self.plain = plain
  228. # self.start_mark = start_mark
  229. # self.end_mark = end_mark
  230. # self.style = style
  231. cdef class CParser:
  232. cdef yaml_parser_t parser
  233. cdef yaml_event_t parsed_event
  234. cdef object stream
  235. cdef object stream_name
  236. cdef object current_token
  237. cdef object current_event
  238. cdef object anchors
  239. cdef object stream_cache
  240. cdef int stream_cache_len
  241. cdef int stream_cache_pos
  242. cdef int unicode_source
  243. def __init__(self, stream):
  244. cdef is_readable
  245. if yaml_parser_initialize(&self.parser) == 0:
  246. raise MemoryError
  247. self.parsed_event.type = YAML_NO_EVENT
  248. is_readable = 1
  249. try:
  250. stream.read
  251. except AttributeError:
  252. is_readable = 0
  253. self.unicode_source = 0
  254. if is_readable:
  255. self.stream = stream
  256. try:
  257. self.stream_name = stream.name
  258. except AttributeError:
  259. self.stream_name = u'<file>'
  260. self.stream_cache = None
  261. self.stream_cache_len = 0
  262. self.stream_cache_pos = 0
  263. yaml_parser_set_input(&self.parser, input_handler, <void *>self)
  264. else:
  265. if PyUnicode_CheckExact(stream) != 0:
  266. stream = PyUnicode_AsUTF8String(stream)
  267. self.stream_name = u'<unicode string>'
  268. self.unicode_source = 1
  269. else:
  270. self.stream_name = u'<byte string>'
  271. if PyBytes_CheckExact(stream) == 0:
  272. raise TypeError(u"a string or stream input is required")
  273. self.stream = stream
  274. yaml_parser_set_input_string(&self.parser, PyBytes_AS_Yaml_STRING(stream), PyBytes_GET_SIZE(stream))
  275. self.current_token = None
  276. self.current_event = None
  277. self.anchors = {}
  278. def __dealloc__(self):
  279. yaml_parser_delete(&self.parser)
  280. yaml_event_delete(&self.parsed_event)
  281. def dispose(self):
  282. pass
  283. cdef object _parser_error(self):
  284. if self.parser.error == YAML_MEMORY_ERROR:
  285. return MemoryError
  286. elif self.parser.error == YAML_READER_ERROR:
  287. return ReaderError(self.stream_name, self.parser.problem_offset,
  288. self.parser.problem_value, u'?', PyUnicode_FromString(self.parser.problem))
  289. elif self.parser.error == YAML_SCANNER_ERROR \
  290. or self.parser.error == YAML_PARSER_ERROR:
  291. context_mark = None
  292. problem_mark = None
  293. if self.parser.context != NULL:
  294. context_mark = Mark(self.stream_name,
  295. self.parser.context_mark.index,
  296. self.parser.context_mark.line,
  297. self.parser.context_mark.column, None, None)
  298. if self.parser.problem != NULL:
  299. problem_mark = Mark(self.stream_name,
  300. self.parser.problem_mark.index,
  301. self.parser.problem_mark.line,
  302. self.parser.problem_mark.column, None, None)
  303. context = None
  304. if self.parser.context != NULL:
  305. context = PyUnicode_FromString(self.parser.context)
  306. problem = PyUnicode_FromString(self.parser.problem)
  307. if self.parser.error == YAML_SCANNER_ERROR:
  308. return ScannerError(context, context_mark, problem, problem_mark)
  309. else:
  310. return ParserError(context, context_mark, problem, problem_mark)
  311. raise ValueError(u"no parser error")
  312. def raw_scan(self):
  313. cdef yaml_token_t token
  314. cdef int done
  315. cdef int count
  316. count = 0
  317. done = 0
  318. while done == 0:
  319. if yaml_parser_scan(&self.parser, &token) == 0:
  320. error = self._parser_error()
  321. raise error
  322. if token.type == YAML_NO_TOKEN:
  323. done = 1
  324. else:
  325. count = count+1
  326. yaml_token_delete(&token)
  327. return count
  328. cdef object _scan(self):
  329. cdef yaml_token_t token
  330. if yaml_parser_scan(&self.parser, &token) == 0:
  331. error = self._parser_error()
  332. raise error
  333. token_object = self._token_to_object(&token)
  334. yaml_token_delete(&token)
  335. return token_object
  336. cdef object _token_to_object(self, yaml_token_t *token):
  337. start_mark = Mark(self.stream_name,
  338. token.start_mark.index,
  339. token.start_mark.line,
  340. token.start_mark.column,
  341. None, None)
  342. end_mark = Mark(self.stream_name,
  343. token.end_mark.index,
  344. token.end_mark.line,
  345. token.end_mark.column,
  346. None, None)
  347. if token.type == YAML_NO_TOKEN:
  348. return None
  349. elif token.type == YAML_STREAM_START_TOKEN:
  350. encoding = None
  351. if token.data.stream_start.encoding == YAML_UTF8_ENCODING:
  352. if self.unicode_source == 0:
  353. encoding = u"utf-8"
  354. elif token.data.stream_start.encoding == YAML_UTF16LE_ENCODING:
  355. encoding = u"utf-16-le"
  356. elif token.data.stream_start.encoding == YAML_UTF16BE_ENCODING:
  357. encoding = u"utf-16-be"
  358. return StreamStartToken(start_mark, end_mark, encoding)
  359. elif token.type == YAML_STREAM_END_TOKEN:
  360. return StreamEndToken(start_mark, end_mark)
  361. elif token.type == YAML_VERSION_DIRECTIVE_TOKEN:
  362. return DirectiveToken(u"YAML",
  363. (token.data.version_directive.major,
  364. token.data.version_directive.minor),
  365. start_mark, end_mark)
  366. elif token.type == YAML_TAG_DIRECTIVE_TOKEN:
  367. handle = PyUnicode_FromYamlString(token.data.tag_directive.handle)
  368. prefix = PyUnicode_FromYamlString(token.data.tag_directive.prefix)
  369. return DirectiveToken(u"TAG", (handle, prefix),
  370. start_mark, end_mark)
  371. elif token.type == YAML_DOCUMENT_START_TOKEN:
  372. return DocumentStartToken(start_mark, end_mark)
  373. elif token.type == YAML_DOCUMENT_END_TOKEN:
  374. return DocumentEndToken(start_mark, end_mark)
  375. elif token.type == YAML_BLOCK_SEQUENCE_START_TOKEN:
  376. return BlockSequenceStartToken(start_mark, end_mark)
  377. elif token.type == YAML_BLOCK_MAPPING_START_TOKEN:
  378. return BlockMappingStartToken(start_mark, end_mark)
  379. elif token.type == YAML_BLOCK_END_TOKEN:
  380. return BlockEndToken(start_mark, end_mark)
  381. elif token.type == YAML_FLOW_SEQUENCE_START_TOKEN:
  382. return FlowSequenceStartToken(start_mark, end_mark)
  383. elif token.type == YAML_FLOW_SEQUENCE_END_TOKEN:
  384. return FlowSequenceEndToken(start_mark, end_mark)
  385. elif token.type == YAML_FLOW_MAPPING_START_TOKEN:
  386. return FlowMappingStartToken(start_mark, end_mark)
  387. elif token.type == YAML_FLOW_MAPPING_END_TOKEN:
  388. return FlowMappingEndToken(start_mark, end_mark)
  389. elif token.type == YAML_BLOCK_ENTRY_TOKEN:
  390. return BlockEntryToken(start_mark, end_mark)
  391. elif token.type == YAML_FLOW_ENTRY_TOKEN:
  392. return FlowEntryToken(start_mark, end_mark)
  393. elif token.type == YAML_KEY_TOKEN:
  394. return KeyToken(start_mark, end_mark)
  395. elif token.type == YAML_VALUE_TOKEN:
  396. return ValueToken(start_mark, end_mark)
  397. elif token.type == YAML_ALIAS_TOKEN:
  398. value = PyUnicode_FromYamlString(token.data.alias.value)
  399. return AliasToken(value, start_mark, end_mark)
  400. elif token.type == YAML_ANCHOR_TOKEN:
  401. value = PyUnicode_FromYamlString(token.data.anchor.value)
  402. return AnchorToken(value, start_mark, end_mark)
  403. elif token.type == YAML_TAG_TOKEN:
  404. handle = PyUnicode_FromYamlString(token.data.tag.handle)
  405. suffix = PyUnicode_FromYamlString(token.data.tag.suffix)
  406. if not handle:
  407. handle = None
  408. return TagToken((handle, suffix), start_mark, end_mark)
  409. elif token.type == YAML_SCALAR_TOKEN:
  410. value = PyUnicode_DecodeUTF8(<char *>token.data.scalar.value,
  411. token.data.scalar.length, 'strict')
  412. plain = False
  413. style = None
  414. if token.data.scalar.style == YAML_PLAIN_SCALAR_STYLE:
  415. plain = True
  416. style = u''
  417. elif token.data.scalar.style == YAML_SINGLE_QUOTED_SCALAR_STYLE:
  418. style = u'\''
  419. elif token.data.scalar.style == YAML_DOUBLE_QUOTED_SCALAR_STYLE:
  420. style = u'"'
  421. elif token.data.scalar.style == YAML_LITERAL_SCALAR_STYLE:
  422. style = u'|'
  423. elif token.data.scalar.style == YAML_FOLDED_SCALAR_STYLE:
  424. style = u'>'
  425. return ScalarToken(value, plain,
  426. start_mark, end_mark, style)
  427. else:
  428. raise ValueError(u"unknown token type")
  429. def get_token(self):
  430. if self.current_token is not None:
  431. value = self.current_token
  432. self.current_token = None
  433. else:
  434. value = self._scan()
  435. return value
  436. def peek_token(self):
  437. if self.current_token is None:
  438. self.current_token = self._scan()
  439. return self.current_token
  440. def check_token(self, *choices):
  441. if self.current_token is None:
  442. self.current_token = self._scan()
  443. if self.current_token is None:
  444. return False
  445. if not choices:
  446. return True
  447. token_class = self.current_token.__class__
  448. for choice in choices:
  449. if token_class is choice:
  450. return True
  451. return False
  452. def raw_parse(self):
  453. cdef yaml_event_t event
  454. cdef int done
  455. cdef int count
  456. count = 0
  457. done = 0
  458. while done == 0:
  459. if yaml_parser_parse(&self.parser, &event) == 0:
  460. error = self._parser_error()
  461. raise error
  462. if event.type == YAML_NO_EVENT:
  463. done = 1
  464. else:
  465. count = count+1
  466. yaml_event_delete(&event)
  467. return count
  468. cdef object _parse(self):
  469. cdef yaml_event_t event
  470. if yaml_parser_parse(&self.parser, &event) == 0:
  471. error = self._parser_error()
  472. raise error
  473. event_object = self._event_to_object(&event)
  474. yaml_event_delete(&event)
  475. return event_object
  476. cdef object _event_to_object(self, yaml_event_t *event):
  477. cdef yaml_tag_directive_t *tag_directive
  478. start_mark = Mark(self.stream_name,
  479. event.start_mark.index,
  480. event.start_mark.line,
  481. event.start_mark.column,
  482. None, None)
  483. end_mark = Mark(self.stream_name,
  484. event.end_mark.index,
  485. event.end_mark.line,
  486. event.end_mark.column,
  487. None, None)
  488. if event.type == YAML_NO_EVENT:
  489. return None
  490. elif event.type == YAML_STREAM_START_EVENT:
  491. encoding = None
  492. if event.data.stream_start.encoding == YAML_UTF8_ENCODING:
  493. if self.unicode_source == 0:
  494. encoding = u"utf-8"
  495. elif event.data.stream_start.encoding == YAML_UTF16LE_ENCODING:
  496. encoding = u"utf-16-le"
  497. elif event.data.stream_start.encoding == YAML_UTF16BE_ENCODING:
  498. encoding = u"utf-16-be"
  499. return StreamStartEvent(start_mark, end_mark, encoding)
  500. elif event.type == YAML_STREAM_END_EVENT:
  501. return StreamEndEvent(start_mark, end_mark)
  502. elif event.type == YAML_DOCUMENT_START_EVENT:
  503. explicit = False
  504. if event.data.document_start.implicit == 0:
  505. explicit = True
  506. version = None
  507. if event.data.document_start.version_directive != NULL:
  508. version = (event.data.document_start.version_directive.major,
  509. event.data.document_start.version_directive.minor)
  510. tags = None
  511. if event.data.document_start.tag_directives.start != NULL:
  512. tags = {}
  513. tag_directive = event.data.document_start.tag_directives.start
  514. while tag_directive != event.data.document_start.tag_directives.end:
  515. handle = PyUnicode_FromYamlString(tag_directive.handle)
  516. prefix = PyUnicode_FromYamlString(tag_directive.prefix)
  517. tags[handle] = prefix
  518. tag_directive = tag_directive+1
  519. return DocumentStartEvent(start_mark, end_mark,
  520. explicit, version, tags)
  521. elif event.type == YAML_DOCUMENT_END_EVENT:
  522. explicit = False
  523. if event.data.document_end.implicit == 0:
  524. explicit = True
  525. return DocumentEndEvent(start_mark, end_mark, explicit)
  526. elif event.type == YAML_ALIAS_EVENT:
  527. anchor = PyUnicode_FromYamlString(event.data.alias.anchor)
  528. return AliasEvent(anchor, start_mark, end_mark)
  529. elif event.type == YAML_SCALAR_EVENT:
  530. anchor = None
  531. if event.data.scalar.anchor != NULL:
  532. anchor = PyUnicode_FromYamlString(event.data.scalar.anchor)
  533. tag = None
  534. if event.data.scalar.tag != NULL:
  535. tag = PyUnicode_FromYamlString(event.data.scalar.tag)
  536. value = PyUnicode_DecodeUTF8(<char *>event.data.scalar.value,
  537. event.data.scalar.length, 'strict')
  538. plain_implicit = False
  539. if event.data.scalar.plain_implicit == 1:
  540. plain_implicit = True
  541. quoted_implicit = False
  542. if event.data.scalar.quoted_implicit == 1:
  543. quoted_implicit = True
  544. style = None
  545. if event.data.scalar.style == YAML_PLAIN_SCALAR_STYLE:
  546. style = u''
  547. elif event.data.scalar.style == YAML_SINGLE_QUOTED_SCALAR_STYLE:
  548. style = u'\''
  549. elif event.data.scalar.style == YAML_DOUBLE_QUOTED_SCALAR_STYLE:
  550. style = u'"'
  551. elif event.data.scalar.style == YAML_LITERAL_SCALAR_STYLE:
  552. style = u'|'
  553. elif event.data.scalar.style == YAML_FOLDED_SCALAR_STYLE:
  554. style = u'>'
  555. return ScalarEvent(anchor, tag,
  556. (plain_implicit, quoted_implicit),
  557. value, start_mark, end_mark, style)
  558. elif event.type == YAML_SEQUENCE_START_EVENT:
  559. anchor = None
  560. if event.data.sequence_start.anchor != NULL:
  561. anchor = PyUnicode_FromYamlString(event.data.sequence_start.anchor)
  562. tag = None
  563. if event.data.sequence_start.tag != NULL:
  564. tag = PyUnicode_FromYamlString(event.data.sequence_start.tag)
  565. implicit = False
  566. if event.data.sequence_start.implicit == 1:
  567. implicit = True
  568. flow_style = None
  569. if event.data.sequence_start.style == YAML_FLOW_SEQUENCE_STYLE:
  570. flow_style = True
  571. elif event.data.sequence_start.style == YAML_BLOCK_SEQUENCE_STYLE:
  572. flow_style = False
  573. return SequenceStartEvent(anchor, tag, implicit,
  574. start_mark, end_mark, flow_style)
  575. elif event.type == YAML_MAPPING_START_EVENT:
  576. anchor = None
  577. if event.data.mapping_start.anchor != NULL:
  578. anchor = PyUnicode_FromYamlString(event.data.mapping_start.anchor)
  579. tag = None
  580. if event.data.mapping_start.tag != NULL:
  581. tag = PyUnicode_FromYamlString(event.data.mapping_start.tag)
  582. implicit = False
  583. if event.data.mapping_start.implicit == 1:
  584. implicit = True
  585. flow_style = None
  586. if event.data.mapping_start.style == YAML_FLOW_MAPPING_STYLE:
  587. flow_style = True
  588. elif event.data.mapping_start.style == YAML_BLOCK_MAPPING_STYLE:
  589. flow_style = False
  590. return MappingStartEvent(anchor, tag, implicit,
  591. start_mark, end_mark, flow_style)
  592. elif event.type == YAML_SEQUENCE_END_EVENT:
  593. return SequenceEndEvent(start_mark, end_mark)
  594. elif event.type == YAML_MAPPING_END_EVENT:
  595. return MappingEndEvent(start_mark, end_mark)
  596. else:
  597. raise ValueError(u"unknown event type")
  598. def get_event(self):
  599. if self.current_event is not None:
  600. value = self.current_event
  601. self.current_event = None
  602. else:
  603. value = self._parse()
  604. return value
  605. def peek_event(self):
  606. if self.current_event is None:
  607. self.current_event = self._parse()
  608. return self.current_event
  609. def check_event(self, *choices):
  610. if self.current_event is None:
  611. self.current_event = self._parse()
  612. if self.current_event is None:
  613. return False
  614. if not choices:
  615. return True
  616. event_class = self.current_event.__class__
  617. for choice in choices:
  618. if event_class is choice:
  619. return True
  620. return False
  621. def check_node(self):
  622. self._parse_next_event()
  623. if self.parsed_event.type == YAML_STREAM_START_EVENT:
  624. yaml_event_delete(&self.parsed_event)
  625. self._parse_next_event()
  626. if self.parsed_event.type != YAML_STREAM_END_EVENT:
  627. return True
  628. return False
  629. def get_node(self):
  630. self._parse_next_event()
  631. if self.parsed_event.type != YAML_STREAM_END_EVENT:
  632. return self._compose_document()
  633. def get_single_node(self):
  634. self._parse_next_event()
  635. yaml_event_delete(&self.parsed_event)
  636. self._parse_next_event()
  637. document = None
  638. if self.parsed_event.type != YAML_STREAM_END_EVENT:
  639. document = self._compose_document()
  640. self._parse_next_event()
  641. if self.parsed_event.type != YAML_STREAM_END_EVENT:
  642. mark = Mark(self.stream_name,
  643. self.parsed_event.start_mark.index,
  644. self.parsed_event.start_mark.line,
  645. self.parsed_event.start_mark.column,
  646. None, None)
  647. raise ComposerError(u"expected a single document in the stream",
  648. document.start_mark, u"but found another document", mark)
  649. return document
  650. cdef object _compose_document(self):
  651. yaml_event_delete(&self.parsed_event)
  652. node = self._compose_node(None, None)
  653. self._parse_next_event()
  654. yaml_event_delete(&self.parsed_event)
  655. self.anchors = {}
  656. return node
  657. cdef object _compose_node(self, object parent, object index):
  658. self._parse_next_event()
  659. if self.parsed_event.type == YAML_ALIAS_EVENT:
  660. anchor = PyUnicode_FromYamlString(self.parsed_event.data.alias.anchor)
  661. if anchor not in self.anchors:
  662. mark = Mark(self.stream_name,
  663. self.parsed_event.start_mark.index,
  664. self.parsed_event.start_mark.line,
  665. self.parsed_event.start_mark.column,
  666. None, None)
  667. raise ComposerError(None, None, u"found undefined alias", mark)
  668. yaml_event_delete(&self.parsed_event)
  669. return self.anchors[anchor]
  670. anchor = None
  671. if self.parsed_event.type == YAML_SCALAR_EVENT \
  672. and self.parsed_event.data.scalar.anchor != NULL:
  673. anchor = PyUnicode_FromYamlString(self.parsed_event.data.scalar.anchor)
  674. elif self.parsed_event.type == YAML_SEQUENCE_START_EVENT \
  675. and self.parsed_event.data.sequence_start.anchor != NULL:
  676. anchor = PyUnicode_FromYamlString(self.parsed_event.data.sequence_start.anchor)
  677. elif self.parsed_event.type == YAML_MAPPING_START_EVENT \
  678. and self.parsed_event.data.mapping_start.anchor != NULL:
  679. anchor = PyUnicode_FromYamlString(self.parsed_event.data.mapping_start.anchor)
  680. if anchor is not None:
  681. if anchor in self.anchors:
  682. mark = Mark(self.stream_name,
  683. self.parsed_event.start_mark.index,
  684. self.parsed_event.start_mark.line,
  685. self.parsed_event.start_mark.column,
  686. None, None)
  687. raise ComposerError(u"found duplicate anchor; first occurrence",
  688. self.anchors[anchor].start_mark, u"second occurrence", mark)
  689. self.descend_resolver(parent, index)
  690. if self.parsed_event.type == YAML_SCALAR_EVENT:
  691. node = self._compose_scalar_node(anchor)
  692. elif self.parsed_event.type == YAML_SEQUENCE_START_EVENT:
  693. node = self._compose_sequence_node(anchor)
  694. elif self.parsed_event.type == YAML_MAPPING_START_EVENT:
  695. node = self._compose_mapping_node(anchor)
  696. self.ascend_resolver()
  697. return node
  698. cdef _compose_scalar_node(self, object anchor):
  699. start_mark = Mark(self.stream_name,
  700. self.parsed_event.start_mark.index,
  701. self.parsed_event.start_mark.line,
  702. self.parsed_event.start_mark.column,
  703. None, None)
  704. end_mark = Mark(self.stream_name,
  705. self.parsed_event.end_mark.index,
  706. self.parsed_event.end_mark.line,
  707. self.parsed_event.end_mark.column,
  708. None, None)
  709. value = PyUnicode_DecodeUTF8(<char *>self.parsed_event.data.scalar.value,
  710. self.parsed_event.data.scalar.length, 'strict')
  711. plain_implicit = False
  712. if self.parsed_event.data.scalar.plain_implicit == 1:
  713. plain_implicit = True
  714. quoted_implicit = False
  715. if self.parsed_event.data.scalar.quoted_implicit == 1:
  716. quoted_implicit = True
  717. if self.parsed_event.data.scalar.tag == NULL \
  718. or (self.parsed_event.data.scalar.tag[0] == c'!'
  719. and self.parsed_event.data.scalar.tag[1] == c'\0'):
  720. tag = self.resolve(ScalarNode, value, (plain_implicit, quoted_implicit))
  721. else:
  722. tag = PyUnicode_FromYamlString(self.parsed_event.data.scalar.tag)
  723. style = None
  724. if self.parsed_event.data.scalar.style == YAML_PLAIN_SCALAR_STYLE:
  725. style = u''
  726. elif self.parsed_event.data.scalar.style == YAML_SINGLE_QUOTED_SCALAR_STYLE:
  727. style = u'\''
  728. elif self.parsed_event.data.scalar.style == YAML_DOUBLE_QUOTED_SCALAR_STYLE:
  729. style = u'"'
  730. elif self.parsed_event.data.scalar.style == YAML_LITERAL_SCALAR_STYLE:
  731. style = u'|'
  732. elif self.parsed_event.data.scalar.style == YAML_FOLDED_SCALAR_STYLE:
  733. style = u'>'
  734. node = ScalarNode(tag, value, start_mark, end_mark, style)
  735. if anchor is not None:
  736. self.anchors[anchor] = node
  737. yaml_event_delete(&self.parsed_event)
  738. return node
  739. cdef _compose_sequence_node(self, object anchor):
  740. cdef int index
  741. start_mark = Mark(self.stream_name,
  742. self.parsed_event.start_mark.index,
  743. self.parsed_event.start_mark.line,
  744. self.parsed_event.start_mark.column,
  745. None, None)
  746. implicit = False
  747. if self.parsed_event.data.sequence_start.implicit == 1:
  748. implicit = True
  749. if self.parsed_event.data.sequence_start.tag == NULL \
  750. or (self.parsed_event.data.sequence_start.tag[0] == c'!'
  751. and self.parsed_event.data.sequence_start.tag[1] == c'\0'):
  752. tag = self.resolve(SequenceNode, None, implicit)
  753. else:
  754. tag = PyUnicode_FromYamlString(self.parsed_event.data.sequence_start.tag)
  755. flow_style = None
  756. if self.parsed_event.data.sequence_start.style == YAML_FLOW_SEQUENCE_STYLE:
  757. flow_style = True
  758. elif self.parsed_event.data.sequence_start.style == YAML_BLOCK_SEQUENCE_STYLE:
  759. flow_style = False
  760. value = []
  761. node = SequenceNode(tag, value, start_mark, None, flow_style)
  762. if anchor is not None:
  763. self.anchors[anchor] = node
  764. yaml_event_delete(&self.parsed_event)
  765. index = 0
  766. self._parse_next_event()
  767. while self.parsed_event.type != YAML_SEQUENCE_END_EVENT:
  768. value.append(self._compose_node(node, index))
  769. index = index+1
  770. self._parse_next_event()
  771. node.end_mark = Mark(self.stream_name,
  772. self.parsed_event.end_mark.index,
  773. self.parsed_event.end_mark.line,
  774. self.parsed_event.end_mark.column,
  775. None, None)
  776. yaml_event_delete(&self.parsed_event)
  777. return node
  778. cdef _compose_mapping_node(self, object anchor):
  779. start_mark = Mark(self.stream_name,
  780. self.parsed_event.start_mark.index,
  781. self.parsed_event.start_mark.line,
  782. self.parsed_event.start_mark.column,
  783. None, None)
  784. implicit = False
  785. if self.parsed_event.data.mapping_start.implicit == 1:
  786. implicit = True
  787. if self.parsed_event.data.mapping_start.tag == NULL \
  788. or (self.parsed_event.data.mapping_start.tag[0] == c'!'
  789. and self.parsed_event.data.mapping_start.tag[1] == c'\0'):
  790. tag = self.resolve(MappingNode, None, implicit)
  791. else:
  792. tag = PyUnicode_FromYamlString(self.parsed_event.data.mapping_start.tag)
  793. flow_style = None
  794. if self.parsed_event.data.mapping_start.style == YAML_FLOW_MAPPING_STYLE:
  795. flow_style = True
  796. elif self.parsed_event.data.mapping_start.style == YAML_BLOCK_MAPPING_STYLE:
  797. flow_style = False
  798. value = []
  799. node = MappingNode(tag, value, start_mark, None, flow_style)
  800. if anchor is not None:
  801. self.anchors[anchor] = node
  802. yaml_event_delete(&self.parsed_event)
  803. self._parse_next_event()
  804. while self.parsed_event.type != YAML_MAPPING_END_EVENT:
  805. item_key = self._compose_node(node, None)
  806. item_value = self._compose_node(node, item_key)
  807. value.append((item_key, item_value))
  808. self._parse_next_event()
  809. node.end_mark = Mark(self.stream_name,
  810. self.parsed_event.end_mark.index,
  811. self.parsed_event.end_mark.line,
  812. self.parsed_event.end_mark.column,
  813. None, None)
  814. yaml_event_delete(&self.parsed_event)
  815. return node
  816. cdef int _parse_next_event(self) except 0:
  817. if self.parsed_event.type == YAML_NO_EVENT:
  818. if yaml_parser_parse(&self.parser, &self.parsed_event) == 0:
  819. error = self._parser_error()
  820. raise error
  821. return 1
  822. cdef int input_handler(void *data, unsigned char *buffer, size_t size, size_t *read) except 0:
  823. cdef CParser parser
  824. parser = <CParser>data
  825. if parser.stream_cache is None:
  826. value = parser.stream.read(size)
  827. if PyUnicode_CheckExact(value) != 0:
  828. value = PyUnicode_AsUTF8String(value)
  829. parser.unicode_source = 1
  830. if PyBytes_CheckExact(value) == 0:
  831. raise TypeError(u"a string value is expected")
  832. parser.stream_cache = value
  833. parser.stream_cache_pos = 0
  834. parser.stream_cache_len = PyBytes_GET_SIZE(value)
  835. if (parser.stream_cache_len - parser.stream_cache_pos) < <int>size:
  836. size = parser.stream_cache_len - parser.stream_cache_pos
  837. if size > 0:
  838. memcpy(buffer, PyBytes_AS_STRING(parser.stream_cache)
  839. + parser.stream_cache_pos, size)
  840. read[0] = size
  841. parser.stream_cache_pos += size
  842. if parser.stream_cache_pos == parser.stream_cache_len:
  843. parser.stream_cache = None
  844. return 1
  845. cdef class CEmitter:
  846. cdef yaml_emitter_t emitter
  847. cdef object stream
  848. cdef int document_start_implicit
  849. cdef int document_end_implicit
  850. cdef object use_version
  851. cdef object use_tags
  852. cdef object serialized_nodes
  853. cdef object anchors
  854. cdef int last_alias_id
  855. cdef int closed
  856. cdef int dump_unicode
  857. cdef object use_encoding
  858. def __init__(self, stream, canonical=None, indent=None, width=None,
  859. allow_unicode=None, line_break=None, encoding=None,
  860. explicit_start=None, explicit_end=None, version=None, tags=None):
  861. if yaml_emitter_initialize(&self.emitter) == 0:
  862. raise MemoryError
  863. self.stream = stream
  864. self.dump_unicode = 0
  865. if hasattr(stream, u'encoding'):
  866. self.dump_unicode = 1
  867. self.use_encoding = encoding
  868. yaml_emitter_set_output(&self.emitter, output_handler, <void *>self)
  869. if canonical:
  870. yaml_emitter_set_canonical(&self.emitter, 1)
  871. if indent is not None:
  872. yaml_emitter_set_indent(&self.emitter, indent)
  873. if width is not None:
  874. yaml_emitter_set_width(&self.emitter, width)
  875. if allow_unicode:
  876. yaml_emitter_set_unicode(&self.emitter, 1)
  877. if line_break is not None:
  878. if line_break == '\r':
  879. yaml_emitter_set_break(&self.emitter, YAML_CR_BREAK)
  880. elif line_break == '\n':
  881. yaml_emitter_set_break(&self.emitter, YAML_LN_BREAK)
  882. elif line_break == '\r\n':
  883. yaml_emitter_set_break(&self.emitter, YAML_CRLN_BREAK)
  884. self.document_start_implicit = 1
  885. if explicit_start:
  886. self.document_start_implicit = 0
  887. self.document_end_implicit = 1
  888. if explicit_end:
  889. self.document_end_implicit = 0
  890. self.use_version = version
  891. self.use_tags = tags
  892. self.serialized_nodes = {}
  893. self.anchors = {}
  894. self.last_alias_id = 0
  895. self.closed = -1
  896. def __dealloc__(self):
  897. yaml_emitter_delete(&self.emitter)
  898. def dispose(self):
  899. pass
  900. cdef object _emitter_error(self):
  901. if self.emitter.error == YAML_MEMORY_ERROR:
  902. return MemoryError
  903. elif self.emitter.error == YAML_EMITTER_ERROR:
  904. problem = PyUnicode_FromString(self.emitter.problem)
  905. return EmitterError(problem)
  906. raise ValueError(u"no emitter error")
  907. cdef int _object_to_event(self, object event_object, yaml_event_t *event) except 0:
  908. cdef yaml_encoding_t encoding
  909. cdef yaml_version_directive_t version_directive_value
  910. cdef yaml_version_directive_t *version_directive
  911. cdef yaml_tag_directive_t tag_directives_value[128]
  912. cdef yaml_tag_directive_t *tag_directives_start
  913. cdef yaml_tag_directive_t *tag_directives_end
  914. cdef int implicit
  915. cdef int plain_implicit
  916. cdef int quoted_implicit
  917. cdef yaml_char_t *anchor
  918. cdef yaml_char_t *tag
  919. cdef yaml_char_t *value
  920. cdef int length
  921. cdef yaml_scalar_style_t scalar_style
  922. cdef yaml_sequence_style_t sequence_style
  923. cdef yaml_mapping_style_t mapping_style
  924. event_class = event_object.__class__
  925. if event_class is StreamStartEvent:
  926. encoding = YAML_UTF8_ENCODING
  927. if event_object.encoding == u'utf-16-le' or event_object.encoding == 'utf-16-le':
  928. encoding = YAML_UTF16LE_ENCODING
  929. elif event_object.encoding == u'utf-16-be' or event_object.encoding == 'utf-16-be':
  930. encoding = YAML_UTF16BE_ENCODING
  931. if event_object.encoding is None:
  932. self.dump_unicode = 1
  933. if self.dump_unicode == 1:
  934. encoding = YAML_UTF8_ENCODING
  935. yaml_stream_start_event_initialize(event, encoding)
  936. elif event_class is StreamEndEvent:
  937. yaml_stream_end_event_initialize(event)
  938. elif event_class is DocumentStartEvent:
  939. version_directive = NULL
  940. if event_object.version:
  941. version_directive_value.major = event_object.version[0]
  942. version_directive_value.minor = event_object.version[1]
  943. version_directive = &version_directive_value
  944. tag_directives_start = NULL
  945. tag_directives_end = NULL
  946. if event_object.tags:
  947. if len(event_object.tags) > 128:
  948. raise ValueError(u"too many tags")
  949. tag_directives_start = tag_directives_value
  950. tag_directives_end = tag_directives_value
  951. cache = []
  952. for handle in event_object.tags:
  953. prefix = event_object.tags[handle]
  954. if PyUnicode_CheckExact(handle):
  955. handle = PyUnicode_AsUTF8String(handle)
  956. cache.append(handle)
  957. if not PyBytes_CheckExact(handle):
  958. raise TypeError(u"tag handle must be a string")
  959. tag_directives_end.handle = PyBytes_AS_Yaml_STRING(handle)
  960. if PyUnicode_CheckExact(prefix):
  961. prefix = PyUnicode_AsUTF8String(prefix)
  962. cache.append(prefix)
  963. if not PyBytes_CheckExact(prefix):
  964. raise TypeError(u"tag prefix must be a string")
  965. tag_directives_end.prefix = PyBytes_AS_Yaml_STRING(prefix)
  966. tag_directives_end = tag_directives_end+1
  967. implicit = 1
  968. if event_object.explicit:
  969. implicit = 0
  970. if yaml_document_start_event_initialize(event, version_directive,
  971. tag_directives_start, tag_directives_end, implicit) == 0:
  972. raise MemoryError
  973. elif event_class is DocumentEndEvent:
  974. implicit = 1
  975. if event_object.explicit:
  976. implicit = 0
  977. yaml_document_end_event_initialize(event, implicit)
  978. elif event_class is AliasEvent:
  979. anchor = NULL
  980. anchor_object = event_object.anchor
  981. if PyUnicode_CheckExact(anchor_object):
  982. anchor_object = PyUnicode_AsUTF8String(anchor_object)
  983. if not PyBytes_CheckExact(anchor_object):
  984. raise TypeError(u"anchor must be a string")
  985. anchor = PyBytes_AS_Yaml_STRING(anchor_object)
  986. if yaml_alias_event_initialize(event, anchor) == 0:
  987. raise MemoryError
  988. elif event_class is ScalarEvent:
  989. anchor = NULL
  990. anchor_object = event_object.anchor
  991. if anchor_object is not None:
  992. if PyUnicode_CheckExact(anchor_object):
  993. anchor_object = PyUnicode_AsUTF8String(anchor_object)
  994. if not PyBytes_CheckExact(anchor_object):
  995. raise TypeError(u"anchor must be a string")
  996. anchor = PyBytes_AS_Yaml_STRING(anchor_object)
  997. tag = NULL
  998. tag_object = event_object.tag
  999. if tag_object is not None:
  1000. if PyUnicode_CheckExact(tag_object):
  1001. tag_object = PyUnicode_AsUTF8String(tag_object)
  1002. if not PyBytes_CheckExact(tag_object):
  1003. raise TypeError(u"tag must be a string")
  1004. tag = PyBytes_AS_Yaml_STRING(tag_object)
  1005. value_object = event_object.value
  1006. if PyUnicode_CheckExact(value_object):
  1007. value_object = PyUnicode_AsUTF8String(value_object)
  1008. if not PyBytes_CheckExact(value_object):
  1009. raise TypeError(u"value must be a string")
  1010. value = PyBytes_AS_Yaml_STRING(value_object)
  1011. length = PyBytes_GET_SIZE(value_object)
  1012. plain_implicit = 0
  1013. quoted_implicit = 0
  1014. if event_object.implicit is not None:
  1015. plain_implicit = event_object.implicit[0]
  1016. quoted_implicit = event_object.implicit[1]
  1017. style_object = event_object.style
  1018. scalar_style = YAML_PLAIN_SCALAR_STYLE
  1019. if style_object == "'" or style_object == u"'":
  1020. scalar_style = YAML_SINGLE_QUOTED_SCALAR_STYLE
  1021. elif style_object == "\"" or style_object == u"\"":
  1022. scalar_style = YAML_DOUBLE_QUOTED_SCALAR_STYLE
  1023. elif style_object == "|" or style_object == u"|":
  1024. scalar_style = YAML_LITERAL_SCALAR_STYLE
  1025. elif style_object == ">" or style_object == u">":
  1026. scalar_style = YAML_FOLDED_SCALAR_STYLE
  1027. if yaml_scalar_event_initialize(event, anchor, tag, value, length,
  1028. plain_implicit, quoted_implicit, scalar_style) == 0:
  1029. raise MemoryError
  1030. elif event_class is SequenceStartEvent:
  1031. anchor = NULL
  1032. anchor_object = event_object.anchor
  1033. if anchor_object is not None:
  1034. if PyUnicode_CheckExact(anchor_object):
  1035. anchor_object = PyUnicode_AsUTF8String(anchor_object)
  1036. if not PyBytes_CheckExact(anchor_object):
  1037. raise TypeError(u"anchor must be a string")
  1038. anchor = PyBytes_AS_Yaml_STRING(anchor_object)
  1039. tag = NULL
  1040. tag_object = event_object.tag
  1041. if tag_object is not None:
  1042. if PyUnicode_CheckExact(tag_object):
  1043. tag_object = PyUnicode_AsUTF8String(tag_object)
  1044. if not PyBytes_CheckExact(tag_object):
  1045. raise TypeError(u"tag must be a string")
  1046. tag = PyBytes_AS_Yaml_STRING(tag_object)
  1047. implicit = 0
  1048. if event_object.implicit:
  1049. implicit = 1
  1050. sequence_style = YAML_BLOCK_SEQUENCE_STYLE
  1051. if event_object.flow_style:
  1052. sequence_style = YAML_FLOW_SEQUENCE_STYLE
  1053. if yaml_sequence_start_event_initialize(event, anchor, tag,
  1054. implicit, sequence_style) == 0:
  1055. raise MemoryError
  1056. elif event_class is MappingStartEvent:
  1057. anchor = NULL
  1058. anchor_object = event_object.anchor
  1059. if anchor_object is not None:
  1060. if PyUnicode_CheckExact(anchor_object):
  1061. anchor_object = PyUnicode_AsUTF8String(anchor_object)
  1062. if not PyBytes_CheckExact(anchor_object):
  1063. raise TypeError(u"anchor must be a string")
  1064. anchor = PyBytes_AS_Yaml_STRING(anchor_object)
  1065. tag = NULL
  1066. tag_object = event_object.tag
  1067. if tag_object is not None:
  1068. if PyUnicode_CheckExact(tag_object):
  1069. tag_object = PyUnicode_AsUTF8String(tag_object)
  1070. if not PyBytes_CheckExact(tag_object):
  1071. raise TypeError(u"tag must be a string")
  1072. tag = PyBytes_AS_Yaml_STRING(tag_object)
  1073. implicit = 0
  1074. if event_object.implicit:
  1075. implicit = 1
  1076. mapping_style = YAML_BLOCK_MAPPING_STYLE
  1077. if event_object.flow_style:
  1078. mapping_style = YAML_FLOW_MAPPING_STYLE
  1079. if yaml_mapping_start_event_initialize(event, anchor, tag,
  1080. implicit, mapping_style) == 0:
  1081. raise MemoryError
  1082. elif event_class is SequenceEndEvent:
  1083. yaml_sequence_end_event_initialize(event)
  1084. elif event_class is MappingEndEvent:
  1085. yaml_mapping_end_event_initialize(event)
  1086. else:
  1087. raise TypeError(u"invalid event %s" % event_object)
  1088. return 1
  1089. def emit(self, event_object):
  1090. cdef yaml_event_t event
  1091. self._object_to_event(event_object, &event)
  1092. if yaml_emitter_emit(&self.emitter, &event) == 0:
  1093. error = self._emitter_error()
  1094. raise error
  1095. def open(self):
  1096. cdef yaml_event_t event
  1097. cdef yaml_encoding_t encoding
  1098. if self.closed == -1:
  1099. if self.use_encoding == u'utf-16-le' or self.use_encoding == 'utf-16-le':
  1100. encoding = YAML_UTF16LE_ENCODING
  1101. elif self.use_encoding == u'utf-16-be' or self.use_encoding == 'utf-16-be':
  1102. encoding = YAML_UTF16BE_ENCODING
  1103. else:
  1104. encoding = YAML_UTF8_ENCODING
  1105. if self.use_encoding is None:
  1106. self.dump_unicode = 1
  1107. if self.dump_unicode == 1:
  1108. encoding = YAML_UTF8_ENCODING
  1109. yaml_stream_start_event_initialize(&event, encoding)
  1110. if yaml_emitter_emit(&self.emitter, &event) == 0:
  1111. error = self._emitter_error()
  1112. raise error
  1113. self.closed = 0
  1114. elif self.closed == 1:
  1115. raise SerializerError(u"serializer is closed")
  1116. else:
  1117. raise SerializerError(u"serializer is already opened")
  1118. def close(self):
  1119. cdef yaml_event_t event
  1120. if self.closed == -1:
  1121. raise SerializerError(u"serializer is not opened")
  1122. elif self.closed == 0:
  1123. yaml_stream_end_event_initialize(&event)
  1124. if yaml_emitter_emit(&self.emitter, &event) == 0:
  1125. error = self._emitter_error()
  1126. raise error
  1127. self.closed = 1
  1128. def serialize(self, node):
  1129. cdef yaml_event_t event
  1130. cdef yaml_version_directive_t version_directive_value
  1131. cdef yaml_version_directive_t *version_directive
  1132. cdef yaml_tag_directive_t tag_directives_value[128]
  1133. cdef yaml_tag_directive_t *tag_directives_start
  1134. cdef yaml_tag_directive_t *tag_directives_end
  1135. if self.closed == -1:
  1136. raise SerializerError(u"serializer is not opened")
  1137. elif self.closed == 1:
  1138. raise SerializerError(u"serializer is closed")
  1139. cache = []
  1140. version_directive = NULL
  1141. if self.use_version:
  1142. version_directive_value.major = self.use_version[0]
  1143. version_directive_value.minor = self.use_version[1]
  1144. version_directive = &version_directive_value
  1145. tag_directives_start = NULL
  1146. tag_directives_end = NULL
  1147. if self.use_tags:
  1148. if len(self.use_tags) > 128:
  1149. raise ValueError(u"too many tags")
  1150. tag_directives_start = tag_directives_value
  1151. tag_directives_end = tag_directives_value
  1152. for handle in self.use_tags:
  1153. prefix = self.use_tags[handle]
  1154. if PyUnicode_CheckExact(handle):
  1155. handle = PyUnicode_AsUTF8String(handle)
  1156. cache.append(handle)
  1157. if not PyBytes_CheckExact(handle):
  1158. raise TypeError(u"tag handle must be a string")
  1159. tag_directives_end.handle = PyBytes_AS_Yaml_STRING(handle)
  1160. if PyUnicode_CheckExact(prefix):
  1161. prefix = PyUnicode_AsUTF8String(prefix)
  1162. cache.append(prefix)
  1163. if not PyBytes_CheckExact(prefix):
  1164. raise TypeError(u"tag prefix must be a string")
  1165. tag_directives_end.prefix = PyBytes_AS_Yaml_STRING(prefix)
  1166. tag_directives_end = tag_directives_end+1
  1167. if yaml_document_start_event_initialize(&event, version_directive,
  1168. tag_directives_start, tag_directives_end,
  1169. self.document_start_implicit) == 0:
  1170. raise MemoryError
  1171. if yaml_emitter_emit(&self.emitter, &event) == 0:
  1172. error = self._emitter_error()
  1173. raise error
  1174. self._anchor_node(node)
  1175. self._serialize_node(node, None, None)
  1176. yaml_document_end_event_initialize(&event, self.document_end_implicit)
  1177. if yaml_emitter_emit(&self.emitter, &event) == 0:
  1178. error = self._emitter_error()
  1179. raise error
  1180. self.serialized_nodes = {}
  1181. self.anchors = {}
  1182. self.last_alias_id = 0
  1183. cdef int _anchor_node(self, object node) except 0:
  1184. if node in self.anchors:
  1185. if self.anchors[node] is None:
  1186. self.last_alias_id = self.last_alias_id+1
  1187. self.anchors[node] = u"id%03d" % self.last_alias_id
  1188. else:
  1189. self.anchors[node] = None
  1190. node_class = node.__class__
  1191. if node_class is SequenceNode:
  1192. for item in node.value:
  1193. self._anchor_node(item)
  1194. elif node_class is MappingNode:
  1195. for key, value in node.value:
  1196. self._anchor_node(key)
  1197. self._anchor_node(value)
  1198. return 1
  1199. cdef int _serialize_node(self, object node, object parent, object index) except 0:
  1200. cdef yaml_event_t event
  1201. cdef int implicit
  1202. cdef int plain_implicit
  1203. cdef int quoted_implicit
  1204. cdef yaml_char_t *anchor
  1205. cdef yaml_char_t *tag
  1206. cdef yaml_char_t *value
  1207. cdef int length
  1208. cdef int item_index
  1209. cdef yaml_scalar_style_t scalar_style
  1210. cdef yaml_sequence_style_t sequence_style
  1211. cdef yaml_mapping_style_t mapping_style
  1212. anchor_object = self.anchors[node]
  1213. anchor = NULL
  1214. if anchor_object is not None:
  1215. if PyUnicode_CheckExact(anchor_object):
  1216. anchor_object = PyUnicode_AsUTF8String(anchor_object)
  1217. if not PyBytes_CheckExact(anchor_object):
  1218. raise TypeError(u"anchor must be a string")
  1219. anchor = PyBytes_AS_Yaml_STRING(anchor_object)
  1220. if node in self.serialized_nodes:
  1221. if yaml_alias_event_initialize(&event, anchor) == 0:
  1222. raise MemoryError
  1223. if yaml_emitter_emit(&self.emitter, &event) == 0:
  1224. error = self._emitter_error()
  1225. raise error
  1226. else:
  1227. node_class = node.__class__
  1228. self.serialized_nodes[node] = True
  1229. self.descend_resolver(parent, index)
  1230. if node_class is ScalarNode:
  1231. plain_implicit = 0
  1232. quoted_implicit = 0
  1233. tag_object = node.tag
  1234. if self.resolve(ScalarNode, node.value, (True, False)) == tag_object:
  1235. plain_implicit = 1
  1236. if self.resolve(ScalarNode, node.value, (False, True)) == tag_object:
  1237. quoted_implicit = 1
  1238. tag = NULL
  1239. if tag_object is not None:
  1240. if PyUnicode_CheckExact(tag_object):
  1241. tag_object = PyUnicode_AsUTF8String(tag_object)
  1242. if not PyBytes_CheckExact(tag_object):
  1243. raise TypeError(u"tag must be a string")
  1244. tag = PyBytes_AS_Yaml_STRING(tag_object)
  1245. value_object = node.value
  1246. if PyUnicode_CheckExact(value_object):
  1247. value_object = PyUnicode_AsUTF8String(value_object)
  1248. if not PyBytes_CheckExact(value_object):
  1249. raise TypeError(u"value must be a string")
  1250. value = PyBytes_AS_Yaml_STRING(value_object)
  1251. length = PyBytes_GET_SIZE(value_object)
  1252. style_object = node.style
  1253. scalar_style = YAML_PLAIN_SCALAR_STYLE
  1254. if style_object == "'" or style_object == u"'":
  1255. scalar_style = YAML_SINGLE_QUOTED_SCALAR_STYLE
  1256. elif style_object == "\"" or style_object == u"\"":
  1257. scalar_style = YAML_DOUBLE_QUOTED_SCALAR_STYLE
  1258. elif style_object == "|" or style_object == u"|":
  1259. scalar_style = YAML_LITERAL_SCALAR_STYLE
  1260. elif style_object == ">" or style_object == u">":
  1261. scalar_style = YAML_FOLDED_SCALAR_STYLE
  1262. if yaml_scalar_event_initialize(&event, anchor, tag, value, length,
  1263. plain_implicit, quoted_implicit, scalar_style) == 0:
  1264. raise MemoryError
  1265. if yaml_emitter_emit(&self.emitter, &event) == 0:
  1266. error = self._emitter_error()
  1267. raise error
  1268. elif node_class is SequenceNode:
  1269. implicit = 0
  1270. tag_object = node.tag
  1271. if self.resolve(SequenceNode, node.value, True) == tag_object:
  1272. implicit = 1
  1273. tag = NULL
  1274. if tag_object is not None:
  1275. if PyUnicode_CheckExact(tag_object):
  1276. tag_object = PyUnicode_AsUTF8String(tag_object)
  1277. if not PyBytes_CheckExact(tag_object):
  1278. raise TypeError(u"tag must be a string")
  1279. tag = PyBytes_AS_Yaml_STRING(tag_object)
  1280. sequence_style = YAML_BLOCK_SEQUENCE_STYLE
  1281. if node.flow_style:
  1282. sequence_style = YAML_FLOW_SEQUENCE_STYLE
  1283. if yaml_sequence_start_event_initialize(&event, anchor, tag,
  1284. implicit, sequence_style) == 0:
  1285. raise MemoryError
  1286. if yaml_emitter_emit(&self.emitter, &event) == 0:
  1287. error = self._emitter_error()
  1288. raise error
  1289. item_index = 0
  1290. for item in node.value:
  1291. self._serialize_node(item, node, item_index)
  1292. item_index = item_index+1
  1293. yaml_sequence_end_event_initialize(&event)
  1294. if yaml_emitter_emit(&self.emitter, &event) == 0:
  1295. error = self._emitter_error()
  1296. raise error
  1297. elif node_class is MappingNode:
  1298. implicit = 0
  1299. tag_object = node.tag
  1300. if self.resolve(MappingNode, node.value, True) == tag_object:
  1301. implicit = 1
  1302. tag = NULL
  1303. if tag_object is not None:
  1304. if PyUnicode_CheckExact(tag_object):
  1305. tag_object = PyUnicode_AsUTF8String(tag_object)
  1306. if not PyBytes_CheckExact(tag_object):
  1307. raise TypeError(u"tag must be a string")
  1308. tag = PyBytes_AS_Yaml_STRING(tag_object)
  1309. mapping_style = YAML_BLOCK_MAPPING_STYLE
  1310. if node.flow_style:
  1311. mapping_style = YAML_FLOW_MAPPING_STYLE
  1312. if yaml_mapping_start_event_initialize(&event, anchor, tag,
  1313. implicit, mapping_style) == 0:
  1314. raise MemoryError
  1315. if yaml_emitter_emit(&self.emitter, &event) == 0:
  1316. error = self._emitter_error()
  1317. raise error
  1318. for item_key, item_value in node.value:
  1319. self._serialize_node(item_key, node, None)
  1320. self._serialize_node(item_value, node, item_key)
  1321. yaml_mapping_end_event_initialize(&event)
  1322. if yaml_emitter_emit(&self.emitter, &event) == 0:
  1323. error = self._emitter_error()
  1324. raise error
  1325. self.ascend_resolver()
  1326. return 1
  1327. cdef int output_handler(void *data, unsigned char *bufferu, size_t size) except 0:
  1328. cdef CEmitter emitter
  1329. cdef char *buffer
  1330. buffer = <char *>bufferu
  1331. emitter = <CEmitter>data
  1332. if emitter.dump_unicode == 0:
  1333. value = PyBytes_FromStringAndSize(buffer, size)
  1334. else:
  1335. value = PyUnicode_DecodeUTF8(buffer, size, 'strict')
  1336. emitter.stream.write(value)
  1337. return 1