Skip to content

pyroid.filters

datatrove 0.10.1's quality filters in Rust, with the same decisions (pyroid.filters).

GopherQualityFilter, GopherRepetitionFilter, C4QualityFilter and FineWebQualityFilter keep and drop the same documents as datatrove, give the same filter_reason strings, and leave the same text after C4's line removal. Parameters have datatrove's names and defaults; pass them as keyword arguments, as a config object (GopherQuality etc.), or pass a datatrove filter instance, whose settings are read.

  • Predicates (gopher_quality ...) return a keep mask in the caller's kind.
  • *_reasons return datatrove's reason per document, None when kept (null in an Arrow column, as are null inputs).
  • c4_lines is C4's line removal as a transform: each document's doc.text after the filter (unchanged and dropped documents come back as the original objects).
  • apply chains filters as datatrove's executor does (the first drop wins and C4's rewritten text is what later filters see), in one pass with one shared tokenization.

Words and languages

datatrove splits text with the word tokenizer of the filter's language (load_word_tokenizer(language); the default "eng" is spaCy 3.8.18's spacy.blank("en") plus the sentencizer). language takes any of datatrove's 4,343 codes ("deu_Latn", "deu", "de", ...; languages lists them), as datatrove does:

  • Native (4,049 codes with a Japanese dictionary and PyThaiNLP installed; 4,029 without PyThaiNLP, 4,045 without the dictionary, 4,025 without either), in Rust on every thread:

  • the 3,742 codes datatrove tokenizes with a rule-based spacy.blank(code): the 57 spaCy languages af ... yo, including xx (spaCy's multi-language tokenizer, which datatrove assigns to 1,995 codes such as "uzn_Latn"). pyroid ports spaCy's prefix, suffix, infix and URL rules, each language's tokenizer exceptions, the special-case matcher and the sentencizer;

  • the 129 codes of IndicNLPTokenizer ("hin_Deva", "ben_Beng", "urd_Arab", ...: indic-nlp-library's trivial_tokenize and sentence_split);
  • the 128 codes of WhitespaceTokenizer ("kat_Geor", ...: spaCy xx words and datatrove's regex sentence splitter);
  • the 10 codes of SpaCyTokenizer("zh") ("cmn_Hani", "yue_Hani", ...: spaCy's Chinese tokenizer over jieba 0.42.1 with its default dictionary, ported as pyroid.jieba, plus the sentencizer);
  • the 4 codes of SpaCyTokenizer("ja") ("jpn_Jpan", ...: datatrove's Japanese tokenizer, SudachiPy 0.7.0 in split mode A, ported to Rust, plus the sentencizer), when a SudachiDict dictionary is installed. pyroid does not ship one (it is about 200 MB): it reads the system.dic of an installed sudachidict-core (pip install sudachidict-core, the dictionary datatrove uses), or the file PYROID_SUDACHI_DICT names, once per process, the first time a filter needs it. Without one, these codes take the Python-tokenizer path below. One error differs in type: where SudachiPy's input limit stops datatrove (a 40,000-byte chunk whose normalization passes 65,535 bytes), datatrove raises sudachipy.errors.SudachiError, which is not a ValueError; pyroid raises ValueError with the same message.
  • the 16 codes of SpaCyTokenizer("vi") ("vie_Latn", ...: spaCy's Vietnamese tokenizer with pyvi 0.1.1, its CRF model ported to Rust and bundled, plus the sentencizer);
  • the 20 codes of ThaiTokenizer ("tha_Thai", ...: PyThaiNLP 5.4.0's newmm-safe words and crfcut sentences, ported to Rust), when PyThaiNLP is installed. pyroid reads its word list and sentence model (corpus/words_th.txt, corpus/sentenceseg_crfcut.model) from the installed pythainlp (pip install pythainlp, which datatrove's Thai tokenizer needs anyway), or from the directory PYROID_PYTHAINLP_CORPUS names, once per process. Without it, these codes take the Python-tokenizer path below. split_into_words and split_into_sentences match datatrove's.
  • Python tokenizer, opt-in (the other 294 codes): datatrove uses a segmenter pyroid does not port: StanzaTokenizer (255 codes), BurmeseTokenizer, TibetanTokenizer, LaoTokenizer, KhmerTokenizer and KiwiTokenizer (see languages). Calling a filter with such a code raises NotImplementedError unless you pass python_tokenizer=True. Then each document is tokenized by datatrove's own tokenizer, in Python, on the calling thread. This needs datatrove 0.10.1 and the segmenter installed (pyroid.PyroidError says what is missing). The filter math runs in Rust on those words, so the decisions are datatrove's.

This path runs at the reference tokenizer's speed, since tokenization dominates the filters' cost. It only tokenizes the documents that reach a word-based check, and emits one pyroid.FallbackWarning per function and language (C4 steps, which run as datatrove's own filter, emit their own). python_tokenizer=True also works for native codes, where it uses datatrove's tokenizer: slower, and no more exact. It is only needed for the others. - language may also be a word tokenizer object, as datatrove allows: a datatrove WordTokenizer instance, or any object with word_tokenize(text) (and span_tokenize(text) for C4). It is called in Python as above, and needs no python_tokenizer=True. - A code datatrove does not know raises datatrove's ValueError, when the call starts.

On the Python-tokenizer path, a C4Quality step (which splits sentences with the tokenizer) runs as datatrove's own C4QualityFilter; in apply, later steps then see (and tokenize) its rewritten text, as in a datatrove pipeline.

Python's str semantics (isalpha, isspace, splitlines, lower, the re digit and word classes) follow the running interpreter's Unicode version (14.0 to 17.0, CPython 3.11 to 3.15), as datatrove's do.

Differences from datatrove

  • A top_n_grams / dup_n_grams size below 1 raises ValueError (datatrove loops forever on dup_n_grams sizes below 1).
  • Values are checked when the call starts. A non-number threshold raises TypeError, and an unknown language ValueError, before any document is filtered; datatrove raises the latter at the first document that needs words.
  • A failing document raises for the whole batch, and the exception names the document.
  • exclusion_writer is not supported (use the *_reasons functions).
  • A document with a token that is exactly IS_ALPHA (e.g. in "IS_ALPHA.", not in "xIS_ALPHA") is tokenized like any other text, as datatrove does the first time in a process. After that, spaCy fails on such documents (its string store maps IS_ALPHA to id 1, which is its hash map's deleted-key marker), and datatrove re-tokenizes text.replace("IS_ALPHA", "") instead, or raises if that still has the token. So datatrove's words for these documents depend on what it saw before; pyroid's do not.

DATATROVE_VERSION module-attribute

DATATROVE_VERSION: Final[str]

STOP_WORDS module-attribute

STOP_WORDS: Final[tuple[str, ...]]

PII_EMAIL_REPLACEMENT module-attribute

PII_EMAIL_REPLACEMENT: Final[tuple[str, ...]]

PIIFormatter's default email_replacement.

PII_IP_REPLACEMENT module-attribute

PII_IP_REPLACEMENT: Final[tuple[str, ...]]

PIIFormatter's default ip_replacement (addresses that did not answer pings).

C4_BADWORDS_LANGUAGES module-attribute

C4_BADWORDS_LANGUAGES: Final[tuple[str, ...]]

The 28 languages datatrove 0.10.1 has a word list for (_BADWORDS_LANGS).

TLDEXTRACT_VERSION module-attribute

TLDEXTRACT_VERSION: Final[str]

GopherQuality

Bases: NamedTuple

GopherQualityFilter's parameters and defaults.

A falsy threshold (None, 0) disables its check, as in datatrove. stop_words=None means STOP_WORDS.

min_doc_words class-attribute instance-attribute

min_doc_words: float | None = 50

max_doc_words class-attribute instance-attribute

max_doc_words: float | None = 100000

min_avg_word_length class-attribute instance-attribute

min_avg_word_length: float | None = 3

max_avg_word_length class-attribute instance-attribute

max_avg_word_length: float | None = 10

max_symbol_word_ratio class-attribute instance-attribute

max_symbol_word_ratio: float | None = 0.1

max_bullet_lines_ratio class-attribute instance-attribute

max_bullet_lines_ratio: float | None = 0.9

max_ellipsis_lines_ratio class-attribute instance-attribute

max_ellipsis_lines_ratio: float | None = 0.3

max_non_alpha_words_ratio class-attribute instance-attribute

max_non_alpha_words_ratio: float | None = 0.8

min_stop_words class-attribute instance-attribute

min_stop_words: float | None = 2

stop_words class-attribute instance-attribute

stop_words: Iterable[str] | None = None

language class-attribute instance-attribute

language: str | _WordTokenizer = 'eng'

GopherRepetition

Bases: NamedTuple

GopherRepetitionFilter's parameters and defaults.

A falsy fraction disables its check. top_n_grams and dup_n_grams are (n, max_fraction) pairs, n >= 1.

dup_line_frac class-attribute instance-attribute

dup_line_frac: float | None = 0.3

dup_para_frac class-attribute instance-attribute

dup_para_frac: float | None = 0.3

dup_line_char_frac class-attribute instance-attribute

dup_line_char_frac: float | None = 0.2

dup_para_char_frac class-attribute instance-attribute

dup_para_char_frac: float | None = 0.2

top_n_grams class-attribute instance-attribute

top_n_grams: Sequence[tuple[int, float]] = ...

dup_n_grams class-attribute instance-attribute

dup_n_grams: Sequence[tuple[int, float]] = ...

language class-attribute instance-attribute

language: str | _WordTokenizer = 'eng'

C4Quality

Bases: NamedTuple

C4QualityFilter's parameters and defaults.

-1 disables min_num_sentences, min_words_per_line or max_word_length. split_paragraph=False filters sentences instead of lines (and joins the kept ones with spaces).

split_paragraph class-attribute instance-attribute

split_paragraph: bool = True

remove_citations class-attribute instance-attribute

remove_citations: bool = True

filter_no_terminal_punct class-attribute instance-attribute

filter_no_terminal_punct: bool = True

min_num_sentences class-attribute instance-attribute

min_num_sentences: int = 5

min_words_per_line class-attribute instance-attribute

min_words_per_line: int = 3

max_word_length class-attribute instance-attribute

max_word_length: int = 1000

filter_lorem_ipsum class-attribute instance-attribute

filter_lorem_ipsum: bool = True

filter_javascript class-attribute instance-attribute

filter_javascript: bool = True

filter_curly_bracket class-attribute instance-attribute

filter_curly_bracket: bool = True

filter_policy class-attribute instance-attribute

filter_policy: bool = True

language class-attribute instance-attribute

language: str | _SentenceTokenizer = 'eng'

FineWebQuality

Bases: NamedTuple

FineWebQualityFilter's parameters and defaults.

stop_chars=None means datatrove's TERMINAL_PUNCTUATION.

line_punct_thr class-attribute instance-attribute

line_punct_thr: float = 0.12

line_punct_exclude_zero class-attribute instance-attribute

line_punct_exclude_zero: bool = False

stop_chars class-attribute instance-attribute

stop_chars: str | Iterable[str] | None = None

short_line_thr class-attribute instance-attribute

short_line_thr: float = 0.67

short_line_length class-attribute instance-attribute

short_line_length: int = 30

char_duplicates_ratio class-attribute instance-attribute

char_duplicates_ratio: float = 0.01

new_line_ratio class-attribute instance-attribute

new_line_ratio: float = 0.3

language class-attribute instance-attribute

language: str | _WordTokenizer = 'eng'

FilterResult

Bases: NamedTuple

What apply returns, each in the caller's container kind.

keep instance-attribute

keep: Any

Keep mask (as the predicates return).

reason instance-attribute

reason: Any

Drop reason per document, None when kept (as *_reasons).

text instance-attribute

text: Any

Each document's text after the chain (as c4_lines).

Language

Bases: NamedTuple

How datatrove 0.10.1 tokenizes one language code (an entry of languages).

tokenizer instance-attribute

tokenizer: str

datatrove's tokenizer class: "SpaCyTokenizer", "StanzaTokenizer", "IndicNLPTokenizer", "WhitespaceTokenizer", "KiwiTokenizer", ...

arg instance-attribute

arg: str

The argument it is built with (a spaCy, Stanza or Indic NLP language code), or "".

native instance-attribute

native: bool

pyroid tokenizes this code natively; if not, it needs python_tokenizer=True.

PII

Bases: NamedTuple

PIIFormatter's parameters and defaults.

Attributes:

remove_emails class-attribute instance-attribute

remove_emails: bool = True

remove_ips class-attribute instance-attribute

remove_ips: bool = True

only_remove_public_ips class-attribute instance-attribute

only_remove_public_ips: bool = True

email_replacement class-attribute instance-attribute

email_replacement: tuple[str, ...] | str = ...

ip_replacement class-attribute instance-attribute

ip_replacement: tuple[str, ...] | str = ...

PIIReplacer

PIIReplacer(
    config: PII | None = None,
    /,
    **kwargs: Unpack[_PIIKwargs],
)

datatrove's PIIFormatter, keeping its state across calls.

Each call rewrites a batch of documents exactly as PIIFormatter.format would, one after another: every match of datatrove's email regex becomes the next email replacement, then, in that text, every match of its IPv4 regex that ipaddress.ip_address accepts (and, by default, calls is_global) becomes the next IP replacement. "Next" cycles through each replacement tuple and carries over from one document, and one call, to the next, so feeding a corpus batch by batch gives datatrove's output.

The matches are found and replaced in Rust, in parallel; the calling thread numbers the replacements and asks ipaddress about each distinct address once.

Attributes:

  • config (PII) –

    The PII settings.

  • email_index (int) –

    Index of the next email replacement (datatrove's emails_replacer._replace_i); assignable.

  • ip_index (int) –

    The same for IP replacements (ip_replacer._replace_i).

A formatter whose counters start at 0.

Parameters:

  • config (PII | None, default: None ) –

    A PII; keyword arguments override its fields.

  • **kwargs (Unpack[_PIIKwargs], default: {} ) –

    PIIFormatter's parameters.

Raises:

config instance-attribute

config: PII

email_index instance-attribute

email_index: int

ip_index instance-attribute

ip_index: int

__call__

__call__(
    texts: str, /, *, threads: int | None = None
) -> str
__call__(
    texts: list[str], /, *, threads: int | None = None
) -> list[str]
__call__(
    texts: tuple[str, ...], /, *, threads: int | None = None
) -> tuple[str, ...]
__call__(
    texts: ArrowStrings, /, *, threads: int | None = None
) -> Column[str]

Rewrite each document; unchanged documents come back as the same objects.

Parameters:

  • texts (str | list[str] | tuple[str, ...] | ArrowStrings) –

    A str, a list or tuple of str, or an Arrow string array/column.

  • threads (int | None, default: None ) –

    None uses pyroid's shared thread pool; n runs at most n tasks at once; 1 runs on the calling thread.

Returns:

  • str | list[str] | tuple[str, ...] | Column[str] –

    The texts in the caller's kind (a pyroid.Column of strings for Arrow input; nulls stay null).

Raises:

C4BadWords

Bases: NamedTuple

C4BadWordsFilter's parameters and defaults (exclusion_writer aside).

Attributes:

  • keep_fraction (float) –

    The fraction of documents with bad words to keep anyway, decided per document by numpy.random.default_rng(seed).uniform().

  • fail_on_missing_language (bool) –

    Raise for a language without a list (else keep its documents).

  • seed (int | None) –

    default_rng's seed: a non-negative int, or None for fresh OS entropy (as numpy).

  • default_language (str) –

    The language of documents given none.

keep_fraction class-attribute instance-attribute

keep_fraction: float = 0.0

fail_on_missing_language class-attribute instance-attribute

fail_on_missing_language: bool = True

seed class-attribute instance-attribute

seed: int | None = None

default_language class-attribute instance-attribute

default_language: str = 'en'

BadWordsResult

Bases: NamedTuple

What a BadWordsFilter call returns, each in the caller's container kind.

keep instance-attribute

keep: Any

True for each kept document.

reason instance-attribute

reason: Any

"document_removed_with_badwords" for each dropped document, else None.

BadWordsFilter

BadWordsFilter(
    config: C4BadWords | None = None,
    /,
    *,
    words: Mapping[str, Iterable[str]] | None = None,
    cache_dir: str | PathLike[str] | None = None,
    download: bool = True,
    **kwargs: Unpack[_C4BadWordsKwargs],
)

datatrove's C4BadWordsFilter, keeping its random state across calls.

A document is dropped when doc.text.lower() contains a word of its language's list, flanked by non-word characters (re's \W) or the text's ends (ja, th and zh words match anywhere), unless keep_fraction > 0 and the next uniform() draw of numpy's default_rng(seed) is below it. The draws are numpy's PCG64 stream, bit for bit, one per flagged document in document order, continuing across calls (rng_state). The search runs in Rust, in parallel.

Attributes:

A filter whose generator is default_rng(seed).

Parameters:

  • config (C4BadWords | None, default: None ) –

    A C4BadWords; keyword arguments override its fields.

  • words (Mapping[str, Iterable[str]] | None, default: None ) –

    Word lists to use instead of datatrove's, by language (any language code; matched literally, not lowercased). Languages not given are loaded with load_c4_badwords when first needed.

  • cache_dir (str | PathLike[str] | None, default: None ) –
  • download (bool, default: True ) –
  • **kwargs (Unpack[_C4BadWordsKwargs], default: {} ) –

    C4BadWordsFilter's parameters.

Raises:

config instance-attribute

config: C4BadWords

rng_state instance-attribute

rng_state: tuple[int, int]

__call__

__call__(
    texts: Any,
    /,
    *,
    languages: _Languages = None,
    threads: int | None = None,
) -> BadWordsResult

Filter texts: keep mask and drop reasons from one pass.

Parameters:

  • texts (Any) –

    A str, a list or tuple of str, or an Arrow string array/column.

  • languages (_Languages, default: None ) –

    Each document's language (datatrove's doc.metadata["language"]): one str for all, or one entry per document (None: the default). Default: default_language.

  • threads (int | None, default: None ) –

    None uses pyroid's shared thread pool; n runs at most n tasks at once; 1 runs on the calling thread.

Returns:

  • BadWordsResult –

    BadWordsResult(keep, reason) in the caller's kind (Arrow nulls stay null).

Raises:

  • ValueError –

    A language has no list and fail_on_missing_language (datatrove's message), or languages has the wrong length.

  • OSError –

    A list could not be downloaded.

  • InputError –

    texts is not one of the accepted kinds.

  • UnicodeEncodeError –

    A str contains a lone surrogate.

  • UnicodeDecodeError –

    An Arrow row is not valid UTF-8.

keep

keep(
    texts: str,
    /,
    *,
    languages: _Languages = None,
    threads: int | None = None,
) -> bool
keep(
    texts: list[str],
    /,
    *,
    languages: _Languages = None,
    threads: int | None = None,
) -> list[bool]
keep(
    texts: tuple[str, ...],
    /,
    *,
    languages: _Languages = None,
    threads: int | None = None,
) -> tuple[bool, ...]
keep(
    texts: ArrowStrings,
    /,
    *,
    languages: _Languages = None,
    threads: int | None = None,
) -> Column[bool]

The keep mask only (draws as __call__).

reasons

reasons(
    texts: str,
    /,
    *,
    languages: _Languages = None,
    threads: int | None = None,
) -> str | None
reasons(
    texts: list[str],
    /,
    *,
    languages: _Languages = None,
    threads: int | None = None,
) -> list[str | None]
reasons(
    texts: tuple[str, ...],
    /,
    *,
    languages: _Languages = None,
    threads: int | None = None,
) -> tuple[str | None, ...]
reasons(
    texts: ArrowStrings,
    /,
    *,
    languages: _Languages = None,
    threads: int | None = None,
) -> Column[str]

The drop reasons only (draws as __call__).

found

found(
    texts: str,
    /,
    *,
    languages: _Languages = None,
    threads: int | None = None,
) -> bool
found(
    texts: list[str],
    /,
    *,
    languages: _Languages = None,
    threads: int | None = None,
) -> list[bool]
found(
    texts: tuple[str, ...],
    /,
    *,
    languages: _Languages = None,
    threads: int | None = None,
) -> tuple[bool, ...]
found(
    texts: ArrowStrings,
    /,
    *,
    languages: _Languages = None,
    threads: int | None = None,
) -> Column[bool]

Whether each document contains a bad word (no draws; missing lists give False).

URLFilterConfig

Bases: NamedTuple

datatrove 0.10.1 URLFilter's parameters and defaults.

The lists are read as datatrove's parse_list reads them: entries starting with # are skipped (the test is x[0] != "#", so an empty string raises IndexError, as in datatrove); domains and URLs are strip()-ped; words, subwords and soft words are normalized (every character but [a-zA-Z0-9] removed, then lowercased), so "--" becomes "". A falsy list adds nothing.

soft_word_threshold class-attribute instance-attribute

soft_word_threshold: Any = 2

extra_domains class-attribute instance-attribute

extra_domains: Iterable[str] | None = None

extra_urls class-attribute instance-attribute

extra_urls: Iterable[str] | None = None

banned_words class-attribute instance-attribute

banned_words: Iterable[str] | None = None

banned_subwords class-attribute instance-attribute

banned_subwords: Iterable[str] | None = None

soft_banned_words class-attribute instance-attribute

soft_banned_words: Iterable[str] | None = None

use_integrated_lists class-attribute instance-attribute

use_integrated_lists: bool = True

DatatroveURLLists

Bases: NamedTuple

The files of datatrove's integrated URL block lists (see datatrove_url_lists).

domains instance-attribute

domains: str

urls instance-attribute

urls: str

banned_words instance-attribute

banned_words: str

banned_subwords instance-attribute

banned_subwords: str

soft_banned_words instance-attribute

soft_banned_words: str

URLFilter

URLFilter(
    config: URLFilterConfig | None = None,
    /,
    *,
    tld_extractor: Any = None,
    **kwargs: Unpack[_URLFilterKwargs],
)

datatrove 0.10.1's URLFilter, built once: the same decisions and drop reasons.

Build it once and reuse it: with the integrated lists it holds 4.56 million blocked domains (about 200 MB, in one Rust string arena with a hash table), and building it takes a second or two. Each URL is checked as datatrove does, in its order, and the first hit is the reason:

  1. "domain": tldextract's registered domain (top_domain_under_public_suffix) is a blocked domain;
  2. "subdomain": its FQDN is a blocked domain;
  3. "url": the URL itself is blocked;
  4. "hard_blacklisted": a word of re.split(r"[^a-zA-Z0-9]+", url) (case sensitive; "" when the URL starts or ends with another character) is a banned word;
  5. "soft_blacklisted": at least soft_word_threshold distinct words are soft-banned;
  6. "blacklisted_subword": a banned subword is a substring of the URL with every character but [a-zA-Z0-9] removed, lowercased.

Domains come from tldextract 5.4.0's extract_str, ported to Rust: lenient_netloc (scheme, userinfo, [IPv6], port, strip(), trailing dots), U+3002, U+FF0E and U+FF61 as dots, the IPv6 literal test (ipaddress.IPv6Address), and the Public Suffix List walk (wildcards such as *.ck, exceptions such as !www.ck), labels lowered with str.lower() of the running interpreter's Unicode version and xn-- labels decoded as idna does. The suffix lists are the ones tld_extractor uses (its cached copy of the Public Suffix List, or tldextract's bundled snapshot), read from it when the filter is built; with its include_psl_private_domains setting.

Parameters:

  • config (URLFilterConfig | None, default: None ) –

    A URLFilterConfig; keyword arguments override its fields.

  • tld_extractor (Any, default: None ) –

    A tldextract.TLDExtract (default: a new TLDExtract(), as datatrove builds).

  • **kwargs (Unpack[_URLFilterKwargs], default: {} ) –

    URLFilter's parameters (see URLFilterConfig).

Raises:

  • TypeError –

    config is not a URLFilterConfig, or soft_word_threshold does not compare with an int (datatrove raises this TypeError at the first URL that reaches the soft-word check).

  • IndexError –

    A list has an empty string (as datatrove).

  • PyroidError –

    tldextract is not installed, or use_integrated_lists=True and datatrove is not installed.

The methods take URLs as a str, a list or tuple of str, or an Arrow string array/column, with threads= as everywhere in pyroid, and raise ValueError for an empty URL (datatrove's assert url), AttributeError as datatrove when the banned subwords are only "" (pyahocorasick's automaton then has no words) and a URL reaches that check, pyroid.InputError for other input kinds, UnicodeEncodeError for a lone surrogate and UnicodeDecodeError for invalid UTF-8 in Arrow input.

config instance-attribute

config: URLFilterConfig | None

tld_extractor property

tld_extractor: Any

The tldextract.TLDExtract whose suffix lists are used.

num_domains property

num_domains: int

Number of blocked domains.

num_urls property

num_urls: int

Number of blocked URLs.

keep

keep(urls: str, /, *, threads: int | None = None) -> bool
keep(
    urls: list[str], /, *, threads: int | None = None
) -> list[bool]
keep(
    urls: tuple[str, ...], /, *, threads: int | None = None
) -> tuple[bool, ...]
keep(
    urls: ArrowStrings, /, *, threads: int | None = None
) -> Column[bool]

True for each URL datatrove keeps.

Returns:

  • bool | list[bool] | tuple[bool, ...] | Column[bool] –

    bool, list[bool], tuple[bool, ...], or a pyroid.Column of bools (nulls stay null), matching urls.

reasons

reasons(
    urls: str, /, *, threads: int | None = None
) -> str | None
reasons(
    urls: list[str], /, *, threads: int | None = None
) -> list[str | None]
reasons(
    urls: tuple[str, ...], /, *, threads: int | None = None
) -> tuple[str | None, ...]
reasons(
    urls: ArrowStrings, /, *, threads: int | None = None
) -> Column[str]

The drop reason (datatrove's) per URL, None when kept.

Reasons: domain, subdomain, url, hard_blacklisted, soft_blacklisted, blacklisted_subword. Arrow input gives a string pyroid.Column (null when kept or null).

domains

domains(
    urls: str, /, *, threads: int | None = None
) -> tuple[str, str]
domains(
    urls: list[str], /, *, threads: int | None = None
) -> tuple[list[str], list[str]]
domains(
    urls: tuple[str, ...], /, *, threads: int | None = None
) -> tuple[tuple[str, ...], tuple[str, ...]]
domains(
    urls: ArrowStrings, /, *, threads: int | None = None
) -> tuple[Column[str], Column[str]]

The (top_domain_under_public_suffix, fqdn) tldextract gives each URL.

What datatrove looks up in the blocked domains (registered_domain is top_domain_under_public_suffix). Both are "" for IP addresses, hosts without a public suffix, and bare suffixes.

Returns:

  • tuple[str, str] | tuple[list[str], list[str]] | tuple[tuple[str, ...], tuple[str, ...]] | tuple[Column[str], Column[str]] –

    A pair, each in the kind of urls (Arrow: large_string columns for large_string input, else string; nulls stay null).

SymbolLines

Bases: NamedTuple

SymbolLinesFormatter's parameters and defaults.

Attributes:

  • symbols_to_remove (Iterable[str] | None) –

    The symbols a removed line may consist of (with " "); None is datatrove's PUNCTUATION_SET.

  • replace_char (str) –

    What a run of removed lines becomes ("": nothing; FineWeb-2 uses "\n").

symbols_to_remove class-attribute instance-attribute

symbols_to_remove: Iterable[str] | None = None

replace_char class-attribute instance-attribute

replace_char: str = ''

gopher_quality

gopher_quality(
    texts: str,
    config: GopherQuality | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_GopherQualityKwargs],
) -> bool
gopher_quality(
    texts: list[str],
    config: GopherQuality | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_GopherQualityKwargs],
) -> list[bool]
gopher_quality(
    texts: tuple[str, ...],
    config: GopherQuality | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_GopherQualityKwargs],
) -> tuple[bool, ...]
gopher_quality(
    texts: ArrowStrings,
    config: GopherQuality | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_GopherQualityKwargs],
) -> Column[bool]

GopherQualityFilter: True for each document datatrove keeps.

Parameters:

  • texts (str | list[str] | tuple[str, ...] | ArrowStrings) –

    A str, a list or tuple of str, or an Arrow string array/column (string, large_string or string_view).

  • config (GopherQuality | None, default: None ) –

    A GopherQuality (or a datatrove GopherQualityFilter); keyword arguments override its fields.

  • threads (int | None, default: None ) –

    None uses pyroid's shared thread pool; n runs at most n tasks at once; 1 runs on the calling thread. On the Python-tokenizer path it applies to the Rust part only.

  • python_tokenizer (bool, default: False ) –

    Tokenize with datatrove's own tokenizer for language, in Python on the calling thread, and run the filter math in Rust on its words (see "Words and languages" above). Needed for the languages pyroid does not tokenize natively; emits pyroid.FallbackWarning once per function and language.

  • **kwargs (Unpack[_GopherQualityKwargs], default: {} ) –

    GopherQualityFilter's parameters (language: a datatrove language code or a word tokenizer object).

Returns:

  • bool | list[bool] | tuple[bool, ...] | Column[bool] –

    bool, list[bool], tuple[bool, ...], or a pyroid.Column of bools (nulls stay null), matching texts.

Raises:

  • InputError –

    texts is not one of the accepted kinds.

  • TypeError –

    A parameter has the wrong type.

  • ValueError –

    datatrove has no tokenizer for language (datatrove's message), or a document of 2**30 characters or more (spaCy's limit).

  • NotImplementedError –

    pyroid does not tokenize language natively and python_tokenizer is not set (the message names datatrove's tokenizer and what to install).

  • PyroidError –

    The Python-tokenizer path needs datatrove or the tokenizer's package, and it is not installed.

  • ZeroDivisionError –

    As datatrove, e.g. min_doc_words=None and a document without words.

  • UnicodeEncodeError –

    A str contains a lone surrogate.

  • UnicodeDecodeError –

    An Arrow row is not valid UTF-8.

gopher_quality_reasons

gopher_quality_reasons(
    texts: str,
    config: GopherQuality | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_GopherQualityKwargs],
) -> str | None
gopher_quality_reasons(
    texts: list[str],
    config: GopherQuality | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_GopherQualityKwargs],
) -> list[str | None]
gopher_quality_reasons(
    texts: tuple[str, ...],
    config: GopherQuality | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_GopherQualityKwargs],
) -> tuple[str | None, ...]
gopher_quality_reasons(
    texts: ArrowStrings,
    config: GopherQuality | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_GopherQualityKwargs],
) -> Column[str]

GopherQualityFilter: datatrove's drop reason, None when kept.

Reasons: gopher_short_doc, gopher_long_doc, gopher_below_avg_threshold, gopher_above_avg_threshold, gopher_too_many_hashes, gopher_too_many_ellipsis, gopher_too_many_bullets, gopher_too_many_end_ellipsis, gopher_below_alpha_threshold, gopher_enough_stop_words. Arguments and errors as for gopher_quality; Arrow input gives a string pyroid.Column (null when kept or null).

gopher_repetition

gopher_repetition(
    texts: str,
    config: GopherRepetition | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_GopherRepetitionKwargs],
) -> bool
gopher_repetition(
    texts: list[str],
    config: GopherRepetition | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_GopherRepetitionKwargs],
) -> list[bool]
gopher_repetition(
    texts: tuple[str, ...],
    config: GopherRepetition | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_GopherRepetitionKwargs],
) -> tuple[bool, ...]
gopher_repetition(
    texts: ArrowStrings,
    config: GopherRepetition | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_GopherRepetitionKwargs],
) -> Column[bool]

