Skip to content

String assertions

Assertions available when the value under test is a str. Call them on the builder returned by assert_that("...").

String assertions mixin.

is_equal_to_ignoring_case

is_equal_to_ignoring_case(other: str) -> Self

Asserts that val is a string and is case-insensitive equal to other.

Checks actual is equal to expected using the == operator and str.lower().

Parameters:

Name Type Description Default
other str

the expected value

required

Examples:

Usage:

assert_that('foo').is_equal_to_ignoring_case('FOO')
assert_that('FOO').is_equal_to_ignoring_case('foo')
assert_that('fOo').is_equal_to_ignoring_case('FoO')

Returns:

Name Type Description
AssertionBuilder Self

returns this instance to chain to the next assertion

Raises:

Type Description
AssertionError

if actual is not case-insensitive equal to expected

Source code in assertpy2/string.py
def is_equal_to_ignoring_case(self, other: str) -> Self:
    """Asserts that val is a string and is case-insensitive equal to other.

    Checks actual is equal to expected using the ``==`` operator and ``str.lower()``.

    Args:
        other: the expected value

    Examples:
        Usage:

            assert_that('foo').is_equal_to_ignoring_case('FOO')
            assert_that('FOO').is_equal_to_ignoring_case('foo')
            assert_that('fOo').is_equal_to_ignoring_case('FoO')

    Returns:
        AssertionBuilder: returns this instance to chain to the next assertion

    Raises:
        AssertionError: if actual is **not** case-insensitive equal to expected
    """
    require_type(self.val, str, "a string")
    require_type(other, str, "a string", subject=argument("other"))
    if self.val.lower() != other.lower():
        return self.error(f"Expected <{self.val}> to be case-insensitive equal to <{other}>, but was not.")
    return self

is_equal_to_ignoring_whitespace

is_equal_to_ignoring_whitespace(other: str) -> Self

Asserts that val is a string and is equal to other ignoring all whitespace.

All whitespace (spaces, tabs, newlines) is stripped from both strings before comparing with the == operator, so differences in spacing, indentation, or line breaks don't matter. Case still does.

Parameters:

Name Type Description Default
other str

the expected value

required

Examples:

Usage:

assert_that('foo bar').is_equal_to_ignoring_whitespace('foobar')
assert_that('foo\nbar').is_equal_to_ignoring_whitespace('foo bar')
assert_that('  foo  ').is_equal_to_ignoring_whitespace('foo')

Returns:

Name Type Description
AssertionBuilder Self

returns this instance to chain to the next assertion

Raises:

Type Description
AssertionError

if actual is not equal to expected ignoring whitespace

TypeError

if val or the given arg is not a string

Source code in assertpy2/string.py
def is_equal_to_ignoring_whitespace(self, other: str) -> Self:
    """Asserts that val is a string and is equal to other ignoring all whitespace.

    All whitespace (spaces, tabs, newlines) is stripped from both strings before comparing with
    the ``==`` operator, so differences in spacing, indentation, or line breaks don't matter.
    Case still does.

    Args:
        other: the expected value

    Examples:
        Usage:

            assert_that('foo bar').is_equal_to_ignoring_whitespace('foobar')
            assert_that('foo\\nbar').is_equal_to_ignoring_whitespace('foo bar')
            assert_that('  foo  ').is_equal_to_ignoring_whitespace('foo')

    Returns:
        AssertionBuilder: returns this instance to chain to the next assertion

    Raises:
        AssertionError: if actual is **not** equal to expected ignoring whitespace
        TypeError: if val or the given arg is not a string
    """
    require_type(self.val, str, "a string")
    require_type(other, str, "a string", subject=argument("other"))
    if "".join(self.val.split()) != "".join(other.split()):
        return self.error(f"Expected <{self.val}> to be equal to <{other}> ignoring whitespace, but was not.")
    return self

contains_ignoring_case

contains_ignoring_case(*items: str) -> Self

Asserts that val is string and contains the given item or items.

Walks val and checks for item or items using the == operator and str.lower().

Parameters:

Name Type Description Default
*items str

the item or items expected to be contained

()

Examples:

Usage:

assert_that('foo').contains_ignoring_case('F', 'oO')
assert_that(['a', 'B']).contains_ignoring_case('A', 'b')
assert_that({'a': 1, 'B': 2}).contains_ignoring_case('A', 'b')
assert_that({'a', 'B'}).contains_ignoring_case('A', 'b')

