diff --git a/rust/kcl-lib/src/simulation_tests.rs b/rust/kcl-lib/src/simulation_tests.rs index 1e459e001..16d6bf29c 100644 --- a/rust/kcl-lib/src/simulation_tests.rs +++ b/rust/kcl-lib/src/simulation_tests.rs @@ -2245,3 +2245,24 @@ mod assembly_mixed_units_cubes { super::execute(TEST_NAME, true).await } } +mod bad_units_in_annotation { + const TEST_NAME: &str = "bad_units_in_annotation"; + + /// Test parsing KCL. + #[test] + fn parse() { + super::parse(TEST_NAME) + } + + /// Test that parsing and unparsing KCL produces the original KCL input. + #[test] + fn unparse() { + super::unparse(TEST_NAME) + } + + /// Test that KCL is executed correctly. + #[tokio::test(flavor = "multi_thread")] + async fn kcl_test_execute() { + super::execute(TEST_NAME, true).await + } +} diff --git a/rust/kcl-lib/tests/bad_units_in_annotation/artifact_commands.snap b/rust/kcl-lib/tests/bad_units_in_annotation/artifact_commands.snap new file mode 100644 index 000000000..0a620912f --- /dev/null +++ b/rust/kcl-lib/tests/bad_units_in_annotation/artifact_commands.snap @@ -0,0 +1,56 @@ +--- +source: kcl-lib/src/simulation_tests.rs +description: Artifact commands bad_units_in_annotation.kcl +--- +[ + { + "cmdId": "[uuid]", + "range": [ + 0, + 0, + 0 + ], + "command": { + "type": "edge_lines_visible", + "hidden": false + } + }, + { + "cmdId": "[uuid]", + "range": [ + 0, + 0, + 0 + ], + "command": { + "type": "set_scene_units", + "unit": "mm" + } + }, + { + "cmdId": "[uuid]", + "range": [ + 0, + 0, + 0 + ], + "command": { + "type": "object_visible", + "object_id": "[uuid]", + "hidden": true + } + }, + { + "cmdId": "[uuid]", + "range": [ + 0, + 0, + 0 + ], + "command": { + "type": "object_visible", + "object_id": "[uuid]", + "hidden": true + } + } +] diff --git a/rust/kcl-lib/tests/bad_units_in_annotation/artifact_graph_flowchart.snap b/rust/kcl-lib/tests/bad_units_in_annotation/artifact_graph_flowchart.snap new file mode 100644 index 000000000..beb49103a --- /dev/null +++ b/rust/kcl-lib/tests/bad_units_in_annotation/artifact_graph_flowchart.snap @@ -0,0 +1,6 @@ +--- +source: kcl-lib/src/simulation_tests.rs +description: Artifact graph flowchart bad_units_in_annotation.kcl +extension: md +snapshot_kind: binary +--- diff --git a/rust/kcl-lib/tests/bad_units_in_annotation/artifact_graph_flowchart.snap.md b/rust/kcl-lib/tests/bad_units_in_annotation/artifact_graph_flowchart.snap.md new file mode 100644 index 000000000..13e533509 --- /dev/null +++ b/rust/kcl-lib/tests/bad_units_in_annotation/artifact_graph_flowchart.snap.md @@ -0,0 +1,3 @@ +```mermaid +flowchart LR +``` diff --git a/rust/kcl-lib/tests/bad_units_in_annotation/ast.snap b/rust/kcl-lib/tests/bad_units_in_annotation/ast.snap new file mode 100644 index 000000000..1b97a1cd0 --- /dev/null +++ b/rust/kcl-lib/tests/bad_units_in_annotation/ast.snap @@ -0,0 +1,847 @@ +--- +source: kcl-lib/src/simulation_tests.rs +description: Result of parsing bad_units_in_annotation.kcl +--- +{ + "Ok": { + "body": [ + { + "declaration": { + "end": 143, + "id": { + "end": 135, + "name": "oxygenRadius", + "start": 123, + "type": "Identifier" + }, + "init": { + "end": 143, + "raw": "0.066", + "start": 138, + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.066, + "suffix": "None" + } + }, + "start": 123, + "type": "VariableDeclarator" + }, + "end": 143, + "kind": "const", + "start": 123, + "type": "VariableDeclaration", + "type": "VariableDeclaration" + }, + { + "declaration": { + "end": 206, + "id": { + "end": 198, + "name": "hydrogenRadius", + "start": 184, + "type": "Identifier" + }, + "init": { + "end": 206, + "raw": "0.053", + "start": 201, + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.053, + "suffix": "None" + } + }, + "start": 184, + "type": "VariableDeclarator" + }, + "end": 206, + "kind": "const", + "start": 184, + "type": "VariableDeclaration", + "type": "VariableDeclaration" + }, + { + "declaration": { + "end": 278, + "id": { + "end": 270, + "name": "oxygenHydrogenDistance", + "start": 248, + "type": "Identifier" + }, + "init": { + "end": 278, + "raw": "0.096", + "start": 273, + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.096, + "suffix": "None" + } + }, + "start": 248, + "type": "VariableDeclarator" + }, + "end": 278, + "kind": "const", + "start": 248, + "type": "VariableDeclaration", + "type": "VariableDeclaration" + }, + { + "declaration": { + "end": 354, + "id": { + "end": 346, + "name": "bondAngle", + "start": 337, + "type": "Identifier" + }, + "init": { + "end": 354, + "raw": "104.5", + "start": 349, + "type": "Literal", + "type": "Literal", + "value": { + "value": 104.5, + "suffix": "None" + } + }, + "start": 337, + "type": "VariableDeclarator" + }, + "end": 354, + "kind": "const", + "start": 337, + "type": "VariableDeclaration", + "type": "VariableDeclaration" + }, + { + "declaration": { + "end": 580, + "id": { + "end": 447, + "name": "createAtom", + "start": 437, + "type": "Identifier" + }, + "init": { + "body": { + "body": [ + { + "argument": { + "body": [ + { + "arguments": [ + { + "end": 493, + "raw": "'XY'", + "start": 489, + "type": "Literal", + "type": "Literal", + "value": "XY" + } + ], + "callee": { + "end": 488, + "name": "startSketchOn", + "start": 475, + "type": "Identifier" + }, + "end": 494, + "start": 475, + "type": "CallExpression", + "type": "CallExpression" + }, + { + "arguments": [ + { + "type": "LabeledArg", + "label": { + "end": 515, + "name": "center", + "start": 509, + "type": "Identifier" + }, + "arg": { + "end": 524, + "name": "center", + "start": 518, + "type": "Identifier", + "type": "Identifier" + } + }, + { + "type": "LabeledArg", + "label": { + "end": 532, + "name": "radius", + "start": 526, + "type": "Identifier" + }, + "arg": { + "end": 541, + "name": "radius", + "start": 535, + "type": "Identifier", + "type": "Identifier" + } + } + ], + "callee": { + "end": 508, + "name": "circle", + "start": 502, + "type": "Identifier" + }, + "end": 542, + "start": 502, + "type": "CallExpressionKw", + "type": "CallExpressionKw", + "unlabeled": null + }, + { + "arguments": [ + { + "type": "LabeledArg", + "label": { + "end": 564, + "name": "length", + "start": 558, + "type": "Identifier" + }, + "arg": { + "end": 577, + "left": { + "end": 573, + "name": "radius", + "start": 567, + "type": "Identifier", + "type": "Identifier" + }, + "operator": "*", + "right": { + "end": 577, + "raw": "2", + "start": 576, + "type": "Literal", + "type": "Literal", + "value": { + "value": 2.0, + "suffix": "None" + } + }, + "start": 567, + "type": "BinaryExpression", + "type": "BinaryExpression" + } + } + ], + "callee": { + "end": 557, + "name": "extrude", + "start": 550, + "type": "Identifier" + }, + "end": 578, + "start": 550, + "type": "CallExpressionKw", + "type": "CallExpressionKw", + "unlabeled": null + } + ], + "end": 578, + "start": 475, + "type": "PipeExpression", + "type": "PipeExpression" + }, + "end": 578, + "start": 468, + "type": "ReturnStatement", + "type": "ReturnStatement" + } + ], + "end": 580, + "start": 464 + }, + "end": 580, + "params": [ + { + "type": "Parameter", + "identifier": { + "end": 454, + "name": "center", + "start": 448, + "type": "Identifier" + } + }, + { + "type": "Parameter", + "identifier": { + "end": 462, + "name": "radius", + "start": 456, + "type": "Identifier" + } + } + ], + "start": 447, + "type": "FunctionExpression", + "type": "FunctionExpression" + }, + "start": 437, + "type": "VariableDeclarator" + }, + "end": 580, + "kind": "fn", + "start": 434, + "type": "VariableDeclaration", + "type": "VariableDeclaration" + }, + { + "declaration": { + "end": 667, + "id": { + "end": 632, + "name": "oxygenAtom", + "start": 622, + "type": "Identifier" + }, + "init": { + "arguments": [ + { + "elements": [ + { + "end": 648, + "raw": "0", + "start": 647, + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.0, + "suffix": "None" + } + }, + { + "end": 651, + "raw": "0", + "start": 650, + "type": "Literal", + "type": "Literal", + "value": { + "value": 0.0, + "suffix": "None" + } + } + ], + "end": 652, + "start": 646, + "type": "ArrayExpression", + "type": "ArrayExpression" + }, + { + "end": 666, + "name": "oxygenRadius", + "start": 654, + "type": "Identifier", + "type": "Identifier" + } + ], + "callee": { + "end": 645, + "name": "createAtom", + "start": 635, + "type": "Identifier" + }, + "end": 667, + "start": 635, + "type": "CallExpression", + "type": "CallExpression" + }, + "start": 622, + "type": "VariableDeclarator" + }, + "end": 667, + "kind": "const", + "start": 622, + "type": "VariableDeclaration", + "type": "VariableDeclaration" + }, + { + "declaration": { + "end": 790, + "id": { + "end": 733, + "name": "hydrogenOffsetX", + "start": 718, + "type": "Identifier" + }, + "init": { + "end": 790, + "left": { + "end": 758, + "name": "oxygenHydrogenDistance", + "start": 736, + "type": "Identifier", + "type": "Identifier" + }, + "operator": "*", + "right": { + "arguments": [ + { + "arguments": [ + { + "end": 788, + "left": { + "end": 784, + "name": "bondAngle", + "start": 775, + "type": "Identifier", + "type": "Identifier" + }, + "operator": "/", + "right": { + "end": 788, + "raw": "2", + "start": 787, + "type": "Literal", + "type": "Literal", + "value": { + "value": 2.0, + "suffix": "None" + } + }, + "start": 775, + "type": "BinaryExpression", + "type": "BinaryExpression" + } + ], + "callee": { + "end": 774, + "name": "toRadians", + "start": 765, + "type": "Identifier" + }, + "end": 789, + "start": 765, + "type": "CallExpression", + "type": "CallExpression" + } + ], + "callee": { + "end": 764, + "name": "cos", + "start": 761, + "type": "Identifier" + }, + "end": 790, + "start": 761, + "type": "CallExpression", + "type": "CallExpression" + }, + "start": 736, + "type": "BinaryExpression", + "type": "BinaryExpression" + }, + "start": 718, + "type": "VariableDeclarator" + }, + "end": 790, + "kind": "const", + "start": 718, + "type": "VariableDeclaration", + "type": "VariableDeclaration" + }, + { + "declaration": { + "end": 863, + "id": { + "end": 806, + "name": "hydrogenOffsetY", + "start": 791, + "type": "Identifier" + }, + "init": { + "end": 863, + "left": { + "end": 831, + "name": "oxygenHydrogenDistance", + "start": 809, + "type": "Identifier", + "type": "Identifier" + }, + "operator": "*", + "right": { + "arguments": [ + { + "arguments": [ + { + "end": 861, + "left": { + "end": 857, + "name": "bondAngle", + "start": 848, + "type": "Identifier", + "type": "Identifier" + }, + "operator": "/", + "right": { + "end": 861, + "raw": "2", + "start": 860, + "type": "Literal", + "type": "Literal", + "value": { + "value": 2.0, + "suffix": "None" + } + }, + "start": 848, + "type": "BinaryExpression", + "type": "BinaryExpression" + } + ], + "callee": { + "end": 847, + "name": "toRadians", + "start": 838, + "type": "Identifier" + }, + "end": 862, + "start": 838, + "type": "CallExpression", + "type": "CallExpression" + } + ], + "callee": { + "end": 837, + "name": "sin", + "start": 834, + "type": "Identifier" + }, + "end": 863, + "start": 834, + "type": "CallExpression", + "type": "CallExpression" + }, + "start": 809, + "type": "BinaryExpression", + "type": "BinaryExpression" + }, + "start": 791, + "type": "VariableDeclarator" + }, + "end": 863, + "kind": "const", + "start": 791, + "type": "VariableDeclaration", + "type": "VariableDeclaration" + }, + { + "declaration": { + "end": 972, + "id": { + "end": 907, + "name": "hydrogenAtom1", + "start": 894, + "type": "Identifier" + }, + "init": { + "arguments": [ + { + "elements": [ + { + "end": 937, + "name": "hydrogenOffsetX", + "start": 922, + "type": "Identifier", + "type": "Identifier" + }, + { + "end": 954, + "name": "hydrogenOffsetY", + "start": 939, + "type": "Identifier", + "type": "Identifier" + } + ], + "end": 955, + "start": 921, + "type": "ArrayExpression", + "type": "ArrayExpression" + }, + { + "end": 971, + "name": "hydrogenRadius", + "start": 957, + "type": "Identifier", + "type": "Identifier" + } + ], + "callee": { + "end": 920, + "name": "createAtom", + "start": 910, + "type": "Identifier" + }, + "end": 972, + "start": 910, + "type": "CallExpression", + "type": "CallExpression" + }, + "start": 894, + "type": "VariableDeclarator" + }, + "end": 972, + "kind": "const", + "start": 894, + "type": "VariableDeclaration", + "type": "VariableDeclaration" + }, + { + "declaration": { + "end": 1052, + "id": { + "end": 986, + "name": "hydrogenAtom2", + "start": 973, + "type": "Identifier" + }, + "init": { + "arguments": [ + { + "elements": [ + { + "argument": { + "end": 1017, + "name": "hydrogenOffsetX", + "start": 1002, + "type": "Identifier", + "type": "Identifier" + }, + "end": 1017, + "operator": "-", + "start": 1001, + "type": "UnaryExpression", + "type": "UnaryExpression" + }, + { + "end": 1034, + "name": "hydrogenOffsetY", + "start": 1019, + "type": "Identifier", + "type": "Identifier" + } + ], + "end": 1035, + "start": 1000, + "type": "ArrayExpression", + "type": "ArrayExpression" + }, + { + "end": 1051, + "name": "hydrogenRadius", + "start": 1037, + "type": "Identifier", + "type": "Identifier" + } + ], + "callee": { + "end": 999, + "name": "createAtom", + "start": 989, + "type": "Identifier" + }, + "end": 1052, + "start": 989, + "type": "CallExpression", + "type": "CallExpression" + }, + "start": 973, + "type": "VariableDeclarator" + }, + "end": 1052, + "kind": "const", + "start": 973, + "type": "VariableDeclaration", + "type": "VariableDeclaration" + } + ], + "end": 1053, + "innerAttrs": [ + { + "end": 33, + "name": { + "end": 9, + "name": "settings", + "start": 1, + "type": "Identifier" + }, + "properties": [ + { + "end": 32, + "key": { + "end": 27, + "name": "defaultLengthUnit", + "start": 10, + "type": "Identifier" + }, + "start": 10, + "type": "ObjectProperty", + "value": { + "end": 32, + "name": "nm", + "start": 30, + "type": "Identifier", + "type": "Identifier" + } + } + ], + "start": 0, + "type": "Annotation" + } + ], + "nonCodeMeta": { + "nonCodeNodes": { + "0": [ + { + "end": 183, + "start": 143, + "type": "NonCodeNode", + "value": { + "type": "inlineComment", + "value": "Approximate radius of an oxygen atom", + "style": "line" + } + } + ], + "1": [ + { + "end": 247, + "start": 206, + "type": "NonCodeNode", + "value": { + "type": "inlineComment", + "value": "Approximate radius of a hydrogen atom", + "style": "line" + } + } + ], + "2": [ + { + "end": 336, + "start": 278, + "type": "NonCodeNode", + "value": { + "type": "inlineComment", + "value": "Approximate distance between oxygen and hydrogen atoms", + "style": "line" + } + } + ], + "3": [ + { + "end": 379, + "start": 354, + "type": "NonCodeNode", + "value": { + "type": "inlineComment", + "value": "Bond angle in degrees", + "style": "line" + } + }, + { + "end": 382, + "start": 379, + "type": "NonCodeNode", + "value": { + "type": "newLine" + } + }, + { + "end": 433, + "start": 382, + "type": "NonCodeNode", + "value": { + "type": "blockComment", + "value": "Function to create a sphere representing an atom", + "style": "line" + } + } + ], + "4": [ + { + "end": 621, + "start": 580, + "type": "NonCodeNode", + "value": { + "type": "newLineBlockComment", + "value": "Create the oxygen atom at the origin", + "style": "line" + } + } + ], + "5": [ + { + "end": 717, + "start": 667, + "type": "NonCodeNode", + "value": { + "type": "newLineBlockComment", + "value": "Calculate the positions of the hydrogen atoms", + "style": "line" + } + } + ], + "7": [ + { + "end": 893, + "start": 863, + "type": "NonCodeNode", + "value": { + "type": "newLineBlockComment", + "value": "Create the hydrogen atoms", + "style": "line" + } + } + ] + }, + "startNodes": [ + { + "end": 84, + "start": 34, + "type": "NonCodeNode", + "value": { + "type": "blockComment", + "value": "Generated by Text-to-CAD: draw a water molecule", + "style": "line" + } + }, + { + "end": 87, + "start": 84, + "type": "NonCodeNode", + "value": { + "type": "newLine" + } + }, + { + "end": 122, + "start": 87, + "type": "NonCodeNode", + "value": { + "type": "blockComment", + "value": "Constants for the water molecule", + "style": "line" + } + } + ] + }, + "start": 0 + } +} diff --git a/rust/kcl-lib/tests/bad_units_in_annotation/execution_error.snap b/rust/kcl-lib/tests/bad_units_in_annotation/execution_error.snap new file mode 100644 index 000000000..1978cac59 --- /dev/null +++ b/rust/kcl-lib/tests/bad_units_in_annotation/execution_error.snap @@ -0,0 +1,14 @@ +--- +source: kcl-lib/src/simulation_tests.rs +description: Error from executing bad_units_in_annotation.kcl +--- +KCL Semantic error + + × semantic: Unexpected value for length units: `nm`; expected one of `mm`, + │ `cm`, `m`, `in`, `ft`, `yd` + ╭─[1:1] + 1 │ @settings(defaultLengthUnit = nm) + · ────────────────┬──────────────── + · ╰── tests/bad_units_in_annotation/input.kcl + 2 │ // Generated by Text-to-CAD: draw a water molecule + ╰──── diff --git a/rust/kcl-lib/tests/bad_units_in_annotation/input.kcl b/rust/kcl-lib/tests/bad_units_in_annotation/input.kcl new file mode 100644 index 000000000..ea567d761 --- /dev/null +++ b/rust/kcl-lib/tests/bad_units_in_annotation/input.kcl @@ -0,0 +1,28 @@ +@settings(defaultLengthUnit = nm) +// Generated by Text-to-CAD: draw a water molecule + + +// Constants for the water molecule +oxygenRadius = 0.066 // Approximate radius of an oxygen atom +hydrogenRadius = 0.053 // Approximate radius of a hydrogen atom +oxygenHydrogenDistance = 0.096 // Approximate distance between oxygen and hydrogen atoms +bondAngle = 104.5 // Bond angle in degrees + + +// Function to create a sphere representing an atom +fn createAtom(center, radius) { + return startSketchOn('XY') + |> circle(center = center, radius = radius) + |> extrude(length = radius * 2) +} + +// Create the oxygen atom at the origin +oxygenAtom = createAtom([0, 0], oxygenRadius) + +// Calculate the positions of the hydrogen atoms +hydrogenOffsetX = oxygenHydrogenDistance * cos(toRadians(bondAngle / 2)) +hydrogenOffsetY = oxygenHydrogenDistance * sin(toRadians(bondAngle / 2)) + +// Create the hydrogen atoms +hydrogenAtom1 = createAtom([hydrogenOffsetX, hydrogenOffsetY], hydrogenRadius) +hydrogenAtom2 = createAtom([-hydrogenOffsetX, hydrogenOffsetY], hydrogenRadius) diff --git a/rust/kcl-lib/tests/bad_units_in_annotation/ops.snap b/rust/kcl-lib/tests/bad_units_in_annotation/ops.snap new file mode 100644 index 000000000..33d0ac85b --- /dev/null +++ b/rust/kcl-lib/tests/bad_units_in_annotation/ops.snap @@ -0,0 +1,5 @@ +--- +source: kcl-lib/src/simulation_tests.rs +description: Operations executed bad_units_in_annotation.kcl +--- +[] diff --git a/rust/kcl-python-bindings/src/lib.rs b/rust/kcl-python-bindings/src/lib.rs index 6a2c0cc53..ba0f6685a 100644 --- a/rust/kcl-python-bindings/src/lib.rs +++ b/rust/kcl-python-bindings/src/lib.rs @@ -401,10 +401,8 @@ async fn execute_and_export(path: String, export_format: FileExportFormat) -> Py .map_err(|err| pyo3::exceptions::PyException::new_err(err.to_string()))?; let program = kcl_lib::Program::parse_no_errs(&code) .map_err(|err| into_miette_for_parse(&path.display().to_string(), &code, err))?; - let settings = program.meta_settings()?.unwrap_or_default(); - let units: UnitLength = settings.default_length_units.into(); - let (ctx, mut state) = new_context_state(Some(path)) + let (ctx, mut state) = new_context_state(Some(path.clone())) .await .map_err(|err| pyo3::exceptions::PyException::new_err(err.to_string()))?; // Execute the program. @@ -412,6 +410,12 @@ async fn execute_and_export(path: String, export_format: FileExportFormat) -> Py .await .map_err(|err| into_miette(err, &code))?; + let settings = program + .meta_settings() + .map_err(|err| into_miette_for_parse(&path.display().to_string(), &code, err))? + .unwrap_or_default(); + let units: UnitLength = settings.default_length_units.into(); + // This will not return until there are files. let resp = ctx .engine @@ -445,8 +449,6 @@ async fn execute_code_and_export(code: String, export_format: FileExportFormat) .spawn(async move { let program = kcl_lib::Program::parse_no_errs(&code).map_err(|err| into_miette_for_parse("", &code, err))?; - let settings = program.meta_settings()?.unwrap_or_default(); - let units: UnitLength = settings.default_length_units.into(); let (ctx, mut state) = new_context_state(None) .await @@ -456,6 +458,12 @@ async fn execute_code_and_export(code: String, export_format: FileExportFormat) .await .map_err(|err| into_miette(err, &code))?; + let settings = program + .meta_settings() + .map_err(|err| into_miette_for_parse("", &code, err))? + .unwrap_or_default(); + let units: UnitLength = settings.default_length_units.into(); + // This will not return until there are files. let resp = ctx .engine diff --git a/rust/kcl-python-bindings/tests/tests.py b/rust/kcl-python-bindings/tests/tests.py index ad013e2ae..5dba675de 100755 --- a/rust/kcl-python-bindings/tests/tests.py +++ b/rust/kcl-python-bindings/tests/tests.py @@ -9,6 +9,7 @@ files_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "..", "fil kcl_dir = os.path.join( os.path.dirname(os.path.realpath(__file__)), "..", "..", "kcl-lib" ) +tests_dir = os.path.join(kcl_dir, "tests") lego_file = os.path.join(kcl_dir, "e2e", "executor", "inputs", "lego.kcl") walkie_talkie_dir = os.path.join( os.path.dirname(os.path.realpath(__file__)), @@ -146,3 +147,20 @@ def test_kcl_lint(): finding_title = finding.title assert finding_title is not None assert len(finding_title) > 0 + + +@pytest.mark.asyncio +async def test_kcl_execute_code_and_export_with_bad_units(): + bad_units_file = os.path.join(tests_dir, "bad_units_in_annotation", "input.kcl") + # Read from a file. + with open(bad_units_file, "r") as f: + code = str(f.read()) + assert code is not None + assert len(code) > 0 + try: + await kcl.execute_code_and_export(code, kcl.FileExportFormat.Step) + except Exception as e: + assert e is not None + assert len(str(e)) > 0 + print(e) + assert "[1:1]" in str(e)