GopherRepetitionFilter: True for each document datatrove keeps.

Arguments, returns and errors as for gopher_quality, with GopherRepetition / GopherRepetitionFilter parameters.

gopher_repetition_reasons

gopher_repetition_reasons(
    texts: str,
    config: GopherRepetition | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_GopherRepetitionKwargs],
) -> str | None
gopher_repetition_reasons(
    texts: list[str],
    config: GopherRepetition | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_GopherRepetitionKwargs],
) -> list[str | None]
gopher_repetition_reasons(
    texts: tuple[str, ...],
    config: GopherRepetition | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_GopherRepetitionKwargs],
) -> tuple[str | None, ...]
gopher_repetition_reasons(
    texts: ArrowStrings,
    config: GopherRepetition | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_GopherRepetitionKwargs],
) -> Column[str]

GopherRepetitionFilter: datatrove's drop reason, None when kept.

Reasons: empty, dup_para_frac, dup_para_char_frac, dup_line_frac, dup_line_char_frac, top_{n}_gram, duplicated_{n}_n_grams.

c4_quality

c4_quality(
    texts: str,
    config: C4Quality | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_C4QualityKwargs],
) -> bool
c4_quality(
    texts: list[str],
    config: C4Quality | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_C4QualityKwargs],
) -> list[bool]
c4_quality(
    texts: tuple[str, ...],
    config: C4Quality | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_C4QualityKwargs],
) -> tuple[bool, ...]
c4_quality(
    texts: ArrowStrings,
    config: C4Quality | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_C4QualityKwargs],
) -> Column[bool]

