Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def preprocess_descriptors(base_url, descriptors):
"""Filter unsupported names and values for descriptors.
Log a warning for every ignored descriptor.
Return a iterable of ``(name, value)`` tuples.
"""
for descriptor in descriptors:
if descriptor.type != 'declaration' or descriptor.important:
continue
tokens = remove_whitespace(descriptor.value)
try:
# Use list() to consume generators now and catch any error.
if descriptor.name not in DESCRIPTORS:
raise InvalidValues('descriptor not supported')
function = DESCRIPTORS[descriptor.name]
if function.wants_base_url:
value = function(tokens, base_url)
else:
value = function(tokens)
if value is None:
raise InvalidValues
result = ((descriptor.name, value),)
except InvalidValues as exc:
LOGGER.warning(
'Ignored `%s:%s` at %i:%i, %s.',
descriptor.name, tinycss2.serialize(descriptor.value),
descriptor.source_line, descriptor.source_column,
exc.args[0] if exc.args and exc.args[0] else 'invalid value')
continue
elif font_stretch([token]) is not None:
suffix = '-stretch'
else:
# We’re done with these four, continue with font-size
break
yield suffix, [token]
if not tokens:
raise InvalidValues
else:
token = tokens.pop()
# Then font-size is mandatory
# Latest `token` from the loop.
if font_size([token]) is None:
raise InvalidValues
yield '-size', [token]
# Then line-height is optional, but font-family is not so the list
# must not be empty yet
if not tokens:
raise InvalidValues
token = tokens.pop()
if token.type == 'literal' and token.value == '/':
token = tokens.pop()
if line_height([token]) is None:
raise InvalidValues
yield 'line-height', [token]
else:
# We pop()ed a font-family, add it back
tokens.append(token)
def border_radius(base_url, name, tokens):
"""Validator for the `border-radius` property."""
current = horizontal = []
vertical = []
for token in tokens:
if token.type == 'literal' and token.value == '/':
if current is horizontal:
if token == tokens[-1]:
raise InvalidValues('Expected value after "/" separator')
else:
current = vertical
else:
raise InvalidValues('Expected only one "/" separator')
else:
current.append(token)
if not vertical:
vertical = horizontal[:]
for values in horizontal, vertical:
# Make sure we have 4 tokens
if len(values) == 1:
values *= 4
elif len(values) == 2:
values *= 2 # (br, bl) defaults to (tl, tr)
elif len(values) == 3:
values.append(values[1]) # bl defaults to tr
elif len(values) != 4:
raise InvalidValues(
"""Wrap the expander."""
keyword = get_single_keyword(tokens)
if keyword in ('inherit', 'initial'):
results = dict.fromkeys(expanded_names, keyword)
skip_validation = True
else:
skip_validation = False
results = {}
if wants_base_url:
result = wrapped(name, tokens, base_url)
else:
result = wrapped(name, tokens)
for new_name, new_token in result:
assert new_name in expanded_names, new_name
if new_name in results:
raise InvalidValues(
'got multiple %s values in a %s shorthand'
% (new_name.strip('-'), name))
results[new_name] = new_token
for new_name in expanded_names:
if new_name.startswith('-'):
# new_name is a suffix
actual_new_name = 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(
def safe_urljoin(base_url, url):
if url_is_absolute(url):
return iri_to_uri(url)
elif base_url:
return iri_to_uri(urljoin(base_url, url))
else:
raise InvalidValues(
'Relative URI reference without a base URI: %r' % url)
def counter(tokens, default_integer):
"""``counter-increment`` and ``counter-reset`` properties validation."""
if get_single_keyword(tokens) == 'none':
return ()
tokens = iter(tokens)
token = next(tokens, None)
assert token, 'got an empty token list'
results = []
while token is not None:
if token.type != 'ident':
return # expected a keyword here
counter_name = token.value
if counter_name in ('none', 'initial', 'inherit'):
raise InvalidValues('Invalid counter name: ' + counter_name)
token = next(tokens, None)
if token is not None and (
token.type == 'number' and token.int_value is not None):
# Found an integer. Use it and get the next token
integer = token.int_value
token = next(tokens, None)
else:
# Not an integer. Might be the next counter name.
# Keep `token` for the next loop iteration.
integer = default_integer
results.append((counter_name, integer))
return tuple(results)
for token in tokens:
var_function = check_var_function(token)
if var_function:
return ((name, var_function),)
keyword = get_single_keyword(tokens)
if keyword in ('initial', 'inherit'):
value = keyword
else:
function = PROPERTIES[name]
if function.wants_base_url:
value = function(tokens, base_url)
else:
value = function(tokens)
if value is None:
raise InvalidValues
return ((name, value),)
'use `%s` instead.',
declaration.name, serialize(declaration.value),
declaration.source_line, declaration.source_column,
unprefixed_name)
continue
if name.startswith('-') and not name.startswith('--'):
validation_error('debug', 'prefixed selectors are ignored')
continue
expander_ = EXPANDERS.get(name, validate_non_shorthand)
tokens = remove_whitespace(declaration.value)
try:
# Use list() to consume generators now and catch any error.
result = list(expander_(base_url, name, tokens))
except InvalidValues as exc:
validation_error(
'warning',
exc.args[0] if exc.args and exc.args[0] else 'invalid value')
continue
important = declaration.important
for long_name, value in result:
yield long_name.replace('-', '_'), value, important