in packages/jsii-pacmak/lib/targets/python.ts [3194:3259]
function emitParameterTypeChecks(
code: CodeMaker,
context: EmitContext,
params: readonly string[],
fqn: string,
): boolean {
if (!context.runtimeTypeChecking) {
return false;
}
const paramInfo = params.map((param) => {
const [name] = param.split(/\s*[:=#]\s*/, 1);
if (name === '*') {
return { kwargsMark: true };
} else if (name.startsWith('*')) {
return { name: name.slice(1), is_rest: true };
}
return { name };
});
const paramNames = paramInfo
.filter((param) => param.name != null)
.map((param) => param.name!.split(/\s*:\s*/)[0]);
const typesVar = slugifyAsNeeded('type_hints', paramNames);
let openedBlock = false;
for (const { is_rest, kwargsMark, name } of paramInfo) {
if (kwargsMark) {
if (!context.runtimeTypeCheckKwargs) {
// This is the keyword-args separator, we won't check keyword arguments here because the kwargs will be rolled
// up into a struct instance, and that struct's constructor will be checking again...
break;
}
// Skip this (there is nothing to be checked as this is just a marker...)
continue;
}
if (!openedBlock) {
code.openBlock('if __debug__');
code.line(
`${typesVar} = ${context.typeCheckingHelper.getTypeHints(fqn, params)}`,
);
openedBlock = true;
}
let expectedType = `${typesVar}[${JSON.stringify(name)}]`;
let comment = '';
if (is_rest) {
// This is a vararg, so the value will appear as a tuple.
expectedType = `typing.Tuple[${expectedType}, ...]`;
// Need to ignore reportGeneralTypeIssues because pyright incorrectly parses that as a type annotation 😒
comment = ' # pyright: ignore [reportGeneralTypeIssues]';
}
code.line(
`check_type(argname=${JSON.stringify(
`argument ${name}`,
)}, value=${name}, expected_type=${expectedType})${comment}`,
);
}
if (openedBlock) {
code.closeBlock();
return true;
}
// We did not reference type annotations data if we never opened a type-checking block.
return false;
}