C4QualityFilter's document decision: True for each document kept.

Arguments, returns and errors as for gopher_quality, with C4Quality / C4QualityFilter parameters. The text after line removal is c4_lines.

c4_quality_reasons

c4_quality_reasons(
    texts: str,
    config: C4Quality | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_C4QualityKwargs],
) -> str | None
c4_quality_reasons(
    texts: list[str],
    config: C4Quality | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_C4QualityKwargs],
) -> list[str | None]
c4_quality_reasons(
    texts: tuple[str, ...],
    config: C4Quality | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_C4QualityKwargs],
) -> tuple[str | None, ...]
c4_quality_reasons(
    texts: ArrowStrings,
    config: C4Quality | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_C4QualityKwargs],
) -> Column[str]

C4QualityFilter: datatrove's drop reason, None when kept.

Reasons: lorem_ipsum, curly_bracket, too_few_sentences.

c4_lines

c4_lines(
    texts: str,
    config: C4Quality | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_C4QualityKwargs],
) -> str
c4_lines(
    texts: list[str],
    config: C4Quality | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_C4QualityKwargs],
) -> list[str]
c4_lines(
    texts: tuple[str, ...],
    config: C4Quality | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_C4QualityKwargs],
) -> tuple[str, ...]
c4_lines(
    texts: ArrowStrings,
    config: C4Quality | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_C4QualityKwargs],
) -> Column[str]