Returns:

Name Type Description
AssertionBuilder Self

returns this instance to chain to the next assertion

Raises:

Type Description
AssertionError

if val does not contain the case-insensitive item or items

Source code in assertpy2/string.py
def contains_ignoring_case(self, *items: str) -> Self:
    """Asserts that val is string and contains the given item or items.

    Walks val and checks for item or items using the ``==`` operator and ``str.lower()``.

    Args:
        *items: the item or items expected to be contained

    Examples:
        Usage:

            assert_that('foo').contains_ignoring_case('F', 'oO')
            assert_that(['a', 'B']).contains_ignoring_case('A', 'b')
            assert_that({'a': 1, 'B': 2}).contains_ignoring_case('A', 'b')
            assert_that({'a', 'B'}).contains_ignoring_case('A', 'b')

    Returns:
        AssertionBuilder: returns this instance to chain to the next assertion

    Raises:
        AssertionError: if val does **not** contain the case-insensitive item or items
    """
    if len(items) == 0:
        raise ValueError("one or more args must be given")
    if isinstance(self.val, str):
        if len(items) == 1:
            require_type(items[0], str, "a string", subject=argument("item"))
            if items[0].lower() not in self.val.lower():
                return self.error(
                    f"Expected <{self.val}> to case-insensitive contain item <{items[0]}>, but did not."
                )
        else:
            val_lower = self.val.lower()
            missing = []
            for item in items:
                require_type(item, str, "a string", subject=argument("item"))
                if item.lower() not in val_lower:
                    missing.append(item)
            if missing:
                return self.error(
                    f"Expected <{self.val}> to case-insensitive contain items"
                    f" {self._fmt_items(items)}, but did not contain {self._fmt_items(missing)}."
                )
    elif isinstance(self.val, collections.abc.Iterable):
        lowered_values = []
        for value in list(self.val):  # materialize once so a one-shot iterable is not exhausted
            # validate every element up front so the error does not depend on match/scan order
            require_type(value, str, "a string", subject="every item of val")
            lowered_values.append(value.lower())
        missing = []
        for item in items:
            require_type(item, str, "a string", subject=argument("item"))
            if item.lower() not in lowered_values:
                missing.append(item)
        if missing:
            return self.error(
                f"Expected <{self.val}> to case-insensitive contain items"
                f" {self._fmt_items(items)}, but did not contain {self._fmt_items(missing)}."
            )
    else:
        refuse(self.val, "a string or an iterable")
    return self

starts_with

starts_with(prefix: str) -> Self

Asserts that val is string or iterable and starts with prefix.

Parameters:

Name Type Description Default
prefix str

the prefix

required

Examples:

Usage:

assert_that('foo').starts_with('fo')
assert_that(['a', 'b', 'c']).starts_with('a')
assert_that((1, 2, 3)).starts_with(1)
assert_that(((1, 2), (3, 4), (5, 6))).starts_with((1, 2))

Returns:

Name Type Description
AssertionBuilder Self

returns this instance to chain to the next assertion

Raises:

Type Description
AssertionError

if val does not start with prefix

Source code in assertpy2/string.py
def starts_with(self, prefix: str) -> Self:
    """Asserts that val is string or iterable and starts with prefix.

    Args:
        prefix: the prefix

    Examples:
        Usage:

            assert_that('foo').starts_with('fo')
            assert_that(['a', 'b', 'c']).starts_with('a')
            assert_that((1, 2, 3)).starts_with(1)
            assert_that(((1, 2), (3, 4), (5, 6))).starts_with((1, 2))

    Returns:
        AssertionBuilder: returns this instance to chain to the next assertion

    Raises:
        AssertionError: if val does **not** start with prefix
    """
    if prefix is None:  # `None` is neither, and reaches the branch below only to confuse it
        refuse(prefix, "a string or bytes", subject=argument("prefix"))
    if isinstance(self.val, str):
        require_type(prefix, str, "a string", subject=argument("prefix"))
        if len(prefix) == 0:
            raise ValueError("given prefix arg must not be empty")
        if not self.val.startswith(prefix):
            return self.error(f"Expected <{self.val}> to start with <{prefix}>, but did not.")
    elif isinstance(self.val, (bytes, bytearray)):
        # bytes are iterable, so without this branch they fall through to the one below and get
        # compared element-wise: `b"foo"` yields the int 102 first, and `102 != b"f"` fails an
        # assertion that should pass. A prefix of a byte string is a byte string, same as for text
        raw_prefix = require_type(prefix, (bytes, bytearray), "bytes", subject=argument("prefix"))
        if len(raw_prefix) == 0:
            raise ValueError("given prefix arg must not be empty")
        if not self.val.startswith(raw_prefix):
            return self.error(f"Expected <{self.val!r}> to start with <{raw_prefix!r}>, but did not.")
    elif isinstance(self.val, collections.abc.Iterable):
        iterator = iter(self.val)
        try:
            first = next(iterator)
        except StopIteration:
            raise ValueError("val must not be empty") from None
        if first != prefix:
            return self.error(f"Expected {self.val} to start with <{prefix}>, but did not.")
    else:
        refuse(self.val, "a string or an iterable")
    return self

