123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- """
- Soup Sieve.
- A CSS selector filter for BeautifulSoup4.
- MIT License
- Copyright (c) 2018 Isaac Muse
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
- """
- from .__meta__ import __version__, __version_info__ # noqa: F401
- from . import css_parser as cp
- from . import css_match as cm
- from . import css_types as ct
- from .util import DEBUG, SelectorSyntaxError # noqa: F401
- import bs4 # type: ignore[import]
- from typing import Dict, Optional, Any, List, Iterator, Iterable
- __all__ = (
- 'DEBUG', 'SelectorSyntaxError', 'SoupSieve',
- 'closest', 'compile', 'filter', 'iselect',
- 'match', 'select', 'select_one'
- )
- SoupSieve = cm.SoupSieve
- def compile( # noqa: A001
- pattern: str,
- namespaces: Optional[Dict[str, str]] = None,
- flags: int = 0,
- *,
- custom: Optional[Dict[str, str]] = None,
- **kwargs: Any
- ) -> cm.SoupSieve:
- """Compile CSS pattern."""
- ns = ct.Namespaces(namespaces) if namespaces is not None else namespaces # type: Optional[ct.Namespaces]
- cs = ct.CustomSelectors(custom) if custom is not None else custom # type: Optional[ct.CustomSelectors]
- if isinstance(pattern, SoupSieve):
- if flags:
- raise ValueError("Cannot process 'flags' argument on a compiled selector list")
- elif namespaces is not None:
- raise ValueError("Cannot process 'namespaces' argument on a compiled selector list")
- elif custom is not None:
- raise ValueError("Cannot process 'custom' argument on a compiled selector list")
- return pattern
- return cp._cached_css_compile(pattern, ns, cs, flags)
- def purge() -> None:
- """Purge cached patterns."""
- cp._purge_cache()
- def closest(
- select: str,
- tag: 'bs4.Tag',
- namespaces: Optional[Dict[str, str]] = None,
- flags: int = 0,
- *,
- custom: Optional[Dict[str, str]] = None,
- **kwargs: Any
- ) -> 'bs4.Tag':
- """Match closest ancestor."""
- return compile(select, namespaces, flags, **kwargs).closest(tag)
- def match(
- select: str,
- tag: 'bs4.Tag',
- namespaces: Optional[Dict[str, str]] = None,
- flags: int = 0,
- *,
- custom: Optional[Dict[str, str]] = None,
- **kwargs: Any
- ) -> bool:
- """Match node."""
- return compile(select, namespaces, flags, **kwargs).match(tag)
- def filter( # noqa: A001
- select: str,
- iterable: Iterable['bs4.Tag'],
- namespaces: Optional[Dict[str, str]] = None,
- flags: int = 0,
- *,
- custom: Optional[Dict[str, str]] = None,
- **kwargs: Any
- ) -> List['bs4.Tag']:
- """Filter list of nodes."""
- return compile(select, namespaces, flags, **kwargs).filter(iterable)
- def select_one(
- select: str,
- tag: 'bs4.Tag',
- namespaces: Optional[Dict[str, str]] = None,
- flags: int = 0,
- *,
- custom: Optional[Dict[str, str]] = None,
- **kwargs: Any
- ) -> 'bs4.Tag':
- """Select a single tag."""
- return compile(select, namespaces, flags, **kwargs).select_one(tag)
- def select(
- select: str,
- tag: 'bs4.Tag',
- namespaces: Optional[Dict[str, str]] = None,
- limit: int = 0,
- flags: int = 0,
- *,
- custom: Optional[Dict[str, str]] = None,
- **kwargs: Any
- ) -> List['bs4.Tag']:
- """Select the specified tags."""
- return compile(select, namespaces, flags, **kwargs).select(tag, limit)
- def iselect(
- select: str,
- tag: 'bs4.Tag',
- namespaces: Optional[Dict[str, str]] = None,
- limit: int = 0,
- flags: int = 0,
- *,
- custom: Optional[Dict[str, str]] = None,
- **kwargs: Any
- ) -> Iterator['bs4.Tag']:
- """Iterate the specified tags."""
- for el in compile(select, namespaces, flags, **kwargs).iselect(tag, limit):
- yield el
- def escape(ident: str) -> str:
- """Escape identifier."""
- return cp.escape(ident)
|