def generic_expander(*expanded_names, **kwargs):
    """Decorator helping expanders to handle ``inherit`` and ``initial``.

    Wrap an expander so that it does not have to handle the 'inherit' and
    'initial' cases, and can just yield name suffixes. Missing suffixes
    get the initial value.

    """
    wants_base_url = kwargs.pop('wants_base_url', False)
    assert not kwargs

    def generic_expander_decorator(wrapped):
        """Decorate the ``wrapped`` expander."""
        @functools.wraps(wrapped)
        def generic_expander_wrapper(tokens, name, base_url):
            """Wrap the expander."""
            expander = functools.partial(
                generic_expander_wrapper, name=name, base_url=base_url)

            skip_validation = False
            keyword = get_single_keyword(tokens)
            if keyword in ('inherit', 'initial'):
                results = {name: keyword for name in expanded_names}
                skip_validation = True
            else:
                results = _find_var(tokens, expander, expanded_names)
                if results:
                    skip_validation = True

            if not skip_validation:
                results = {}
                if wants_base_url:
                    result = wrapped(tokens, name, base_url)
                else:
                    result = wrapped(tokens, name)
                for new_name, new_token in result:
                    assert new_name in expanded_names, new_name
                    if new_name in results:
                        raise InvalidValues(
                            f'got multiple {new_name.strip("-")} values '
                            f'in a {name} shorthand')
                    results[new_name] = new_token

            for new_name in expanded_names:
                if new_name.startswith('-'):
                    # new_name is a suffix
                    actual_new_name = f'{name}{new_name}'
                else:
                    actual_new_name = new_name

                if new_name in results:
                    value = results[new_name]
                    if not skip_validation:
                        # validate_non_shorthand returns ((name, value),)
                        (actual_new_name, value), = validate_non_shorthand(
                            value, actual_new_name, base_url, required=True)
                else:
                    value = 'initial'

                yield actual_new_name, value
        return generic_expander_wrapper
    return generic_expander_decorator
Decorator helping expanders to handle ``inherit`` and ``initial``.

Wrap an expander so that it does not have to handle the 'inherit' and
'initial' cases, and can just yield name suffixes. Missing suffixes
get the initial value.
weasyprint/css/validation/expanders.py