ends_with

ends_with(suffix: str) -> Self

Asserts that val is string or iterable and ends with suffix.

Parameters:

Name Type Description Default
suffix str

the suffix

required

Examples:

Usage:

assert_that('foo').ends_with('oo')
assert_that(['a', 'b', 'c']).ends_with('c')
assert_that((1, 2, 3)).ends_with(3)
assert_that(((1, 2), (3, 4), (5, 6))).ends_with((5, 6))

Returns:

Name Type Description
AssertionBuilder Self

returns this instance to chain to the next assertion

Raises:

Type Description
AssertionError

if val does not end with suffix

Source code in assertpy2/string.py
def ends_with(self, suffix: str) -> Self:
    """Asserts that val is string or iterable and ends with suffix.

    Args:
        suffix: the suffix

    Examples:
        Usage:

            assert_that('foo').ends_with('oo')
            assert_that(['a', 'b', 'c']).ends_with('c')
            assert_that((1, 2, 3)).ends_with(3)
            assert_that(((1, 2), (3, 4), (5, 6))).ends_with((5, 6))

    Returns:
        AssertionBuilder: returns this instance to chain to the next assertion

    Raises:
        AssertionError: if val does **not** end with suffix
    """
    if suffix is None:
        refuse(suffix, "a string or bytes", subject=argument("suffix"))
    if isinstance(self.val, str):
        require_type(suffix, str, "a string", subject=argument("suffix"))
        if len(suffix) == 0:
            raise ValueError("given suffix arg must not be empty")
        if not self.val.endswith(suffix):
            return self.error(f"Expected <{self.val}> to end with <{suffix}>, but did not.")
    elif isinstance(self.val, (bytes, bytearray)):
        # the mirror of the branch in starts_with, and broken the same way without it: the last
        # element of `b"foo"` is the int 111, never equal to `b"o"`
        raw_suffix = require_type(suffix, (bytes, bytearray), "bytes", subject=argument("suffix"))
        if len(raw_suffix) == 0:
            raise ValueError("given suffix arg must not be empty")
        if not self.val.endswith(raw_suffix):
            return self.error(f"Expected <{self.val!r}> to end with <{raw_suffix!r}>, but did not.")
    elif isinstance(self.val, collections.abc.Iterable):
        items = list(self.val)
        if not items:
            raise ValueError("val must not be empty")
        if items[-1] != suffix:
            return self.error(f"Expected {self.val} to end with <{suffix}>, but did not.")
    else:
        refuse(self.val, "a string or an iterable")
    return self

starts_with_ignoring_case

starts_with_ignoring_case(prefix: str) -> Self

Asserts that val is a string and starts with prefix, ignoring case.

Like starts_with() but case-insensitive (via str.lower()), and strings only.

Parameters:

Name Type Description Default
prefix str

the prefix

required

Examples:

Usage:

assert_that('FooBar').starts_with_ignoring_case('foo')
assert_that('foobar').starts_with_ignoring_case('FOO')

Returns:

Name Type Description
AssertionBuilder Self

returns this instance to chain to the next assertion

Raises:

Type Description
AssertionError

if val does not case-insensitive start with prefix

TypeError

if val or the given prefix is not a string

ValueError

if the given prefix is empty