C4QualityFilter's line removal: doc.text after the filter.

For a kept document, the lines (or sentences) C4 keeps, stripped and re-joined, citations removed; for a dropped one, the input (datatrove leaves it untouched). Unchanged documents are the original objects; Arrow nulls stay null.

Returns:

  • str | list[str] | tuple[str, ...] | Column[str] –

    str, list, tuple, or a pyroid.Column of strings (large_string for large_string input), matching texts.

fineweb_quality

fineweb_quality(
    texts: str,
    config: FineWebQuality | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_FineWebQualityKwargs],
) -> bool
fineweb_quality(
    texts: list[str],
    config: FineWebQuality | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_FineWebQualityKwargs],
) -> list[bool]
fineweb_quality(
    texts: tuple[str, ...],
    config: FineWebQuality | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_FineWebQualityKwargs],
) -> tuple[bool, ...]
fineweb_quality(
    texts: ArrowStrings,
    config: FineWebQuality | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_FineWebQualityKwargs],
) -> Column[bool]

FineWebQualityFilter: True for each document datatrove keeps.

Arguments, returns and errors as for gopher_quality, with FineWebQuality / FineWebQualityFilter parameters.

fineweb_quality_reasons

fineweb_quality_reasons(
    texts: str,
    config: FineWebQuality | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_FineWebQualityKwargs],
) -> str | None
fineweb_quality_reasons(
    texts: list[str],
    config: FineWebQuality | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_FineWebQualityKwargs],
) -> list[str | None]
fineweb_quality_reasons(
    texts: tuple[str, ...],
    config: FineWebQuality | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_FineWebQualityKwargs],
) -> tuple[str | None, ...]
fineweb_quality_reasons(
    texts: ArrowStrings,
    config: FineWebQuality | None = None,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
    **kwargs: Unpack[_FineWebQualityKwargs],
) -> Column[str]

