selectolax 0.4.4__cp310-cp310-macosx_10_9_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
selectolax/__init__.py ADDED
@@ -0,0 +1,8 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+
4
+ __author__ = """Artem Golubin"""
5
+ __email__ = "me@rushter.com"
6
+ __version__ = "0.4.4"
7
+
8
+ from . import lexbor, modest, parser
selectolax/base.pxi ADDED
@@ -0,0 +1,4 @@
1
+
2
+ class SelectolaxError(Exception):
3
+ """An exception that indicates error."""
4
+ pass
@@ -0,0 +1,120 @@
1
+ cimport cython
2
+
3
+
4
+ @cython.final
5
+ cdef class LexborAttributes:
6
+ """A dict-like object that represents attributes."""
7
+ cdef lxb_dom_node_t *node
8
+ cdef unicode decode_errors
9
+
10
+ @staticmethod
11
+ cdef LexborAttributes create(lxb_dom_node_t *node):
12
+ obj = <LexborAttributes> LexborAttributes.__new__(LexborAttributes)
13
+ obj.node = node
14
+ return obj
15
+
16
+ def __iter__(self):
17
+ cdef lxb_dom_attr_t *attr = lxb_dom_element_first_attribute_noi(<lxb_dom_element_t *> self.node)
18
+ cdef size_t str_len = 0
19
+ attributes = dict()
20
+
21
+ while attr != NULL:
22
+ key = lxb_dom_attr_local_name_noi(attr, &str_len)
23
+ if key is not NULL:
24
+ yield key.decode(_ENCODING)
25
+ attr = attr.next
26
+
27
+ def __setitem__(self, str key, object value):
28
+ value = value
29
+ bytes_key = key.encode(_ENCODING)
30
+ bytes_value = value.encode(_ENCODING) if value else b""
31
+ cdef lxb_dom_attr_t *attr
32
+ cdef lxb_dom_document_t *doc
33
+
34
+ if value is None:
35
+ # N.B. This is suboptimal, but there is not API to set empty attributes
36
+ attr = lxb_dom_element_set_attribute(
37
+ <lxb_dom_element_t *> self.node,
38
+ <lxb_char_t *> bytes_key, len(bytes_key),
39
+ NULL, 0
40
+ )
41
+ doc = (<lxb_dom_node_t*>attr).owner_document
42
+ lexbor_str_destroy(attr.value, doc.text, 0)
43
+ attr.value = NULL
44
+
45
+ elif isinstance(value, str) or isinstance(value, unicode) :
46
+ lxb_dom_element_set_attribute(
47
+ <lxb_dom_element_t *> self.node,
48
+ <lxb_char_t *> bytes_key, len(bytes_key),
49
+ <lxb_char_t *> bytes_value, len(bytes_value),
50
+ )
51
+ else:
52
+ raise TypeError("Expected str or unicode, got %s" % type(value))
53
+
54
+ def __delitem__(self, key):
55
+ try:
56
+ self.__getitem__(key)
57
+ except KeyError:
58
+ raise KeyError(key)
59
+ bytes_key = key.encode(_ENCODING)
60
+ lxb_dom_element_remove_attribute(
61
+ <lxb_dom_element_t *> self.node,
62
+ <lxb_char_t *> bytes_key, len(bytes_key),
63
+ )
64
+
65
+ def __getitem__(self, str key):
66
+ bytes_key = key.encode(_ENCODING)
67
+ cdef lxb_dom_attr_t * attr = lxb_dom_element_attr_by_name(
68
+ <lxb_dom_element_t *> self.node,
69
+ <lxb_char_t *> bytes_key, len(bytes_key)
70
+ )
71
+ cdef size_t str_len = 0
72
+ if attr != NULL:
73
+ value = lxb_dom_attr_value_noi(attr, &str_len)
74
+ return value.decode(_ENCODING) if value else None
75
+ raise KeyError(key)
76
+
77
+ def __len__(self):
78
+ return len(list(self.__iter__()))
79
+
80
+ def keys(self):
81
+ return self.__iter__()
82
+
83
+ def items(self):
84
+ for key in self.__iter__():
85
+ yield key, self[key]
86
+
87
+ def values(self):
88
+ for key in self.__iter__():
89
+ yield self[key]
90
+
91
+ def get(self, key, default=None):
92
+ try:
93
+ return self[key]
94
+ except KeyError:
95
+ return default
96
+
97
+ def sget(self, key, default=""):
98
+ """Same as get, but returns empty strings instead of None values for empty attributes."""
99
+ try:
100
+ val = self[key]
101
+ if val is None:
102
+ val = ""
103
+ return val
104
+ except KeyError:
105
+ return default
106
+
107
+ def __contains__(self, key):
108
+ try:
109
+ self[key]
110
+ except KeyError:
111
+ return False
112
+ else:
113
+ return True
114
+
115
+ def __repr__(self):
116
+ cdef lxb_char_t *c_text
117
+ cdef size_t str_len = 0
118
+ c_text = lxb_dom_element_qualified_name(<lxb_dom_element_t *> self.node, &str_len)
119
+ tag_name = c_text.decode(_ENCODING, 'ignore') if c_text != NULL else 'unknown'
120
+ return "<%s attributes, %s items>" % (tag_name, len(self))