Source code in assertpy2/string.py
def starts_with_ignoring_case(self, prefix: str) -> Self:
    """Asserts that val is a string and starts with prefix, ignoring case.

    Like [`starts_with()`][assertpy2.string.StringMixin.starts_with] but case-insensitive
    (via ``str.lower()``), and strings only.

    Args:
        prefix: the prefix

    Examples:
        Usage:

            assert_that('FooBar').starts_with_ignoring_case('foo')
            assert_that('foobar').starts_with_ignoring_case('FOO')

    Returns:
        AssertionBuilder: returns this instance to chain to the next assertion

    Raises:
        AssertionError: if val does **not** case-insensitive start with prefix
        TypeError: if val or the given prefix is not a string
        ValueError: if the given prefix is empty
    """
    require_type(self.val, str, "a string")
    require_type(prefix, str, "a string", subject=argument("prefix"))
    if len(prefix) == 0:
        raise ValueError("given prefix arg must not be empty")
    if not self.val.lower().startswith(prefix.lower()):
        return self.error(f"Expected <{self.val}> to case-insensitive start with <{prefix}>, but did not.")
    return self

ends_with_ignoring_case

ends_with_ignoring_case(suffix: str) -> Self

Asserts that val is a string and ends with suffix, ignoring case.

Like ends_with() but case-insensitive (via str.lower()), and strings only.

Parameters:

Name Type Description Default
suffix str

the suffix

required

Examples:

Usage:

assert_that('FooBar').ends_with_ignoring_case('BAR')
assert_that('foobar').ends_with_ignoring_case('Bar')

Returns:

Name Type Description
AssertionBuilder Self

returns this instance to chain to the next assertion

Raises:

Type Description
AssertionError

if val does not case-insensitive end with suffix

TypeError

if val or the given suffix is not a string

ValueError

if the given suffix is empty

Source code in assertpy2/string.py
def ends_with_ignoring_case(self, suffix: str) -> Self:
    """Asserts that val is a string and ends with suffix, ignoring case.

    Like [`ends_with()`][assertpy2.string.StringMixin.ends_with] but case-insensitive
    (via ``str.lower()``), and strings only.

    Args:
        suffix: the suffix

    Examples:
        Usage:

            assert_that('FooBar').ends_with_ignoring_case('BAR')
            assert_that('foobar').ends_with_ignoring_case('Bar')

    Returns:
        AssertionBuilder: returns this instance to chain to the next assertion

    Raises:
        AssertionError: if val does **not** case-insensitive end with suffix
        TypeError: if val or the given suffix is not a string
        ValueError: if the given suffix is empty
    """
    require_type(self.val, str, "a string")
    require_type(suffix, str, "a string", subject=argument("suffix"))
    if len(suffix) == 0:
        raise ValueError("given suffix arg must not be empty")
    if not self.val.lower().endswith(suffix.lower()):
        return self.error(f"Expected <{self.val}> to case-insensitive end with <{suffix}>, but did not.")
    return self

matches

matches(pattern) -> Self

Asserts that val is string and matches the given regex pattern.

Parameters:

Name Type Description Default
pattern str

the regular expression pattern, as raw string (aka prefixed with r)

required

Examples:

Usage:

assert_that('foo').matches(r'\w')
assert_that('123-456-7890').matches(r'\d{3}-\d{3}-\d{4}')

Match is partial unless anchored, so these assertion pass:

assert_that('foo').matches(r'\w')
assert_that('foo').matches(r'oo')
assert_that('foo').matches(r'\w{2}')

To match the entire string, just use an anchored regex pattern where ^ and $ match the start and end of line and \A and \Z match the start and end of string:

assert_that('foo').matches(r'^\w{3}$')
assert_that('foo').matches(r'\A\w{3}\Z')

And regex flags, such as re.MULTILINE and re.DOTALL, can only be applied via inline modifiers, such as (?m) and (?s):

s = '''bar
foo
baz'''

# using multiline (?m)
assert_that(s).matches(r'(?m)^foo$')

# using dotall (?s)
assert_that(s).matches(r'(?s)b(.*)z')

Returns:

Name Type Description
AssertionBuilder Self

returns this instance to chain to the next assertion

Raises:

Type Description
AssertionError

if val does not match pattern

Tip

Regular expressions are tricky. Be sure to use raw strings (aka prefixed with r). Also, note that the matches() assertion passes for partial matches (as does the underlying re.match method). So, if you need to match the entire string, you must include anchors in the regex pattern.

