generating higher resolution exceptions for the vnu validator¤
the vnu validator is now available on conda which means it is easier to test your html
import pandas, pathlib, json, collections, exceptiongroup, re, dataclasses
file = "../../../nbconvert-a11y/tests/exports/validator/lorenz-executed-default.json"
class Violation(Exception):
map = {}
def __class_getitem__(cls, id):
bases = None
if isinstance(id, tuple): id, bases = id
if id in cls.map: return cls.map[id]
return cls.map.setdefault(id, type(id, bases or (Violation,), {}))
def __repr__(self):
return super().__repr__()[:150]
exceptions are facetted by their type and info level.
def messages_to_violations(messages):
ct = collections.defaultdict(int)
CSS_START = re.compile("""^“\S+”:""")
exceptions = []
for message in messages:
t = message["type"],
ct[t[0]] += 1
if message.get("subType"): t += message.get("subType"),
msg = message["message"]
if msg.startswith("CSS:"):
msg = msg[5:]
t += "css",
if CSS_START.match(msg):
prop, _, msg = msg.partition(": ")
t += prop[1:-1],
id = F"""{message["type"]}-{prop[1:-1]}"""
else:
id =F"""{message["type"]}-{msg.strip()}"""
else:
id = F"""{message["type"]}-{msg.strip()}"""
msg = message["extract"]
exceptions.append(Violation[id](msg.strip()))
if exceptions:
return exceptiongroup.ExceptionGroup(
F"""{sum(ct.values())} violations: """ + ", ".join(
F"""{v} {k}""" for k, v in ct.items()
),
exceptions)
exc = messages_to_violations(
messages := json.loads(pathlib.Path(file).read_text())["messages"]
); exc
messages_to_violations
to violations dynamically generates Exception
types for specific responses from the vnu validator.
print(
F"we created {len(Violation.map)} exceptions.",
*Violation.map.values(), sep="\n")