FineWebQualityFilter: datatrove's drop reason, None when kept.

Reasons: empty, line_punct_ratio, short_line_ratio, char_dup_ratio, list_ratio.

apply

apply(
    texts: str | list[str] | tuple[str, ...] | ArrowStrings,
    filters: Iterable[
        GopherQuality
        | GopherRepetition
        | C4Quality
        | FineWebQuality
        | Any
    ]
    | GopherQuality
    | GopherRepetition
    | C4Quality
    | FineWebQuality,
    /,
    *,
    threads: int | None = None,
    python_tokenizer: bool = False,
) -> FilterResult

Run several filters in order, in one pass over each document.

The same as running the datatrove filters one after another in a pipeline: a document dropped by one filter is not seen by the next, and a C4Quality step's rewritten text is what later steps filter. Steps that see the same text tokenize it once.

Parameters:

Returns:

  • FilterResult –

    FilterResult(keep, reason, text), each in the caller's kind.

Raises the same exceptions as gopher_quality.

languages

languages() -> dict[str, Language]

Every language code datatrove 0.10.1 knows, with its tokenizer.

The keys are what language= accepts: datatrove's tokenizer_assignment.csv as load_word_tokenizer reads it ("deu_Latn", "deu", "de", ...). pyroid.dedup.languages is the same function.

