Skip to content

Commit

Permalink
feat: update to safe-ds-runner v0.7.0 (#906)
Browse files Browse the repository at this point in the history
### Summary of Changes

Adjust code generation to runner API changes (see
Safe-DS/Runner#54).
  • Loading branch information
lars-reimann authored Feb 22, 2024
1 parent 048d9cf commit 070f406
Show file tree
Hide file tree
Showing 15 changed files with 77 additions and 113 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ const BLOCK_LAMBDA_PREFIX = `${CODEGEN_PREFIX}block_lambda_`;
const BLOCK_LAMBDA_RESULT_PREFIX = `${CODEGEN_PREFIX}block_lambda_result_`;
const YIELD_PREFIX = `${CODEGEN_PREFIX}yield_`;

const RUNNER_SERVER_PIPELINE_MANAGER_PACKAGE = 'safeds_runner.server.pipeline_manager';
const RUNNER_PACKAGE = 'safeds_runner';
const PYTHON_INDENT = ' ';

const SPACING = new CompositeGeneratorNode(NL, NL);
Expand Down Expand Up @@ -648,11 +648,11 @@ export class SafeDsPythonGenerator {
if (frame.isInsidePipeline && !generateLambda && !frame.disableRunnerIntegration) {
for (const savableAssignment of assignees.filter(isSdsPlaceholder)) {
// should always be SdsPlaceholder
frame.addImport({ importPath: RUNNER_SERVER_PIPELINE_MANAGER_PACKAGE });
frame.addImport({ importPath: RUNNER_PACKAGE });
assignmentStatements.push(
expandTracedToNode(
savableAssignment,
)`${RUNNER_SERVER_PIPELINE_MANAGER_PACKAGE}.runner_save_placeholder('${savableAssignment.name}', ${savableAssignment.name})`,
)`${RUNNER_PACKAGE}.save_placeholder('${savableAssignment.name}', ${savableAssignment.name})`,
);
}
}
Expand Down Expand Up @@ -954,15 +954,15 @@ export class SafeDsPythonGenerator {
if (!this.isMemoizableCall(expression) || frame.disableRunnerIntegration) {
return generatedPythonCall;
}
frame.addImport({ importPath: RUNNER_SERVER_PIPELINE_MANAGER_PACKAGE });
frame.addImport({ importPath: RUNNER_PACKAGE });
const hiddenParameters = this.getMemoizedCallHiddenParameters(expression, frame);
const callable = this.nodeMapper.callToCallable(expression);
const memoizedArgs = getParameters(callable).map(
(parameter) => this.nodeMapper.callToParameterValue(expression, parameter)!,
);
return expandTracedToNode(
expression,
)`${RUNNER_SERVER_PIPELINE_MANAGER_PACKAGE}.runner_memoized_function_call("${this.generateFullyQualifiedFunctionName(
)`${RUNNER_PACKAGE}.memoized_call("${this.generateFullyQualifiedFunctionName(
expression,
)}", lambda *_ : ${generatedPythonCall}, [${joinTracedToNode(expression.argumentList, 'arguments')(
memoizedArgs,
Expand All @@ -983,7 +983,7 @@ export class SafeDsPythonGenerator {
frame: GenerationInfoFrame,
thisParam: CompositeGeneratorNode | undefined = undefined,
): CompositeGeneratorNode {
frame.addImport({ importPath: RUNNER_SERVER_PIPELINE_MANAGER_PACKAGE });
frame.addImport({ importPath: RUNNER_PACKAGE });
const hiddenParameters = this.getMemoizedCallHiddenParameters(expression, frame);
const callable = this.nodeMapper.callToCallable(expression);
const memoizedArgs = getParameters(callable).map(
Expand All @@ -995,9 +995,7 @@ export class SafeDsPythonGenerator {
Parameter.isOptional(this.nodeMapper.argumentToParameter(arg)),
);
const fullyQualifiedTargetName = this.generateFullyQualifiedFunctionName(expression);
return expandTracedToNode(
expression,
)`${RUNNER_SERVER_PIPELINE_MANAGER_PACKAGE}.runner_memoized_function_call("${fullyQualifiedTargetName}", ${
return expandTracedToNode(expression)`${RUNNER_PACKAGE}.memoized_call("${fullyQualifiedTargetName}", ${
containsOptionalArgs ? 'lambda *_ : ' : ''
}${
containsOptionalArgs
Expand Down Expand Up @@ -1026,9 +1024,7 @@ export class SafeDsPythonGenerator {
if (reason instanceof FileRead) {
if (typeof reason.path === 'string') {
hiddenParameters.push(
expandTracedToNode(
expression,
)`${RUNNER_SERVER_PIPELINE_MANAGER_PACKAGE}.runner_filemtime('${reason.path}')`,
expandTracedToNode(expression)`${RUNNER_PACKAGE}.file_mtime('${reason.path}')`,
);
} else if (isSdsParameter(reason.path)) {
const argument = this.nodeMapper
Expand All @@ -1041,9 +1037,7 @@ export class SafeDsPythonGenerator {
);
}
hiddenParameters.push(
expandTracedToNode(
argument,
)`${RUNNER_SERVER_PIPELINE_MANAGER_PACKAGE}.runner_filemtime(${this.generateArgument(
expandTracedToNode(argument)`${RUNNER_PACKAGE}.file_mtime(${this.generateArgument(
argument,
frame,
)})`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import semver from 'semver';

// Most of the functionality cannot be tested automatically as a functioning runner setup would always be required

const SUPPORTED_VERSION_RANGE = '>=0.6.0 <0.7.0';
const SUPPORTED_VERSION_RANGE = '~0.7.0';

export class SafeDsRunner {
private readonly annotations: SafeDsAnnotations;
Expand Down
50 changes: 10 additions & 40 deletions packages/safe-ds-lang/tests/language/generation/creator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {
uriToShortenedTestResourceName,
} from '../../helpers/testResources.js';
import path from 'path';
import fs from 'fs';
import { createSafeDsServices } from '../../../src/language/index.js';
import { ErrorsInCodeError, getErrorsAtURI } from '../../helpers/diagnostics.js';
import { findTestChecks } from '../../helpers/testChecks.js';
Expand All @@ -29,7 +28,7 @@ export const createGenerationTests = async (): Promise<GenerationTest[]> => {

const createGenerationTest = async (parentDirectory: URI, inputUris: URI[]): Promise<GenerationTest> => {
const outputRoot = URI.file(path.join(parentDirectory.fsPath, 'generated'));
const expectedOutputFiles = readExpectedOutputFiles(outputRoot);
const expectedOutputUris = listExpectedOutputFiles(outputRoot);
let runUntil: Location | undefined;

// Load all files, so they get linked
Expand Down Expand Up @@ -80,33 +79,19 @@ const createGenerationTest = async (parentDirectory: URI, inputUris: URI[]): Pro
testName: `[${shortenedResourceName}]`,
inputUris,
outputRoot,
expectedOutputFiles,
expectedOutputUris,
runUntil,
disableRunnerIntegration: !shortenedResourceName.startsWith(runnerIntegration),
};
};

/**
* Read all expected output files.
* List all expected output files.
*
* @param outputRoot Where the actual output files are supposed to be located.
* @param outputRoot The directory, where output files are located.
*/
const readExpectedOutputFiles = (outputRoot: URI): ExpectedOutputFile[] => {
return listTestFilesWithExtensions(uriToShortenedTestResourceName(outputRoot), ['py', 'map'])
.sort((a, b) => {
// List .py files first, so they get compared first
if (a.fsPath.endsWith('.map') && b.fsPath.endsWith('.py')) {
return 1;
}

return -1;
})
.map((uri) => {
return {
uri,
code: fs.readFileSync(uri.fsPath).toString(),
};
});
const listExpectedOutputFiles = (outputRoot: URI): URI[] => {
return listTestFilesWithExtensions(uriToShortenedTestResourceName(outputRoot), ['py', 'map']);
};

/**
Expand All @@ -122,7 +107,7 @@ const invalidTest = (level: 'FILE' | 'SUITE', error: TestDescriptionError): Gene
testName,
inputUris: [],
outputRoot: URI.file(''),
expectedOutputFiles: [],
expectedOutputUris: [],
error,
disableRunnerIntegration: false,
};
Expand All @@ -143,36 +128,21 @@ interface GenerationTest extends TestDescription {
outputRoot: URI;

/**
* The expected generated code.
* The expected output files.
*/
expectedOutputFiles: ExpectedOutputFile[];
expectedOutputUris: URI[];

/**
* Location after which execution should be stopped.
*/
runUntil?: Location;

/**
* Whether the test should run with runner integration (memoization & placeholder saving) disabled
* Whether the test should run with runner integration (memoization & placeholder saving) disabled.
*/
disableRunnerIntegration: boolean;
}

/**
* A file containing the expected output.
*/
interface ExpectedOutputFile {
/**
* URI of the output file.
*/
uri: URI;

/**
* Content of the output file.
*/
code: string;
}

/**
* Found multiple test checks.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ describe('generation', async () => {

// File paths must match
const actualOutputPaths = Array.from(actualOutputs.keys()).sort();
const expectedOutputPaths = test.expectedOutputFiles.map((file) => file.uri.toString()).sort();
const expectedOutputPaths = test.expectedOutputUris.map((uri) => uri.toString()).sort();
expect(actualOutputPaths).toStrictEqual(expectedOutputPaths);
});
});
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Imports ----------------------------------------------------------------------

import safeds_runner.server.pipeline_manager
import safeds_runner
from typing import Any, Callable, TypeVar

# Type variables ---------------------------------------------------------------
Expand All @@ -15,20 +15,20 @@ def __gen_null_safe_call(receiver: Any, callable: Callable[[], __gen_T]) -> __ge
# Pipelines --------------------------------------------------------------------

def test():
f(safeds_runner.server.pipeline_manager.runner_memoized_function_call("tests.generator.callWithRunnerIntegration.g", lambda *_ : g(1, param2=2), [1, 2], []))
f(safeds_runner.server.pipeline_manager.runner_memoized_function_call("tests.generator.callWithRunnerIntegration.g", lambda *_ : g(2, param2=1), [2, 1], []))
f(safeds_runner.server.pipeline_manager.runner_memoized_function_call("tests.generator.callWithRunnerIntegration.h", lambda *_ : h(1, param_2=2), [1, 2], []))
f(safeds_runner.server.pipeline_manager.runner_memoized_function_call("tests.generator.callWithRunnerIntegration.h", lambda *_ : h(2, param_2=1), [2, 1], []))
f(safeds_runner.server.pipeline_manager.runner_memoized_function_call("tests.generator.callWithRunnerIntegration.h", h, [2, 0], []))
f(safeds_runner.memoized_call("tests.generator.callWithRunnerIntegration.g", lambda *_ : g(1, param2=2), [1, 2], []))
f(safeds_runner.memoized_call("tests.generator.callWithRunnerIntegration.g", lambda *_ : g(2, param2=1), [2, 1], []))
f(safeds_runner.memoized_call("tests.generator.callWithRunnerIntegration.h", lambda *_ : h(1, param_2=2), [1, 2], []))
f(safeds_runner.memoized_call("tests.generator.callWithRunnerIntegration.h", lambda *_ : h(2, param_2=1), [2, 1], []))
f(safeds_runner.memoized_call("tests.generator.callWithRunnerIntegration.h", h, [2, 0], []))
'abc'.i()
'abc'.j(123)
k(456, 1.23)
__gen_null_safe_call(f, lambda: f(safeds_runner.server.pipeline_manager.runner_memoized_function_call("tests.generator.callWithRunnerIntegration.g", lambda *_ : g(1, param2=2), [1, 2], [])))
__gen_null_safe_call(f, lambda: f(safeds_runner.server.pipeline_manager.runner_memoized_function_call("tests.generator.callWithRunnerIntegration.g", lambda *_ : g(2, param2=1), [2, 1], [])))
__gen_null_safe_call(f, lambda: f(safeds_runner.server.pipeline_manager.runner_memoized_function_call("tests.generator.callWithRunnerIntegration.h", lambda *_ : h(1, param_2=2), [1, 2], [])))
__gen_null_safe_call(f, lambda: f(safeds_runner.server.pipeline_manager.runner_memoized_function_call("tests.generator.callWithRunnerIntegration.h", lambda *_ : h(2, param_2=1), [2, 1], [])))
__gen_null_safe_call(f, lambda: f(safeds_runner.server.pipeline_manager.runner_memoized_function_call("tests.generator.callWithRunnerIntegration.h", h, [2, 0], [])))
__gen_null_safe_call(f, lambda: f(safeds_runner.memoized_call("tests.generator.callWithRunnerIntegration.g", lambda *_ : g(1, param2=2), [1, 2], [])))
__gen_null_safe_call(f, lambda: f(safeds_runner.memoized_call("tests.generator.callWithRunnerIntegration.g", lambda *_ : g(2, param2=1), [2, 1], [])))
__gen_null_safe_call(f, lambda: f(safeds_runner.memoized_call("tests.generator.callWithRunnerIntegration.h", lambda *_ : h(1, param_2=2), [1, 2], [])))
__gen_null_safe_call(f, lambda: f(safeds_runner.memoized_call("tests.generator.callWithRunnerIntegration.h", lambda *_ : h(2, param_2=1), [2, 1], [])))
__gen_null_safe_call(f, lambda: f(safeds_runner.memoized_call("tests.generator.callWithRunnerIntegration.h", h, [2, 0], [])))
__gen_null_safe_call(i, lambda: 'abc'.i())
__gen_null_safe_call(j, lambda: 'abc'.j(123))
__gen_null_safe_call(k, lambda: k(456, 1.23))
f(safeds_runner.server.pipeline_manager.runner_memoized_function_call("tests.generator.callWithRunnerIntegration.readFile", readFile, [], [safeds_runner.server.pipeline_manager.runner_filemtime('a.txt')]))
f(safeds_runner.memoized_call("tests.generator.callWithRunnerIntegration.readFile", readFile, [], [safeds_runner.file_mtime('a.txt')]))

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Imports ----------------------------------------------------------------------

import safeds_runner.server.pipeline_manager
import safeds_runner
from typing import Any, TypeVar

# Type variables ---------------------------------------------------------------
Expand All @@ -15,14 +15,14 @@ def __gen_null_safe_member_access(receiver: Any, member_name: str) -> __gen_T |
# Pipelines --------------------------------------------------------------------

def test():
f(safeds_runner.server.pipeline_manager.runner_memoized_function_call("tests.generator.memberAccessWithRunnerIntegration.g", g, [], []))
f(safeds_runner.server.pipeline_manager.runner_memoized_function_call("tests.generator.memberAccessWithRunnerIntegration.h", h, [], [])[0])
f(safeds_runner.server.pipeline_manager.runner_memoized_function_call("tests.generator.memberAccessWithRunnerIntegration.h", h, [], [])[1])
f(safeds_runner.server.pipeline_manager.runner_memoized_function_call("tests.generator.memberAccessWithRunnerIntegration.C", C, [], []).a)
f(safeds_runner.server.pipeline_manager.runner_memoized_function_call("tests.generator.memberAccessWithRunnerIntegration.C", C, [], []).c)
f(__gen_null_safe_member_access(safeds_runner.server.pipeline_manager.runner_memoized_function_call("tests.generator.memberAccessWithRunnerIntegration.factory", factory, [], []), 'a'))
f(__gen_null_safe_member_access(safeds_runner.server.pipeline_manager.runner_memoized_function_call("tests.generator.memberAccessWithRunnerIntegration.factory", factory, [], []), 'c'))
f(safeds_runner.server.pipeline_manager.runner_memoized_function_call("tests.generator.memberAccessWithRunnerIntegration.C.i", lambda *_ : 1.i(safeds_runner.server.pipeline_manager.runner_memoized_function_call("tests.generator.memberAccessWithRunnerIntegration.C", C, [], [])), [1], []))
f(safeds_runner.server.pipeline_manager.runner_memoized_function_call("tests.generator.memberAccessWithRunnerIntegration.C.j", C.j, [safeds_runner.server.pipeline_manager.runner_memoized_function_call("tests.generator.memberAccessWithRunnerIntegration.C", C, [], []), 123], []))
f(safeds_runner.server.pipeline_manager.runner_memoized_function_call("tests.generator.memberAccessWithRunnerIntegration.C.k2", C.k2, [safeds_runner.server.pipeline_manager.runner_memoized_function_call("tests.generator.memberAccessWithRunnerIntegration.C", C, [], []), 'abc'], []))
f(safeds_runner.server.pipeline_manager.runner_memoized_function_call("tests.generator.memberAccessWithRunnerIntegration.C.from_csv_file", C.from_csv_file, ['abc.csv'], [safeds_runner.server.pipeline_manager.runner_filemtime('abc.csv')]))
f(safeds_runner.memoized_call("tests.generator.memberAccessWithRunnerIntegration.g", g, [], []))
f(safeds_runner.memoized_call("tests.generator.memberAccessWithRunnerIntegration.h", h, [], [])[0])
f(safeds_runner.memoized_call("tests.generator.memberAccessWithRunnerIntegration.h", h, [], [])[1])
f(safeds_runner.memoized_call("tests.generator.memberAccessWithRunnerIntegration.C", C, [], []).a)
f(safeds_runner.memoized_call("tests.generator.memberAccessWithRunnerIntegration.C", C, [], []).c)
f(__gen_null_safe_member_access(safeds_runner.memoized_call("tests.generator.memberAccessWithRunnerIntegration.factory", factory, [], []), 'a'))
f(__gen_null_safe_member_access(safeds_runner.memoized_call("tests.generator.memberAccessWithRunnerIntegration.factory", factory, [], []), 'c'))
f(safeds_runner.memoized_call("tests.generator.memberAccessWithRunnerIntegration.C.i", lambda *_ : 1.i(safeds_runner.memoized_call("tests.generator.memberAccessWithRunnerIntegration.C", C, [], [])), [1], []))
f(safeds_runner.memoized_call("tests.generator.memberAccessWithRunnerIntegration.C.j", C.j, [safeds_runner.memoized_call("tests.generator.memberAccessWithRunnerIntegration.C", C, [], []), 123], []))
f(safeds_runner.memoized_call("tests.generator.memberAccessWithRunnerIntegration.C.k2", C.k2, [safeds_runner.memoized_call("tests.generator.memberAccessWithRunnerIntegration.C", C, [], []), 'abc'], []))
f(safeds_runner.memoized_call("tests.generator.memberAccessWithRunnerIntegration.C.from_csv_file", C.from_csv_file, ['abc.csv'], [safeds_runner.file_mtime('abc.csv')]))
Loading

0 comments on commit 070f406

Please sign in to comment.