1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
|
"""Test type stubs for correctness where possible."""
import os
import pytest
import xmlsec
black = pytest.importorskip('black')
constants_stub_header = """
import sys
from typing import NamedTuple
if sys.version_info >= (3, 8):
from typing import Final
else:
from typing_extensions import Final
class __KeyData(NamedTuple): # __KeyData type
href: str
name: str
class __KeyDataNoHref(NamedTuple): # __KeyData type
href: None
name: str
class __Transform(NamedTuple): # __Transform type
href: str
name: str
usage: int
class __TransformNoHref(NamedTuple): # __Transform type
href: None
name: str
usage: int
"""
def gen_constants_stub():
"""
Generate contents of the file:`xmlsec/constants.pyi`.
Simply load all constants at runtime,
generate appropriate type hint for each constant type.
"""
def process_constant(name):
"""Generate line in stub file for constant name."""
obj = getattr(xmlsec.constants, name)
type_name = type(obj).__name__
if type_name in ('__KeyData', '__Transform') and obj.href is None:
type_name += 'NoHref'
return '{name}: Final[{type_name}]'.format(name=name, type_name=type_name)
names = list(sorted(name for name in dir(xmlsec.constants) if not name.startswith('__')))
lines = [process_constant(name) for name in names]
return constants_stub_header + os.linesep.join(lines)
def test_xmlsec_constants_stub(request):
"""
Generate the stub file for :mod:`xmlsec.constants` from existing code.
Compare it against the existing stub :file:`xmlsec/constants.pyi`.
"""
stub = request.config.rootpath / 'src' / 'xmlsec' / 'constants.pyi'
mode = black.FileMode(target_versions={black.TargetVersion.PY39}, line_length=130, is_pyi=True, string_normalization=False)
formatted = black.format_file_contents(gen_constants_stub(), fast=False, mode=mode)
assert formatted == stub.read_text()
|