Skip to content

Latest commit

 

History

History
234 lines (169 loc) · 10.4 KB

MagicCommands.md

File metadata and controls

234 lines (169 loc) · 10.4 KB

Magic Commands

Some of this documentation is a work in progress.

The Swift kernel has various built-in commands for downloading dependencies and interacting with the operating system. These commands start with % and behave like the IPython magic commands. They take the role of inline Shell commands in Python notebooks, which start with !.

Magic commands are implemented in PreprocessAndExecute.swift and the SwiftPMEngine directory.

Syntax

Each magic command accepts arguments styled like command-line arguments, unless stated otherwise. Commands initially pass into Python Regex library (re), which extracts the % directive. A Shell lexer (shlex) parses the rest of the line.

This styling is a feature coming in Swift-Colab v2.3. In the current release (v2.2), magic commands have varied and inconsistent restrictions on accepted formats.

Arguments may be entered with or without quotes, and both single and double quotes work. To facilitate appropriate syntax highlighting and improve legibility, wrap text-like arguments in double quotes. The Swift parser treats these like string literals. For command-line flags, do not use quotes.

// Double quotes for the file path.
// No quotes for the executable name.
%system unzip "x10-binary.zip"

// Single quotes for the inline Swift code.
// No quotes for the Swift module name.
%install '.package(url: "https://...", branch: "main")' Module

// Double quotes for the '-L' argument, which contains a file path.
// No quotes for the command-line flag '-Xlinker'.
%install-swiftpm-flags -Xlinker "-L/content/Library/..."

// No quotes for the special '$clear' argument.
%install-swiftpm-flags $clear

// Double quotes for the file path.
%include "EnableIPythonDisplay.swift"

Execution

Before executing a code block, the kernel extracts (almost*) all magic commands and executes them in the order they appear. The commands are oblivious to the surrounding Swift code. In contrast, a Python notebook executes Shell commands according to the control flow of their surrounding code. This code in a Swift notebook:

*%include is an exception to this rule.

for _ in 0..<2 {
%system echo "A"
  print("B")
%system echo "C"
  print("D")
}

Produces (replacing newlines with spaces):

A C B D B D

While this code in a Python notebook:

for i in range(2):
  !echo A
  print('B')
  !echo C
  print('D')

Produces (replacing newlines with spaces):

A B C D A B C D

Commands

%include

%include PATH 

Inject code from a source file into the interpreter. The %include command substitutes with the source code located at PATH, inserting at the command's exact location* within the notebook cell.

  • PATH - File path relative to the current working directory (/content). If the file does not exist there, it looks inside /opt/swift/include.

Source code injected by %include may not contain magic commands.

PATH may omit the first forward slash; prefer this style when specifying just a file name. The path registers as /content/PATH internally. Prepending a slash creates /content//PATH, which resolves to the same location.

*In Swift-Colab v2.0-2.2, the command silently failed if you previously included PATH during the current Jupyter session. This protective mechanism prevented duplication of the IPythonDisplay.socket Python object in EnableIPythonDisplay.swift.

The behavior deviated from swift-jupyter and the magic command's semantic meaning. Thus, it was restored in v2.3 (not yet released).

%install

%install SPEC MODULE [MODULE ...]

Build a Swift package for use inside a notebook. If a previous Jupyter session executed this command, import the cached build products. To avoid recompilation, the SwiftPM flags should match those present when the %install command last executed.

  • SPEC - Specification to insert into a package manifest. Prefer to use SwiftPM version 5.0* syntax, such as .package(url: "", branch: "")), although v4.2 syntax also works for backward compatibility. Place the specification between single quotes to avoid colliding with string literals, which use double quotes.
  • MODULE - Each package product the debugger should build and import.

*v5.0 syntax will be supported in Swift-Colab v2.4. Until that happens, use v4.2 syntax such as .package(url: "", .branch("")).

Although the SwiftPM engine utilizes cached build products, LLDB does not automatically detect exported modules. %install tells the Jupyter kernel to locate and optionally recompile each MODULE. Always run the command before using external dependencies in a notebook.

To build packages stored on the local computer, pass $cwd into .package(path: ""). This keyword substitutes with the current working directory, which is always /content. The example below demonstrates directory substitution.

// Install the SimplePackage package that's in the kernel's working directory.
%install '.package(path: "$cwd/SimplePackage")' SimplePackage

%install-extra-include-command

%install-extra-include-command EXECUTABLE [ARGUMENT ...]
  • Link to forum thread that initiated this
  • Using this command seems like a bad idea, based on problem 4 in this comment. Perhaps it will be usable in Swift-Colab v2.4.

%install-location

%install-location PATH
  • Link to PR that initiated this
  • Has $cwd substitution (describe).
  • Long-term cache build products with Google Drive.
  • Switching install location may impact future build performance, because it changes which cached build products are visible to the Jupyter kernel.
  • Packages cached in the previous location are still available to %install-swiftpm-import. They are also available to the interpreter with import Module, but I'm not sure why. I haven't been able to prevent packages from being importable by switching the install location.

%install-swiftpm-flags

%install-swiftpm-flags [FLAG ...]
%install-swiftpm-flags $clear
  • Appends the arguments to a growing list of flags every time you execute
  • The $clear flag was added to allow emptying SwiftPM flags. If you have $clear before other flags, it resets then adds the flags to the right of it.
  • Explain workaround for -Xcc -I/... flags, but for now just hyperlink: problem 4 in this comment.
  • $clear also resets anything added by %install-swiftpm-environment or %install-swiftpm-import, but not %install-location.

%system

%system EXECUTABLE [ARGUMENT ...]
  • Executes a command-line command, executes before the code in the cell
  • Forwards stdout just like Python bash commands, but not stdin (tracked by #17)
  • Works in Python mode because it’s a Jupyter magic command. The Python mode version prints the output like a comma-separated list instead of actual stdout.
%system cd "sample_data" && touch "$(uname -m).sh"

The code above works and makes a file called x86_64.sh in /content/sample_data.