Source code in assertpy2/string.py
def matches(self, pattern) -> Self:
    """Asserts that val is string and matches the given regex pattern.

    Args:
        pattern (str): the regular expression pattern, as raw string (aka prefixed with ``r``)

    Examples:
        Usage:

            assert_that('foo').matches(r'\\w')
            assert_that('123-456-7890').matches(r'\\d{3}-\\d{3}-\\d{4}')

        Match is partial unless anchored, so these assertion pass:

            assert_that('foo').matches(r'\\w')
            assert_that('foo').matches(r'oo')
            assert_that('foo').matches(r'\\w{2}')

        To match the entire string, just use an anchored regex pattern where ``^`` and ``$``
        match the start and end of line and ``\\A`` and ``\\Z`` match the start and end of string:

            assert_that('foo').matches(r'^\\w{3}$')
            assert_that('foo').matches(r'\\A\\w{3}\\Z')

        And regex flags, such as ``re.MULTILINE`` and ``re.DOTALL``, can only be applied via
        *inline modifiers*, such as ``(?m)`` and ``(?s)``:

            s = '''bar
            foo
            baz'''

            # using multiline (?m)
            assert_that(s).matches(r'(?m)^foo$')

            # using dotall (?s)
            assert_that(s).matches(r'(?s)b(.*)z')

    Returns:
        AssertionBuilder: returns this instance to chain to the next assertion

    Raises:
        AssertionError: if val does **not** match pattern

    Tip:
        Regular expressions are tricky.  Be sure to use raw strings (aka prefixed with ``r``).
        Also, note that the [`matches()`][assertpy2.string.StringMixin.matches] assertion passes
        for partial matches (as does the
        underlying ``re.match`` method).  So, if you need to match the entire string, you must
        include anchors in the regex pattern.
    """
    require_type(self.val, str, "a string")
    require_type(pattern, str, "a string", subject=argument("pattern"))
    if len(pattern) == 0:
        raise ValueError("given pattern arg must not be empty")
    if re.search(pattern, self.val) is None:
        return self.error(f"Expected <{self.val}> to match pattern <{pattern}>, but did not.")
    return self

does_not_match

does_not_match(pattern) -> Self

Asserts that val is string and does not match the given regex pattern.

Parameters:

Name Type Description Default
pattern str

the regular expression pattern, as raw string (aka prefixed with r)

required

Examples:

Usage:

assert_that('foo').does_not_match(r'\d+')
assert_that('123').does_not_match(r'\w+')

Returns:

Name Type Description
AssertionBuilder Self

returns this instance to chain to the next assertion

Raises:

Type Description
AssertionError

if val does match pattern

See Also

matches() - for more about regex patterns

Source code in assertpy2/string.py
def does_not_match(self, pattern) -> Self:
    """Asserts that val is string and does not match the given regex pattern.

    Args:
        pattern (str): the regular expression pattern, as raw string (aka prefixed with ``r``)

    Examples:
        Usage:

            assert_that('foo').does_not_match(r'\\d+')
            assert_that('123').does_not_match(r'\\w+')

    Returns:
        AssertionBuilder: returns this instance to chain to the next assertion

    Raises:
        AssertionError: if val **does** match pattern

    See Also:
        [`matches()`][assertpy2.string.StringMixin.matches] - for more about regex patterns
    """
    require_type(self.val, str, "a string")
    require_type(pattern, str, "a string", subject=argument("pattern"))
    if len(pattern) == 0:
        raise ValueError("given pattern arg must not be empty")
    if re.search(pattern, self.val) is not None:
        return self.error(f"Expected <{self.val}> to not match pattern <{pattern}>, but did.")
    return self

is_alpha

is_alpha() -> Self

Asserts that val is non-empty string and all characters are alphabetic (using str.isalpha()).

Examples:

Usage:

assert_that('foo').is_alpha()

Returns:

Name Type Description
AssertionBuilder Self

returns this instance to chain to the next assertion

Raises:

Type Description
AssertionError

if val is not alphabetic

Source code in assertpy2/string.py
def is_alpha(self) -> Self:
    """Asserts that val is non-empty string and all characters are alphabetic (using ``str.isalpha()``).

    Examples:
        Usage:

            assert_that('foo').is_alpha()

    Returns:
        AssertionBuilder: returns this instance to chain to the next assertion

    Raises:
        AssertionError: if val is **not** alphabetic
    """
    return self._assert_string_chars(str.isalpha, "alphabetic chars")

