fix: fixed script work on distributed apps
This commit is contained in:
@@ -1,5 +1,45 @@
|
|||||||
import { BDS_PYTHON_API_CONTRACT_V1 } from './pythonApiContractV1';
|
import { BDS_PYTHON_API_CONTRACT_V1 } from './pythonApiContractV1';
|
||||||
|
|
||||||
|
const PYTHON_RESERVED_KEYWORDS = new Set([
|
||||||
|
'false',
|
||||||
|
'none',
|
||||||
|
'true',
|
||||||
|
'and',
|
||||||
|
'as',
|
||||||
|
'assert',
|
||||||
|
'async',
|
||||||
|
'await',
|
||||||
|
'break',
|
||||||
|
'class',
|
||||||
|
'continue',
|
||||||
|
'def',
|
||||||
|
'del',
|
||||||
|
'elif',
|
||||||
|
'else',
|
||||||
|
'except',
|
||||||
|
'finally',
|
||||||
|
'for',
|
||||||
|
'from',
|
||||||
|
'global',
|
||||||
|
'if',
|
||||||
|
'import',
|
||||||
|
'in',
|
||||||
|
'is',
|
||||||
|
'lambda',
|
||||||
|
'nonlocal',
|
||||||
|
'not',
|
||||||
|
'or',
|
||||||
|
'pass',
|
||||||
|
'raise',
|
||||||
|
'return',
|
||||||
|
'try',
|
||||||
|
'while',
|
||||||
|
'with',
|
||||||
|
'yield',
|
||||||
|
'match',
|
||||||
|
'case',
|
||||||
|
]);
|
||||||
|
|
||||||
function toSnakeCase(value: string): string {
|
function toSnakeCase(value: string): string {
|
||||||
return value
|
return value
|
||||||
.replace(/([a-z0-9])([A-Z])/g, '$1_$2')
|
.replace(/([a-z0-9])([A-Z])/g, '$1_$2')
|
||||||
@@ -12,6 +52,23 @@ function quotePython(value: string): string {
|
|||||||
return value.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
return value.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toPythonIdentifier(value: string): string {
|
||||||
|
let identifier = toSnakeCase(value);
|
||||||
|
if (!identifier) {
|
||||||
|
identifier = '_';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (/^[0-9]/.test(identifier)) {
|
||||||
|
identifier = `_${identifier}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PYTHON_RESERVED_KEYWORDS.has(identifier)) {
|
||||||
|
identifier = `${identifier}_`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return identifier;
|
||||||
|
}
|
||||||
|
|
||||||
function buildPythonMethod(method: {
|
function buildPythonMethod(method: {
|
||||||
method: string;
|
method: string;
|
||||||
description: string;
|
description: string;
|
||||||
@@ -22,10 +79,10 @@ function buildPythonMethod(method: {
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
const pythonMethodName = toSnakeCase(member);
|
const pythonMethodName = toPythonIdentifier(member);
|
||||||
const pythonParams = method.params.map((param) => ({
|
const pythonParams = method.params.map((param) => ({
|
||||||
sourceName: param.name,
|
sourceName: param.name,
|
||||||
pythonName: toSnakeCase(param.name),
|
pythonName: toPythonIdentifier(param.name),
|
||||||
required: param.required,
|
required: param.required,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -90,7 +147,7 @@ export function generatePythonApiModuleV1(): string {
|
|||||||
|
|
||||||
const namespaceAssignments = Array.from(namespaceMap.keys())
|
const namespaceAssignments = Array.from(namespaceMap.keys())
|
||||||
.sort((left, right) => left.localeCompare(right))
|
.sort((left, right) => left.localeCompare(right))
|
||||||
.map((namespace) => ` self.${toSnakeCase(namespace)} = ${namespace[0].toUpperCase()}${namespace.slice(1)}Api(transport)`)
|
.map((namespace) => ` self.${toPythonIdentifier(namespace)} = ${namespace[0].toUpperCase()}${namespace.slice(1)}Api(transport)`)
|
||||||
.join('\n');
|
.join('\n');
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
|||||||
@@ -78,4 +78,12 @@ describe('generatePythonApiModuleV1', () => {
|
|||||||
expect(moduleCode).toContain('class BdsApi:');
|
expect(moduleCode).toContain('class BdsApi:');
|
||||||
expect(moduleCode).toContain('bds = BdsApi(_transport)');
|
expect(moduleCode).toContain('bds = BdsApi(_transport)');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('escapes python keyword method names to valid identifiers', () => {
|
||||||
|
const moduleCode = generatePythonApiModuleV1();
|
||||||
|
|
||||||
|
expect(moduleCode).toContain('return await self._transport.call("media.import", { "sourcePath": source_path, "metadata": metadata })');
|
||||||
|
expect(moduleCode).toContain('async def import_(self, source_path, metadata=None):');
|
||||||
|
expect(moduleCode).not.toContain('async def import(self, source_path, metadata=None):');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
Reference in New Issue
Block a user