Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/soupsieve/__init__.py: 68%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""
2Soup Sieve.
4A CSS selector filter for BeautifulSoup4.
6MIT License
8Copyright (c) 2018 Isaac Muse
10Permission is hereby granted, free of charge, to any person obtaining a copy
11of this software and associated documentation files (the "Software"), to deal
12in the Software without restriction, including without limitation the rights
13to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14copies of the Software, and to permit persons to whom the Software is
15furnished to do so, subject to the following conditions:
17The above copyright notice and this permission notice shall be included in all
18copies or substantial portions of the Software.
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26SOFTWARE.
27"""
28from __future__ import annotations
29from .__meta__ import __version__, __version_info__ # noqa: F401
30from . import css_parser as cp
31from . import css_match as cm
32from . import css_types as ct
33from .util import DEBUG, NOCACHE, SelectorSyntaxError # noqa: F401
34import bs4
35from typing import Any, Iterator, Iterable
37__all__ = (
38 'DEBUG', 'NOCACHE', 'SelectorSyntaxError', 'SoupSieve',
39 'closest', 'compile', 'filter', 'iselect',
40 'match', 'select', 'select_one'
41)
43SoupSieve = cm.SoupSieve
46def compile( # noqa: A001
47 pattern: str,
48 namespaces: dict[str, str] | None = None,
49 flags: int = 0,
50 *,
51 custom: dict[str, str] | None = None,
52 ignore: Iterable[str] | None = None,
53 **kwargs: Any
54) -> cm.SoupSieve:
55 """Compile CSS pattern."""
57 if isinstance(pattern, SoupSieve):
58 if flags:
59 raise ValueError("Cannot process 'flags' argument on a compiled selector list")
60 elif namespaces is not None:
61 raise ValueError("Cannot process 'namespaces' argument on a compiled selector list")
62 elif custom is not None:
63 raise ValueError("Cannot process 'custom' argument on a compiled selector list")
64 return pattern
66 return cp._cached_css_compile(
67 pattern,
68 ct.Namespaces(namespaces) if namespaces is not None else namespaces,
69 ct.CustomSelectors(custom) if custom is not None else custom,
70 tuple(i.lower() for i in ignore) if ignore is not None else ignore,
71 flags,
72 )
75def purge() -> None:
76 """Purge cached patterns."""
78 cp._purge_cache()
81def closest(
82 select: str,
83 tag: bs4.Tag,
84 namespaces: dict[str, str] | None = None,
85 flags: int = 0,
86 *,
87 custom: dict[str, str] | None = None,
88 ignore: Iterable[str] | None = None,
89 **kwargs: Any
90) -> bs4.Tag | None:
91 """Match closest ancestor."""
93 return compile(select, namespaces, flags, custom=custom, ignore=ignore, **kwargs).closest(tag)
96def match(
97 select: str,
98 tag: bs4.Tag,
99 namespaces: dict[str, str] | None = None,
100 flags: int = 0,
101 *,
102 custom: dict[str, str] | None = None,
103 ignore: Iterable[str] | None = None,
104 **kwargs: Any
105) -> bool:
106 """Match node."""
108 return compile(select, namespaces, flags, custom=custom, ignore=ignore, **kwargs).match(tag)
111def filter( # noqa: A001
112 select: str,
113 iterable: Iterable[bs4.Tag],
114 namespaces: dict[str, str] | None = None,
115 flags: int = 0,
116 *,
117 custom: dict[str, str] | None = None,
118 ignore: Iterable[str] | None = None,
119 **kwargs: Any
120) -> list[bs4.Tag]:
121 """Filter list of nodes."""
123 return compile(select, namespaces, flags, custom=custom, ignore=ignore, **kwargs).filter(iterable)
126def select_one(
127 select: str,
128 tag: bs4.Tag,
129 namespaces: dict[str, str] | None = None,
130 flags: int = 0,
131 *,
132 custom: dict[str, str] | None = None,
133 ignore: Iterable[str] | None = None,
134 **kwargs: Any
135) -> bs4.Tag | None:
136 """Select a single tag."""
138 return compile(select, namespaces, flags, custom=custom, ignore=ignore, **kwargs).select_one(tag)
141def select(
142 select: str,
143 tag: bs4.Tag,
144 namespaces: dict[str, str] | None = None,
145 limit: int = 0,
146 flags: int = 0,
147 *,
148 custom: dict[str, str] | None = None,
149 ignore: Iterable[str] | None = None,
150 **kwargs: Any
151) -> list[bs4.Tag]:
152 """Select the specified tags."""
154 return compile(select, namespaces, flags, custom=custom, ignore=ignore, **kwargs).select(tag, limit)
157def iselect(
158 select: str,
159 tag: bs4.Tag,
160 namespaces: dict[str, str] | None = None,
161 limit: int = 0,
162 flags: int = 0,
163 *,
164 custom: dict[str, str] | None = None,
165 ignore: Iterable[str] | None = None,
166 **kwargs: Any
167) -> Iterator[bs4.Tag]:
168 """Iterate the specified tags."""
170 yield from compile(select, namespaces, flags, custom=custom, ignore=ignore, **kwargs).iselect(tag, limit)
173def escape(ident: str) -> str:
174 """Escape identifier."""
176 return cp.escape(ident)