is_digit

is_digit() -> Self

Asserts that val is non-empty string and all characters are digits (using str.isdigit()).

Examples:

Usage:

assert_that('1234567890').is_digit()

Returns:

Name Type Description
AssertionBuilder Self

returns this instance to chain to the next assertion

Raises:

Type Description
AssertionError

if val is not digits

Source code in assertpy2/string.py
def is_digit(self) -> Self:
    """Asserts that val is non-empty string and all characters are digits (using ``str.isdigit()``).

    Examples:
        Usage:

            assert_that('1234567890').is_digit()

    Returns:
        AssertionBuilder: returns this instance to chain to the next assertion

    Raises:
        AssertionError: if val is **not** digits
    """
    return self._assert_string_chars(str.isdigit, "digits")

is_lower

is_lower() -> Self

Asserts that val is non-empty string and all characters are lowercase (using str.lower()).

Examples:

Usage:

assert_that('foo').is_lower()

Returns:

Name Type Description
AssertionBuilder Self

returns this instance to chain to the next assertion

Raises:

Type Description
AssertionError

if val is not lowercase

Source code in assertpy2/string.py
def is_lower(self) -> Self:
    """Asserts that val is non-empty string and all characters are lowercase (using ``str.lower()``).

    Examples:
        Usage:

            assert_that('foo').is_lower()

    Returns:
        AssertionBuilder: returns this instance to chain to the next assertion

    Raises:
        AssertionError: if val is **not** lowercase
    """
    return self._assert_string_chars(lambda value: value == value.lower(), "lowercase chars")

is_upper

is_upper() -> Self

Asserts that val is non-empty string and all characters are uppercase (using str.upper()).

Examples:

Usage:

assert_that('FOO').is_upper()

Returns:

Name Type Description
AssertionBuilder Self

returns this instance to chain to the next assertion

Raises:

Type Description
AssertionError

if val is not uppercase

Source code in assertpy2/string.py
def is_upper(self) -> Self:
    """Asserts that val is non-empty string and all characters are uppercase (using ``str.upper()``).

    Examples:
        Usage:

            assert_that('FOO').is_upper()

    Returns:
        AssertionBuilder: returns this instance to chain to the next assertion

    Raises:
        AssertionError: if val is **not** uppercase
    """
    return self._assert_string_chars(lambda value: value == value.upper(), "uppercase chars")

is_alphanumeric

is_alphanumeric() -> Self

Asserts that val is non-empty string and all characters are alphanumeric (using str.isalnum()).

Examples:

Usage:

assert_that('abc123').is_alphanumeric()

Returns:

Name Type Description
AssertionBuilder Self

returns this instance to chain to the next assertion

Raises:

Type Description
AssertionError

if val is not alphanumeric

Source code in assertpy2/string.py
def is_alphanumeric(self) -> Self:
    """Asserts that val is non-empty string and all characters are alphanumeric (using ``str.isalnum()``).

    Examples:
        Usage:

            assert_that('abc123').is_alphanumeric()

    Returns:
        AssertionBuilder: returns this instance to chain to the next assertion

    Raises:
        AssertionError: if val is **not** alphanumeric
    """
    return self._assert_string_chars(str.isalnum, "alphanumeric chars")

is_whitespace

is_whitespace() -> Self

Asserts that val is non-empty string and all characters are whitespace (using str.isspace()).

Examples:

Usage:

assert_that('  ').is_whitespace()
assert_that('\t\n').is_whitespace()

Returns:

Name Type Description
AssertionBuilder Self

returns this instance to chain to the next assertion

Raises:

Type Description
AssertionError

if val is not whitespace

Source code in assertpy2/string.py
def is_whitespace(self) -> Self:
    """Asserts that val is non-empty string and all characters are whitespace (using ``str.isspace()``).

    Examples:
        Usage:

            assert_that('  ').is_whitespace()
            assert_that('\\t\\n').is_whitespace()

    Returns:
        AssertionBuilder: returns this instance to chain to the next assertion

    Raises:
        AssertionError: if val is **not** whitespace
    """
    return self._assert_string_chars(str.isspace, "whitespace")

contains_any_of

contains_any_of(*items: str) -> Self

Asserts that val is a string and contains at least one of the given items.

Parameters:

Name Type Description Default
*items str

