selectolax 0.3.29__cp312-cp312-win32.whl → 0.4.0__cp312-cp312-win32.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.

Potentially problematic release.


This version of selectolax might be problematic. Click here for more details.

selectolax/parser.pyx CHANGED
@@ -1,5 +1,6 @@
1
1
 
2
- from cpython cimport bool
2
+ from cpython.bool cimport bool
3
+ from cpython.exc cimport PyErr_SetObject
3
4
 
4
5
  include "modest/selection.pxi"
5
6
  include "modest/node.pxi"
@@ -61,8 +62,7 @@ cdef class HTMLParser:
61
62
 
62
63
  """
63
64
 
64
- node = Node()
65
- node._init(self.html_tree.node_html, self)
65
+ cdef Node node = Node.new(self.html_tree.node_html, self)
66
66
  return node.css(query)
67
67
 
68
68
  def css_first(self, str query, default=None, strict=False):
@@ -72,9 +72,9 @@ cdef class HTMLParser:
72
72
  ----------
73
73
 
74
74
  query : str
75
- default : bool, default None
75
+ default : Any, default None
76
76
  Default value to return if there is no match.
77
- strict: bool, default True
77
+ strict: bool, default False
78
78
  Set to True if you want to check if there is strictly only one match in the document.
79
79
 
80
80
 
@@ -84,12 +84,11 @@ cdef class HTMLParser:
84
84
 
85
85
  """
86
86
 
87
- node = Node()
88
- node._init(self.html_tree.node_html, self)
87
+ cdef Node node = Node.new(self.html_tree.node_html, self)
89
88
  return node.css_first(query, default, strict)
90
89
 
91
90
  cdef void _detect_encoding(self, char* html, size_t html_len) nogil:
92
- cdef myencoding_t encoding = MyENCODING_DEFAULT;
91
+ cdef myencoding_t encoding = MyENCODING_DEFAULT
93
92
 
94
93
  if self.use_meta_tags:
95
94
  encoding = myencoding_prescan_stream_to_determine_encoding(html, html_len)
@@ -102,7 +101,7 @@ cdef class HTMLParser:
102
101
 
103
102
  self._encoding = encoding
104
103
 
105
- cdef _parse_html(self, char* html, size_t html_len):
104
+ cdef int _parse_html(self, char* html, size_t html_len) except -1:
106
105
  cdef myhtml_t* myhtml
107
106
  cdef mystatus_t status
108
107
 
@@ -111,23 +110,28 @@ cdef class HTMLParser:
111
110
  status = myhtml_init(myhtml, MyHTML_OPTIONS_DEFAULT, 1, 0)
112
111
 
113
112
  if status != 0:
114
- raise RuntimeError("Can't init MyHTML object.")
113
+ PyErr_SetObject(RuntimeError, "Can't init MyHTML object.")
114
+ return -1
115
115
 
116
116
  with nogil:
117
117
  self.html_tree = myhtml_tree_create()
118
118
  status = myhtml_tree_init(self.html_tree, myhtml)
119
119
 
120
120
  if status != 0:
121
- raise RuntimeError("Can't init MyHTML Tree object.")
121
+ PyErr_SetObject(RuntimeError, "Can't init MyHTML Tree object.")
122
+ return -1
122
123
 
123
124
  with nogil:
124
125
  status = myhtml_parse(self.html_tree, self._encoding, html, html_len)
125
126
 
126
127
  if status != 0:
127
- raise RuntimeError("Can't parse HTML:\n%s" % str(html))
128
-
129
- assert self.html_tree.node_html != NULL
128
+ PyErr_SetObject(RuntimeError, "Can't parse HTML (status code: %d)" % status)
129
+ return -1
130
130
 
131
+ if self.html_tree.node_html == NULL:
132
+ PyErr_SetObject(RuntimeError, "html_tree is still NULL even after parsing ")
133
+ return -1
134
+ return 0
131
135
 
132
136
  @property
133
137
  def input_encoding(self):
@@ -147,9 +151,11 @@ cdef class HTMLParser:
147
151
  def root(self):
148
152
  """Returns root node."""
149
153
  if self.html_tree and self.html_tree.node_html:
150
- node = Node()
151
- node._init(self.html_tree.node_html, self)
152
- return node
154
+ try:
155
+ return Node.new(self.html_tree.node_html, self)
156
+ except Exception:
157
+ # If Node creation or initialization fails, return None
158
+ return None
153
159
  return None
154
160
 
155
161
  @property
@@ -159,9 +165,7 @@ cdef class HTMLParser:
159
165
  head = myhtml_tree_get_node_head(self.html_tree)
160
166
 
161
167
  if head != NULL:
162
- node = Node()
163
- node._init(head, self)
164
- return node
168
+ return Node.new(head, self)
165
169
  return None
166
170
 
167
171
  @property
@@ -171,10 +175,7 @@ cdef class HTMLParser:
171
175
  body = myhtml_tree_get_node_body(self.html_tree)
172
176
 
173
177
  if body != NULL:
174
- node = Node()
175
- node._init(body, self)
176
- return node
177
-
178
+ return Node.new(body, self)
178
179
  return None
179
180
 
180
181
  def tags(self, str name):
@@ -185,9 +186,15 @@ cdef class HTMLParser:
185
186
  name : str (e.g. div)
186
187
 
187
188
  """
189
+ # Validate tag name
190
+ if not name:
191
+ raise ValueError("Tag name cannot be empty")
192
+ if len(name) > 100: # Reasonable limit for tag names
193
+ raise ValueError("Tag name is too long")
194
+
188
195
  cdef myhtml_collection_t* collection = NULL
189
196
  pybyte_name = name.encode('UTF-8')
190
- cdef mystatus_t status = 0;
197
+ cdef mystatus_t status = 0
191
198
 
192
199
  result = list()
193
200
  collection = myhtml_get_nodes_by_name(self.html_tree, NULL, pybyte_name, len(pybyte_name), &status)
@@ -197,8 +204,7 @@ cdef class HTMLParser:
197
204
 
198
205
  if status == 0:
199
206
  for i in range(collection.length):
200
- node = Node()
201
- node._init(collection.list[i], self)
207
+ node = Node.new(collection.list[i], self)
202
208
  result.append(node)
203
209
 
204
210
  myhtml_collection_destroy(collection)
@@ -248,7 +254,7 @@ cdef class HTMLParser:
248
254
  """
249
255
  cdef myhtml_collection_t* collection = NULL
250
256
 
251
- cdef mystatus_t status = 0;
257
+ cdef mystatus_t status = 0
252
258
 
253
259
  for tag in tags:
254
260
  pybyte_name = tag.encode('UTF-8')
@@ -268,7 +274,6 @@ cdef class HTMLParser:
268
274
 
269
275
  myhtml_collection_destroy(collection)
270
276
 
271
-
272
277
  def unwrap_tags(self, list tags, delete_empty : bool = False):
273
278
  """Unwraps specified tags from the HTML tree.
274
279
 
@@ -295,9 +300,9 @@ cdef class HTMLParser:
295
300
  @property
296
301
  def html(self):
297
302
  """Return HTML representation of the page."""
298
- if self.html_tree and self.html_tree.document:
299
- node = Node()
300
- node._init(self.html_tree.document, self)
303
+ cdef Node node
304
+ if self.html_tree != NULL and self.html_tree.document != NULL:
305
+ node = Node.new(self.html_tree.document, self)
301
306
  return node.html
302
307
  return None
303
308
 
@@ -351,6 +356,7 @@ cdef class HTMLParser:
351
356
 
352
357
  def css_matches(self, str selector):
353
358
  return self.root.css_matches(selector)
359
+
354
360
  def merge_text_nodes(self):
355
361
  """Iterates over all text nodes and merges all text nodes that are close to each other.
356
362
 
@@ -370,6 +376,7 @@ cdef class HTMLParser:
370
376
  "John Doe"
371
377
  """
372
378
  return self.root.merge_text_nodes()
379
+
373
380
  @staticmethod
374
381
  cdef HTMLParser from_tree(
375
382
  myhtml_tree_t * tree, bytes raw_html, bint detect_encoding, bint use_meta_tags, str decode_errors,
@@ -386,13 +393,13 @@ cdef class HTMLParser:
386
393
  obj.cached_script_srcs = None
387
394
  return obj
388
395
 
389
-
390
396
  def clone(self):
391
397
  """Clone the current tree."""
392
398
  cdef myhtml_t* myhtml
393
399
  cdef mystatus_t status
394
400
  cdef myhtml_tree_t* html_tree
395
401
  cdef myhtml_tree_node_t* node
402
+ cdef HTMLParser cls
396
403
 
397
404
  with nogil:
398
405
  myhtml = myhtml_create()
@@ -428,6 +435,7 @@ cdef class HTMLParser:
428
435
  if self.html_tree != NULL:
429
436
  myhtml = self.html_tree.myhtml
430
437
  myhtml_tree_destroy(self.html_tree)
438
+ self.html_tree = NULL # Prevent double-free
431
439
  if myhtml != NULL:
432
440
  myhtml_destroy(myhtml)
433
441
 
selectolax/utils.pxi CHANGED
@@ -4,6 +4,16 @@ MAX_HTML_INPUT_SIZE = 250e+7
4
4
 
5
5
  ParserCls = Union[Type["HTMLParser"], Type["LexborHTMLParser"]]
6
6
  Parser = Union["HTMLParser", "LexborHTMLParser"]
7
+ FRAGMENT = Literal[
8
+ "document",
9
+ "fragment",
10
+ "head",
11
+ "body",
12
+ "head_and_body",
13
+ "document_no_head",
14
+ "document_no_body",
15
+ "document_no_head_no_body",
16
+ ]
7
17
 
8
18
 
9
19
  def preprocess_input(html, decode_errors='ignore'):
@@ -29,10 +39,10 @@ def get_fragment_type(
29
39
  html: str,
30
40
  parser_cls: ParserCls,
31
41
  tree: Optional[Parser] = None,
32
- ) -> Literal["document", "fragment", "head", "body", "head_and_body", "document_no_head", "document_no_body", "document_no_head_no_body"]:
42
+ ) -> FRAGMENT:
33
43
  if not tree:
34
44
  tree = parser_cls(html)
35
-
45
+
36
46
  import re
37
47
  html_re = re.compile(r"<html|<body|<head(?!er)", re.IGNORECASE)
38
48
 
@@ -49,7 +59,7 @@ def get_fragment_type(
49
59
 
50
60
  if has_html and has_head and has_body:
51
61
  break
52
-
62
+
53
63
  if has_html and has_head and has_body:
54
64
  return "document"
55
65
  elif has_html and not has_head and has_body:
@@ -0,0 +1,32 @@
1
+ Metadata-Version: 2.4
2
+ Name: selectolax
3
+ Version: 0.4.0
4
+ Summary: Fast HTML5 parser with CSS selectors.
5
+ Home-page: https://github.com/rushter/selectolax
6
+ Author: Artem Golubin
7
+ Author-email: Artem Golubin <me@rushter.com>
8
+ License-Expression: MIT
9
+ Project-URL: Repository, https://github.com/rushter/selectolax
10
+ Project-URL: Documentation, https://selectolax.readthedocs.io/en/latest/parser.html
11
+ Project-URL: Changelog, https://github.com/rushter/selectolax/blob/master/CHANGES.md
12
+ Keywords: selectolax,html,parser,css,fast
13
+ Classifier: Development Status :: 5 - Production/Stable
14
+ Classifier: Topic :: Text Processing :: Markup :: HTML
15
+ Classifier: Topic :: Internet
16
+ Classifier: Topic :: Internet :: WWW/HTTP
17
+ Classifier: Intended Audience :: Developers
18
+ Classifier: Natural Language :: English
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3.9
21
+ Classifier: Programming Language :: Python :: 3.10
22
+ Classifier: Programming Language :: Python :: 3.11
23
+ Classifier: Programming Language :: Python :: 3.12
24
+ Classifier: Programming Language :: Python :: 3.13
25
+ Requires-Python: >=3.9
26
+ Description-Content-Type: text/x-rst
27
+ License-File: LICENSE
28
+ Provides-Extra: cython
29
+ Requires-Dist: Cython; extra == "cython"
30
+ Dynamic: author
31
+ Dynamic: home-page
32
+ Dynamic: license-file
@@ -0,0 +1,27 @@
1
+ selectolax/__init__.py,sha256=-050n6lsikxxW1ZltsXOBwrx_z-ULnFcxLZ0xTjoJQg,156
2
+ selectolax/base.pxi,sha256=zOj3BrCA71xd-mJFtkMIAglP4ZybfrHVoCoy6ljTBDQ,93
3
+ selectolax/lexbor.c,sha256=ITeSHYPEi6FvXCjJj6ruZJ0cB4Z5BwBSmASVsgigYjk,2501237
4
+ selectolax/lexbor.cp312-win32.pyd,sha256=AFUJXYuvzPR4iLLebToYIEqlpCy7WjgcfQ0zVWEP060,2655232
5
+ selectolax/lexbor.pxd,sha256=jZugG2ClrbWzJohWWeqblIVmbvFHkbX5WB-Wvc8tkn4,22236
6
+ selectolax/lexbor.pyi,sha256=hu1HMzR3mWfraGM-XNyiX3eHU_xljVEPg0AoRF27a_w,31046
7
+ selectolax/lexbor.pyx,sha256=P5Q3it_Apj3rFhywvpSlcZXofOhuq9upHzbOAEDBcuA,13892
8
+ selectolax/parser.c,sha256=gWdDUJkfF1K75R15HA17AWaV0JF2jSXM5zYEa2WWVIk,2260668
9
+ selectolax/parser.cp312-win32.pyd,sha256=p3DyvxJ8Iq-gGQE82N81MP9cvktqa0P_eZmim8uf1Gc,1477120
10
+ selectolax/parser.pxd,sha256=T7GoQdaOkhp_W2TBlRY0tZqom97PkHrytYaXQlyVnbI,25196
11
+ selectolax/parser.pyi,sha256=wO1pkE5efgtWLGt0ULEqHEZ_XyxcBy_YWzFZmU5mJdQ,25699
12
+ selectolax/parser.pyx,sha256=wy6GHgv__oa5gt1kQYGJGNc4cwVIU1NdJUJ8O4FKqmI,14127
13
+ selectolax/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
+ selectolax/utils.pxi,sha256=hkzKfycdpwH1P-E_pP-9NTGsmiajt6EJNZSlkxlRapA,3623
15
+ selectolax/lexbor/attrs.pxi,sha256=d59V77aGkpp7YsYsd6t_z4-tRnUoQTJZKsvMC8nyttM,3978
16
+ selectolax/lexbor/node.pxi,sha256=98M-9bRzKfnbHn0-vT1v3fSUrXqojpPK2yK4FI2BEJk,36345
17
+ selectolax/lexbor/node_remove.pxi,sha256=6h7KwWCxkLWtl71VROlLDA6EukHK745iyKK-uNw78fI,789
18
+ selectolax/lexbor/selection.pxi,sha256=H2-oPgLAEBwhwXMmk_-49YKah5z5hGgwBK0gciQtBak,8245
19
+ selectolax/lexbor/util.pxi,sha256=q2EYVNdnROg9y30mWpGwlNA0W00nJ7ZRNEEDrOEG14s,584
20
+ selectolax/modest/node.pxi,sha256=M52G3TlJrHIErR8CLqIXWUjSlNSCanjSJ9aFKn1p74Y,34777
21
+ selectolax/modest/selection.pxi,sha256=PfHUN1uuNA7YfcxTu7JZjhxevVbFRP1bHd3kyyFdO7E,6703
22
+ selectolax/modest/util.pxi,sha256=zab67Wzo8FcipA2VS8ClptaC19lZirbNqFEGQ3hW2Is,572
23
+ selectolax-0.4.0.dist-info/licenses/LICENSE,sha256=A7Jb3WZcENcLfZRc7QPdm9zJdwfpIyPodPJu-kdMH6E,1087
24
+ selectolax-0.4.0.dist-info/METADATA,sha256=tbBfJ2_fHMj95Pm8aazPr0U2Jvon511S9bn5FKDMWSs,1319
25
+ selectolax-0.4.0.dist-info/WHEEL,sha256=LwxTQZ0gyDP_uaeNCLm-ZIktY9hv6x0e22Q-hgFd-po,97
26
+ selectolax-0.4.0.dist-info/top_level.txt,sha256=e5MuEM2PrQzoDlWetkFli9uXSlxa_ktW5jJEihhaI1c,11
27
+ selectolax-0.4.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.0.1)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: false
4
4
  Tag: cp312-cp312-win32
5
5
 
@@ -1,194 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: selectolax
3
- Version: 0.3.29
4
- Summary: Fast HTML5 parser with CSS selectors.
5
- Home-page: https://github.com/rushter/selectolax
6
- Author: Artem Golubin
7
- Author-email: me@rushter.com
8
- License: MIT license
9
- Project-URL: Source code, https://github.com/rushter/selectolax
10
- Keywords: selectolax
11
- Classifier: Development Status :: 5 - Production/Stable
12
- Classifier: Topic :: Text Processing :: Markup :: HTML
13
- Classifier: Topic :: Internet
14
- Classifier: Topic :: Internet :: WWW/HTTP
15
- Classifier: Intended Audience :: Developers
16
- Classifier: License :: OSI Approved :: MIT License
17
- Classifier: Natural Language :: English
18
- Classifier: Programming Language :: Python :: 3
19
- Classifier: Programming Language :: Python :: 3.7
20
- Classifier: Programming Language :: Python :: 3.8
21
- Classifier: Programming Language :: Python :: 3.9
22
- Classifier: Programming Language :: Python :: 3.10
23
- Classifier: Programming Language :: Python :: 3.11
24
- Classifier: Programming Language :: Python :: 3.12
25
- Classifier: Programming Language :: Python :: 3.13
26
- License-File: LICENSE
27
- Provides-Extra: cython
28
- Requires-Dist: Cython==3.0.11; extra == "cython"
29
- Dynamic: author
30
- Dynamic: author-email
31
- Dynamic: classifier
32
- Dynamic: description
33
- Dynamic: home-page
34
- Dynamic: keywords
35
- Dynamic: license
36
- Dynamic: license-file
37
- Dynamic: project-url
38
- Dynamic: provides-extra
39
- Dynamic: summary
40
-
41
- .. image:: docs/logo.png
42
- :alt: selectolax logo
43
-
44
- -------------------------
45
-
46
- .. image:: https://img.shields.io/pypi/v/selectolax.svg
47
- :target: https://pypi.python.org/pypi/selectolax
48
-
49
- A fast HTML5 parser with CSS selectors using `Modest <https://github.com/lexborisov/Modest/>`_ and
50
- `Lexbor <https://github.com/lexbor/lexbor>`_ engines.
51
-
52
-
53
- Installation
54
- ------------
55
- From PyPI using pip:
56
-
57
- .. code-block:: bash
58
-
59
- pip install selectolax
60
-
61
- If installation fails due to compilation errors, you may need to install `Cython <https://github.com/cython/cython>`_:
62
-
63
- .. code-block:: bash
64
-
65
- pip install selectolax[cython]
66
-
67
- This usually happens when you try to install an outdated version of selectolax on a newer version of Python.
68
-
69
-
70
- Development version from GitHub:
71
-
72
- .. code-block:: bash
73
-
74
- git clone --recursive https://github.com/rushter/selectolax
75
- cd selectolax
76
- pip install -r requirements_dev.txt
77
- python setup.py install
78
-
79
- How to compile selectolax while developing:
80
-
81
- .. code-block:: bash
82
-
83
- make clean
84
- make dev
85
-
86
- Basic examples
87
- --------------
88
-
89
- Here are some basic examples to get you started with selectolax:
90
-
91
- Parsing HTML and extracting text:
92
-
93
- .. code:: python
94
-
95
- In [1]: from selectolax.parser import HTMLParser
96
- ...:
97
- ...: html = """
98
- ...: <h1 id="title" data-updated="20201101">Hi there</h1>
99
- ...: <div class="post">Lorem Ipsum is simply dummy text of the printing and typesetting industry. </div>
100
- ...: <div class="post">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</div>
101
- ...: """
102
- ...: tree = HTMLParser(html)
103
-
104
- In [2]: tree.css_first('h1#title').text()
105
- Out[2]: 'Hi there'
106
-
107
- In [3]: tree.css_first('h1#title').attributes
108
- Out[3]: {'id': 'title', 'data-updated': '20201101'}
109
-
110
- In [4]: [node.text() for node in tree.css('.post')]
111
- Out[4]:
112
- ['Lorem Ipsum is simply dummy text of the printing and typesetting industry. ',
113
- 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.']
114
-
115
- Using advanced CSS selectors:
116
-
117
- .. code:: python
118
-
119
- In [1]: html = "<div><p id=p1><p id=p2><p id=p3><a>link</a><p id=p4><p id=p5>text<p id=p6></div>"
120
- ...: selector = "div > :nth-child(2n+1):not(:has(a))"
121
-
122
- In [2]: for node in HTMLParser(html).css(selector):
123
- ...: print(node.attributes, node.text(), node.tag)
124
- ...: print(node.parent.tag)
125
- ...: print(node.html)
126
- ...:
127
- {'id': 'p1'} p
128
- div
129
- <p id="p1"></p>
130
- {'id': 'p5'} text p
131
- div
132
- <p id="p5">text</p>
133
-
134
-
135
- * `Detailed overview <https://github.com/rushter/selectolax/blob/master/examples/walkthrough.ipynb>`_
136
-
137
- Available backends
138
- ------------------
139
-
140
- Selectolax supports two backends: ``Modest`` and ``Lexbor``. By default, all examples use the Modest backend.
141
- Most of the features between backends are almost identical, but there are still some differences.
142
-
143
- As of 2024, the preferred backend is ``Lexbor``. The ``Modest`` backend is still available for compatibility reasons
144
- and the underlying C library that selectolax uses is not maintained anymore.
145
-
146
-
147
- To use ``lexbor``, just import the parser and use it in the similar way to the `HTMLParser`.
148
-
149
- .. code:: python
150
-
151
- In [1]: from selectolax.lexbor import LexborHTMLParser
152
-
153
- In [2]: html = """
154
- ...: <title>Hi there</title>
155
- ...: <div id="updated">2021-08-15</div>
156
- ...: """
157
-
158
- In [3]: parser = LexborHTMLParser(html)
159
- In [4]: parser.root.css_first("#updated").text()
160
- Out[4]: '2021-08-15'
161
-
162
-
163
- Simple Benchmark
164
- ----------------
165
-
166
- * Extract title, links, scripts and a meta tag from main pages of top 754 domains. See ``examples/benchmark.py`` for more information.
167
-
168
- ============================ ===========
169
- Package Time
170
- ============================ ===========
171
- Beautiful Soup (html.parser) 61.02 sec.
172
- lxml / Beautiful Soup (lxml) 9.09 sec.
173
- html5_parser 16.10 sec.
174
- selectolax (Modest) 2.94 sec.
175
- selectolax (Lexbor) 2.39 sec.
176
- ============================ ===========
177
-
178
- Links
179
- -----
180
-
181
- * `selectolax API reference <http://selectolax.readthedocs.io/en/latest/parser.html>`_
182
- * `Video introduction to web scraping using selectolax <https://youtu.be/HpRsfpPuUzE>`_
183
- * `How to Scrape 7k Products with Python using selectolax and httpx <https://www.youtube.com/watch?v=XpGvq755J2U>`_
184
- * `Detailed overview <https://github.com/rushter/selectolax/blob/master/examples/walkthrough.ipynb>`_
185
- * `Modest introduction <https://lexborisov.github.io/Modest/>`_
186
- * `Modest benchmark <http://lexborisov.github.io/benchmark-html-persers/>`_
187
- * `Python benchmark <https://rushter.com/blog/python-fast-html-parser/>`_
188
- * `Another Python benchmark <https://www.peterbe.com/plog/selectolax-or-pyquery>`_
189
-
190
- License
191
- -------
192
-
193
- * Modest engine — `LGPL2.1 <https://github.com/lexborisov/Modest/blob/master/LICENSE>`_
194
- * selectolax - `MIT <https://github.com/rushter/selectolax/blob/master/LICENSE>`_
@@ -1,26 +0,0 @@
1
- selectolax/__init__.py,sha256=EJMTWQiycBDUJq3c6zs6gPVxNbcNCHfynjXd42bZWeA,185
2
- selectolax/base.pxi,sha256=zOj3BrCA71xd-mJFtkMIAglP4ZybfrHVoCoy6ljTBDQ,93
3
- selectolax/lexbor.c,sha256=MGAIgra4f3fjLWOb7R_VNeroUdk7D1WlkQ06uQ8D7D0,2368851
4
- selectolax/lexbor.cp312-win32.pyd,sha256=IJaK_3ExECZFcPN6Mxqb30v0xsJKj_WSWxpbY6Zw_Nw,2661888
5
- selectolax/lexbor.pxd,sha256=1d9nvZd9rZl27gwPwVV5BlbR2LAi6jDK69Xm9Guz5Kk,21538
6
- selectolax/lexbor.pyi,sha256=IeGh8NEcvybAHWxgh_-rHV9oxKjkdeWb9QUtgjBH12M,6782
7
- selectolax/lexbor.pyx,sha256=6nvezEKHO5ffieso6jr0vYss8V0WkVup9NocJoVepuo,11353
8
- selectolax/parser.c,sha256=9FirqHRzfMS3U67DKJk0YJ5x7HdEqOpmFAQnJskv_MM,2224906
9
- selectolax/parser.cp312-win32.pyd,sha256=RdcZdIXL-x9mkgf_iXsrr_tu-pt5FjxwTdx0Zk-f49s,1508352
10
- selectolax/parser.pxd,sha256=4pM_CcZlvJlaR8EMjZCnSmnCcJbwcYOldRTBEbfwm48,25145
11
- selectolax/parser.pyi,sha256=jFQa0_av9w9HT4XtbJioI86Le0N_Wvbc7BFbdPqDuHM,11598
12
- selectolax/parser.pyx,sha256=CeZDNHF6G1RhUv2TfihZmCVMkGUwMhy6zrsffB1p7hE,13528
13
- selectolax/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
- selectolax/utils.pxi,sha256=4rtdRcLWuemxN1qe7Eul5jvAmHZ65r7Gvf67_Wg8Bt4,3566
15
- selectolax/lexbor/attrs.pxi,sha256=r9DroDAkoxIvSMiDTRKpfYp503b7yUteDoYwglhQ0FM,3241
16
- selectolax/lexbor/node.pxi,sha256=Kr5Oi3eQdxplTt8ltG1eWjFfHFrdcgsm5YYJnKFJDK8,30763
17
- selectolax/lexbor/selection.pxi,sha256=DVtVnaCwzXPPkDqgW0vEtkQa1zWJ0c2Ud3KGSrvK5PM,6755
18
- selectolax/lexbor/util.pxi,sha256=0I4ElWIwXxrZCfMmGCtyDU127oMsPCqC3IcUk4QmMAc,582
19
- selectolax/modest/node.pxi,sha256=FP2_09dUKxK-z-j_A9hw98WwvBZFGvtifA2YYKbKpbU,34300
20
- selectolax/modest/selection.pxi,sha256=0elY7JwnpPVaw0QZE1T7A78s9FIph5uWIhwy4sEXGU8,6586
21
- selectolax/modest/util.pxi,sha256=o2nPGGGtRlLqOCa7yPk94CfBzNlVr7ull7osFy6NRX4,570
22
- selectolax-0.3.29.dist-info/licenses/LICENSE,sha256=A7Jb3WZcENcLfZRc7QPdm9zJdwfpIyPodPJu-kdMH6E,1087
23
- selectolax-0.3.29.dist-info/METADATA,sha256=wwLeEm4lfcwdZ58hApe0sxokMPTPsk4rnO16d2tPZBU,6471
24
- selectolax-0.3.29.dist-info/WHEEL,sha256=i_mAMKEyQNMsJTllODhqxu4gwSczQiHeyo3ZjgICPYA,97
25
- selectolax-0.3.29.dist-info/top_level.txt,sha256=e5MuEM2PrQzoDlWetkFli9uXSlxa_ktW5jJEihhaI1c,11
26
- selectolax-0.3.29.dist-info/RECORD,,