Example:

>>> pyroid.filters.languages()["cmn_Hani"]
Language(tokenizer='SpaCyTokenizer', arg='zh', native=False)

Returns:

  • dict[str, Language] –

    {code: Language(tokenizer, arg, native)}, sorted by code.

english_languages

english_languages() -> list[str]

The datatrove language codes whose tokenizer is SpaCyTokenizer("en").

pii_replace

pii_replace(
    texts: str,
    config: PII | None = None,
    /,
    *,
    threads: int | None = None,
    **kwargs: Unpack[_PIIKwargs],
) -> str
pii_replace(
    texts: list[str],
    config: PII | None = None,
    /,
    *,
    threads: int | None = None,
    **kwargs: Unpack[_PIIKwargs],
) -> list[str]
pii_replace(
    texts: tuple[str, ...],
    config: PII | None = None,
    /,
    *,
    threads: int | None = None,
    **kwargs: Unpack[_PIIKwargs],
) -> tuple[str, ...]
pii_replace(
    texts: ArrowStrings,
    config: PII | None = None,
    /,
    *,
    threads: int | None = None,
    **kwargs: Unpack[_PIIKwargs],
) -> Column[str]

PIIFormatter: each document's text with emails and IP addresses replaced.

A fresh formatter per call, so the replacement counters start at 0: one call over a whole corpus gives datatrove's output. To process a corpus in batches, use one PIIReplacer.