the items, at least one of which is expected to be contained

()

Examples:

Usage:

assert_that('foobar').contains_any_of('foo', 'xxx')
assert_that('foobar').contains_any_of('xxx', 'bar')

Returns:

Name Type Description
AssertionBuilder Self

returns this instance to chain to the next assertion

Raises:

Type Description
AssertionError

if val does not contain any of the items

Source code in assertpy2/string.py
def contains_any_of(self, *items: str) -> Self:
    """Asserts that val is a string and contains at least one of the given items.

    Args:
        *items: the items, at least one of which is expected to be contained

    Examples:
        Usage:

            assert_that('foobar').contains_any_of('foo', 'xxx')
            assert_that('foobar').contains_any_of('xxx', 'bar')

    Returns:
        AssertionBuilder: returns this instance to chain to the next assertion

    Raises:
        AssertionError: if val does **not** contain any of the items
    """
    require_type(self.val, str, "a string")
    if len(items) == 0:
        raise ValueError("one or more args must be given")
    for item in items:
        require_type(item, str, "a string", subject=argument("item"))
    if not any(item in self.val for item in items):
        return self.error(f"Expected <{self.val}> to contain any of {self._fmt_items(items)}, but did not.")
    return self

contains_none_of

contains_none_of(*items: str) -> Self

Asserts that val is a string and contains none of the given items.

Parameters:

Name Type Description Default
*items str

the items, none of which should be contained

()

Examples:

Usage:

assert_that('foobar').contains_none_of('xxx', 'yyy')

Returns:

Name Type Description
AssertionBuilder Self

returns this instance to chain to the next assertion

Raises:

Type Description
AssertionError

if val does contain any of the items

Source code in assertpy2/string.py
def contains_none_of(self, *items: str) -> Self:
    """Asserts that val is a string and contains none of the given items.

    Args:
        *items: the items, none of which should be contained

    Examples:
        Usage:

            assert_that('foobar').contains_none_of('xxx', 'yyy')

    Returns:
        AssertionBuilder: returns this instance to chain to the next assertion

    Raises:
        AssertionError: if val **does** contain any of the items
    """
    require_type(self.val, str, "a string")
    if len(items) == 0:
        raise ValueError("one or more args must be given")
    for item in items:
        require_type(item, str, "a string", subject=argument("item"))
    found = [item for item in items if item in self.val]
    if found:
        return self.error(
            f"Expected <{self.val}> to contain none of {self._fmt_items(items)},"
            f" but did contain {self._fmt_items(found)}."
        )
    return self

is_unicode

is_unicode() -> Self

Asserts that val is a str.

Retained for assertpy compatibility: every str is unicode on Python 3, so this is effectively an isinstance(val, str) check.

Examples:

Usage:

assert_that('foo').is_unicode()

Returns:

Name Type Description
AssertionBuilder Self

returns this instance to chain to the next assertion

Raises:

Type Description
AssertionError

if val is not a str

Source code in assertpy2/string.py
def is_unicode(self) -> Self:
    """Asserts that val is a ``str``.

    Retained for ``assertpy`` compatibility: every ``str`` is unicode on Python 3, so this is
    effectively an ``isinstance(val, str)`` check.

    Examples:
        Usage:

            assert_that('foo').is_unicode()

    Returns:
        AssertionBuilder: returns this instance to chain to the next assertion

    Raises:
        AssertionError: if val is **not** a ``str``
    """
    if not isinstance(self.val, str):
        return self.error(f"Expected <{self.val}> to be unicode, but was <{type(self.val).__name__}>.")
    return self

extracting_group

extracting_group(
    pattern: str, group: int | str = 0
) -> Self

Search val for pattern and return a new builder whose val is the captured group.

Parameters:

Name Type Description Default
pattern str

the regular expression pattern (must contain at least one group)

required
group int | str

the group index (int) or name (str) to extract. Defaults to 0 (the entire match).

0

Examples:

Usage with positional groups:

assert_that("status=200 path=/api").extracting_group(r"status=(\d+)", 1).is_equal_to("200")

Usage with named groups:

assert_that("2024-01-15 ERROR").extracting_group(
    r"(?P<level>\w+)$", "level"
).is_equal_to("ERROR")

Returns:

Name Type Description
AssertionBuilder Self

a new builder whose val is the extracted group string

Raises:

Type Description
TypeError

if val is not a string or pattern is not a string

ValueError

if pattern is empty

AssertionError

if the pattern does not match val or the group does not exist

Source code in assertpy2/string.py
def extracting_group(self, pattern: str, group: int | str = 0) -> Self:
    """Search val for ``pattern`` and return a new builder whose val is the captured group.

    Args:
        pattern: the regular expression pattern (must contain at least one group)
        group: the group index (int) or name (str) to extract. Defaults to ``0``
            (the entire match).

    Examples:
        Usage with positional groups:

            assert_that("status=200 path=/api").extracting_group(r"status=(\\d+)", 1).is_equal_to("200")

        Usage with named groups:

            assert_that("2024-01-15 ERROR").extracting_group(
                r"(?P<level>\\w+)$", "level"
            ).is_equal_to("ERROR")

    Returns:
        AssertionBuilder: a **new** builder whose val is the extracted group string

    Raises:
        TypeError: if val is not a string or pattern is not a string
        ValueError: if pattern is empty
        AssertionError: if the pattern does not match val or the group does not exist
    """
    require_type(self.val, str, "a string")
    require_type(pattern, str, "a string", subject=argument("pattern"))
    if len(pattern) == 0:
        raise ValueError("given pattern arg must not be empty")
    match_obj = re.search(pattern, self.val)
    if match_obj is None:
        return self.error(f"Expected <{self.val}> to match pattern <{pattern}>, but did not.")
    try:
        extracted = match_obj.group(group)
    except IndexError:
        return self.error(
            f"Expected pattern <{pattern}> to have group <{group}>, but it does not.", suppress_context=True
        )
    if extracted is None:
        return self.error(
            f"Expected group <{group}> of pattern <{pattern}> to be matched in <{self.val}>, but it was not."
        )
    return self.builder(extracted, self.description, self.kind)

matches_with_groups

matches_with_groups(pattern: str) -> Self

Search val for pattern and return a new builder whose val is the tuple of all groups.

If the pattern contains named groups, the builder val is a dict of {name: value} for all named groups. Otherwise it is the tuple returned by Match.groups().

Parameters:

Name Type Description Default
pattern str

the regular expression pattern with one or more groups

required

Examples:

Positional groups:

assert_that("2024-01-15 ERROR").matches_with_groups(
    r"(\d{4}-\d{2}-\d{2}) (\w+)"
).is_length(2)

Named groups:

assert_that("status=200").matches_with_groups(
    r"(?P<key>\w+)=(?P<val>\w+)"
).contains_key("key").contains_key("val")

Returns:

Name Type Description
AssertionBuilder Self

a new builder whose val is the groups tuple or groupdict

Raises:

Type Description
TypeError

if val is not a string or pattern is not a string

ValueError

if pattern is empty

AssertionError

if the pattern does not match val

Source code in assertpy2/string.py
def matches_with_groups(self, pattern: str) -> Self:
    """Search val for ``pattern`` and return a new builder whose val is the tuple of all groups.

    If the pattern contains **named** groups, the builder val is a ``dict``
    of ``{name: value}`` for all named groups.  Otherwise it is the
    ``tuple`` returned by ``Match.groups()``.

    Args:
        pattern: the regular expression pattern with one or more groups

    Examples:
        Positional groups:

            assert_that("2024-01-15 ERROR").matches_with_groups(
                r"(\\d{4}-\\d{2}-\\d{2}) (\\w+)"
            ).is_length(2)

        Named groups:

            assert_that("status=200").matches_with_groups(
                r"(?P<key>\\w+)=(?P<val>\\w+)"
            ).contains_key("key").contains_key("val")

    Returns:
        AssertionBuilder: a **new** builder whose val is the groups tuple or groupdict

    Raises:
        TypeError: if val is not a string or pattern is not a string
        ValueError: if pattern is empty
        AssertionError: if the pattern does not match val
    """
    require_type(self.val, str, "a string")
    require_type(pattern, str, "a string", subject=argument("pattern"))
    if len(pattern) == 0:
        raise ValueError("given pattern arg must not be empty")
    match_obj = re.search(pattern, self.val)
    if match_obj is None:
        return self.error(f"Expected <{self.val}> to match pattern <{pattern}>, but did not.")
    groupdict = match_obj.groupdict()
    result = groupdict or match_obj.groups()
    return self.builder(result, self.description, self.kind)