Parameters:

  • texts (str | list[str] | tuple[str, ...] | ArrowStrings) –

    A str, a list or tuple of str, or an Arrow string array/column.

  • config (PII | None, default: None ) –

    A PII; keyword arguments override its fields.

  • threads (int | None, default: None ) –

    As for PIIReplacer.__call__.

  • **kwargs (Unpack[_PIIKwargs], default: {} ) –

    PIIFormatter's parameters.

Returns:

  • str | list[str] | tuple[str, ...] | Column[str] –

    As PIIReplacer.__call__.

load_c4_badwords

load_c4_badwords(
    language: str,
    *,
    cache_dir: str | PathLike[str] | None = None,
    download: bool = True,
) -> frozenset[str]

Datatrove's bad-word set for language.

The lists are the LDNOOBW "List of Dirty, Naughty, Obscene, and Otherwise Bad Words" (https://github.com/LDNOOBW/List-of-Dirty-Naughty-Obscene-and-Otherwise-Bad-Words, CC BY 4.0), at the two commits datatrove pins. pyroid does not ship them: like datatrove, it downloads a list the first time it is needed, into cache_dir (default $PYROID_CACHE_DIR, else $XDG_CACHE_HOME/pyroid, else ~/.cache/pyroid) under c4_badwords/, and checks its sha256. The set is built as datatrove builds it: each line strip()-ed, minus every language's allowlist (sm, グロ, 女の子, 性).

Parameters:

  • language (str) –
  • cache_dir (str | PathLike[str] | None, default: None ) –

    Where the lists are kept.

  • download (bool, default: True ) –

    Fetch a missing list (else FileNotFoundError).

Raises:

  • ValueError –

    No list for language (datatrove's message).

  • OSError –

    The download failed, or the file's sha256 is not the pinned one.

c4_badwords

c4_badwords(
    texts: str,
    config: C4BadWords | None = None,
    /,
    *,
    languages: _Languages = None,
    words: Mapping[str, Iterable[str]] | None = None,
    threads: int | None = None,
    **kwargs: Unpack[_C4BadWordsKwargs],
) -> bool
c4_badwords(
    texts: list[str],
    config: C4BadWords | None = None,
    /,
    *,
    languages: _Languages = None,
    words: Mapping[str, Iterable[str]] | None = None,
    threads: int | None = None,
    **kwargs: Unpack[_C4BadWordsKwargs],
) -> list[bool]
c4_badwords(
    texts: tuple[str, ...],
    config: C4BadWords | None = None,
    /,
    *,
    languages: _Languages = None,
    words: Mapping[str, Iterable[str]] | None = None,
    threads: int | None = None,
    **kwargs: Unpack[_C4BadWordsKwargs],
) -> tuple[bool, ...]
c4_badwords(
    texts: ArrowStrings,
    config: C4BadWords | None = None,
    /,
    *,
    languages: _Languages = None,
    words: Mapping[str, Iterable[str]] | None = None,
    threads: int | None = None,
    **kwargs: Unpack[_C4BadWordsKwargs],
) -> Column[bool]

C4BadWordsFilter: True for each document datatrove keeps.

A fresh BadWordsFilter per call, so the draws start from default_rng(seed): one call over a whole corpus gives datatrove's decisions. For batches, use one BadWordsFilter.

Parameters:

  • texts (str | list[str] | tuple[str, ...] | ArrowStrings) –

    A str, a list or tuple of str, or an Arrow string array/column.

  • config (C4BadWords | None, default: None ) –

    A C4BadWords; keyword arguments override its fields.

  • languages (_Languages, default: None ) –

    As for BadWordsFilter.__call__.

  • words (Mapping[str, Iterable[str]] | None, default: None ) –

    As for BadWordsFilter.

  • threads (int | None, default: None ) –

    As for BadWordsFilter.__call__.

  • **kwargs (Unpack[_C4BadWordsKwargs], default: {} ) –

    C4BadWordsFilter's parameters.

Returns:

  • bool | list[bool] | tuple[bool, ...] | Column[bool] –

    A keep mask in the caller's kind.

c4_badwords_reasons

c4_badwords_reasons(
    texts: str,
    config: C4BadWords | None = None,
    /,
    *,
    languages: _Languages = None,
    words: Mapping[str, Iterable[str]] | None = None,
    threads: int | None = None,
    **kwargs: Unpack[_C4BadWordsKwargs],
) -> str | None
c4_badwords_reasons(
    texts: list[str],
    config: C4BadWords | None = None,
    /,
    *,
    languages: _Languages = None,
    words: Mapping[str, Iterable[str]] | None = None,
    threads: int | None = None,
    **kwargs: Unpack[_C4BadWordsKwargs],
) -> list[str | None]
c4_badwords_reasons(
    texts: tuple[str, ...],
    config: C4BadWords | None = None,
    /,
    *,
    languages: _Languages = None,
    words: Mapping[str, Iterable[str]] | None = None,
    threads: int | None = None,
    **kwargs: Unpack[_C4BadWordsKwargs],
) -> tuple[str | None, ...]
c4_badwords_reasons(
    texts: ArrowStrings,
    config: C4BadWords | None = None,
    /,
    *,
    languages: _Languages = None,
    words: Mapping[str, Iterable[str]] | None = None,
    threads: int | None = None,
    **kwargs: Unpack[_C4BadWordsKwargs],
) -> Column[str]

C4BadWordsFilter: datatrove's drop reason per document, None when kept.

As c4_badwords, returning "document_removed_with_badwords" or None.

datatrove_url_lists

datatrove_url_lists() -> DatatroveURLLists

Extract datatrove's integrated URL block lists as datatrove does; return their paths.

datatrove 0.10.1 ships them in its package (datatrove/assets): url_filterblacklistsv0_3_0.tar.gz (domains: 4,558,940 lines; urls: 19,587), banned_words.txt, banned_subwords.txt and soft_banned_words.txt. The archive is extracted once into datatrove's own cache (huggingface_hub.cached_assets_path("datatrove", "filters", "url_filter")), under datatrove's lock and .completed marker, so datatrove and pyroid share one copy. pyroid does not ship these lists: they are not under pyroid's licence.

Raises:

  • PyroidError –

    datatrove (or huggingface_hub) is not installed.

  • ImportError –

    fasteners is not installed (datatrove's lock needs it).

url_filter

url_filter(
    urls: str,
    config: URLFilterConfig | URLFilter | None = None,
    /,
    *,
    threads: int | None = None,
    **kwargs: Unpack[_URLFilterKwargs],
) -> bool
url_filter(
    urls: list[str],
    config: URLFilterConfig | URLFilter | None = None,
    /,
    *,
    threads: int | None = None,
    **kwargs: Unpack[_URLFilterKwargs],
) -> list[bool]
url_filter(
    urls: tuple[str, ...],
    config: URLFilterConfig | URLFilter | None = None,
    /,
    *,
    threads: int | None = None,
    **kwargs: Unpack[_URLFilterKwargs],
) -> tuple[bool, ...]
url_filter(
    urls: ArrowStrings,
    config: URLFilterConfig | URLFilter | None = None,
    /,
    *,
    threads: int | None = None,
    **kwargs: Unpack[_URLFilterKwargs],
) -> Column[bool]

URLFilter: True for each URL datatrove keeps.

config is a URLFilterConfig (keyword arguments override its fields) or a built URLFilter. The last two filters built from configs are cached (configs whose lists are lists, tuples, sets or strings), so repeated calls do not reload the block lists.

Returns:

  • bool | list[bool] | tuple[bool, ...] | Column[bool] –

url_filter_reasons

url_filter_reasons(
    urls: str,
    config: URLFilterConfig | URLFilter | None = None,
    /,
    *,
    threads: int | None = None,
    **kwargs: Unpack[_URLFilterKwargs],
) -> str | None
url_filter_reasons(
    urls: list[str],
    config: URLFilterConfig | URLFilter | None = None,
    /,
    *,
    threads: int | None = None,
    **kwargs: Unpack[_URLFilterKwargs],
) -> list[str | None]
url_filter_reasons(
    urls: tuple[str, ...],
    config: URLFilterConfig | URLFilter | None = None,
    /,
    *,
    threads: int | None = None,
    **kwargs: Unpack[_URLFilterKwargs],
) -> tuple[str | None, ...]
url_filter_reasons(
    urls: ArrowStrings,
    config: URLFilterConfig | URLFilter | None = None,
    /,
    *,
    threads: int | None = None,
    **kwargs: Unpack[_URLFilterKwargs],
) -> Column[str]

URLFilter: datatrove's drop reason per URL, None when kept.

Arguments as for url_filter; results as URLFilter.reasons.

symbol_lines

symbol_lines(
    texts: str,
    config: SymbolLines | None = None,
    /,
    *,
    threads: int | None = None,
    **kwargs: Unpack[_SymbolLinesKwargs],
) -> str
symbol_lines(
    texts: list[str],
    config: SymbolLines | None = None,
    /,
    *,
    threads: int | None = None,
    **kwargs: Unpack[_SymbolLinesKwargs],
) -> list[str]
symbol_lines(
    texts: tuple[str, ...],
    config: SymbolLines | None = None,
    /,
    *,
    threads: int | None = None,
    **kwargs: Unpack[_SymbolLinesKwargs],
) -> tuple[str, ...]
symbol_lines(
    texts: ArrowStrings,
    config: SymbolLines | None = None,
    /,
    *,
    threads: int | None = None,
    **kwargs: Unpack[_SymbolLinesKwargs],
) -> Column[str]

SymbolLinesFormatter: each document without its symbol-only lines.

As datatrove: over text.splitlines(), a non-blank line made only of symbols_to_remove and spaces is dropped, a run of them becomes one replace_char (if not empty), and the kept lines are joined with "\n" (so "\r\n" and a trailing newline come out as datatrove's do).

Parameters:

  • texts (str | list[str] | tuple[str, ...] | ArrowStrings) –

    A str, a list or tuple of str, or an Arrow string array/column.

  • config (SymbolLines | None, default: None ) –

    A SymbolLines; keyword arguments override its fields.

  • threads (int | None, default: None ) –

    None uses pyroid's shared thread pool; n runs at most n tasks at once; 1 runs on the calling thread.

  • **kwargs (Unpack[_SymbolLinesKwargs], default: {} ) –

    SymbolLinesFormatter's parameters.

Returns:

  • str | list[str] | tuple[str, ...] | Column[str] –

    The texts in the caller's kind; a document that comes out equal comes back as the same object (Arrow: a pyroid.Column, nulls stay null).

Raises: