or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

context-management.mdengine-language-management.mdindex.mdjava-python-interop.mdsecurity-access-control.mdsource-management.mdvalue-operations.md

source-management.mddocs/

0

# Source Management

1

2

Source management provides comprehensive functionality for creating, configuring, and managing Python source code objects. The Source class abstracts different input formats and provides metadata management, automatic language detection, and flexible source creation patterns.

3

4

## Capabilities

5

6

### Source Creation

7

8

Create Source objects from various input formats including strings, files, URLs, and streams.

9

10

```java { .api }

11

/**

12

* Creates a builder for constructing Source objects from string content

13

* @param language the language identifier (use "python" for Python)

14

* @param characters the source code content

15

* @param name a descriptive name for the source

16

* @return Source.Builder for configuration

17

*/

18

public static Builder newBuilder(String language, CharSequence characters, String name);

19

20

/**

21

* Creates a builder for constructing Source objects from files

22

* @param language the language identifier

23

* @param file the source file

24

* @return Source.Builder for configuration

25

*/

26

public static Builder newBuilder(String language, File file);

27

28

/**

29

* Creates a builder for constructing Source objects from URLs

30

* @param language the language identifier

31

* @param url the source URL

32

* @return Source.Builder for configuration

33

*/

34

public static Builder newBuilder(String language, URL url);

35

36

/**

37

* Creates a builder for constructing Source objects from readers

38

* @param language the language identifier

39

* @param source the Reader providing source content

40

* @param name a descriptive name for the source

41

* @return Source.Builder for configuration

42

*/

43

public static Builder newBuilder(String language, Reader source, String name);

44

45

/**

46

* Quick creation method for simple string sources

47

* @param language the language identifier

48

* @param source the source code content

49

* @return Source object ready for evaluation

50

*/

51

public static Source create(String language, CharSequence source);

52

```

53

54

**Usage Examples:**

55

56

```java

57

// Simple string source

58

Source simpleSource = Source.create("python", "print('Hello, World!')");

59

60

// Named string source with builder

61

Source namedSource = Source.newBuilder("python",

62

"def factorial(n):\n return 1 if n <= 1 else n * factorial(n-1)",

63

"factorial.py")

64

.build();

65

66

// File-based source

67

File pythonFile = new File("/path/to/script.py");

68

Source fileSource = Source.newBuilder("python", pythonFile)

69

.mimeType("text/x-python")

70

.build();

71

72

// URL-based source

73

URL scriptUrl = new URL("https://example.com/script.py");

74

Source urlSource = Source.newBuilder("python", scriptUrl)

75

.cached(true)

76

.build();

77

78

// Reader-based source

79

StringReader reader = new StringReader("import math\nprint(math.pi)");

80

Source readerSource = Source.newBuilder("python", reader, "math_example.py")

81

.build();

82

83

// Multi-line Python script

84

String pythonScript = """

85

import sys

86

import json

87

88

def process_data(data):

89

result = []

90

for item in data:

91

if isinstance(item, dict):

92

result.append(item.get('value', 0) * 2)

93

return result

94

95

data = [{'value': 1}, {'value': 2}, {'value': 3}]

96

print(json.dumps(process_data(data)))

97

""";

98

99

Source scriptSource = Source.newBuilder("python", pythonScript, "data_processor.py")

100

.uri(URI.create("file:///examples/data_processor.py"))

101

.build();

102

```

103

104

### Language Detection

105

106

Automatically detect the language of source files based on file extensions and content analysis.

107

108

```java { .api }

109

/**

110

* Detects the language of a file based on its extension and content

111

* @param file the file to analyze

112

* @return language identifier string, or null if detection fails

113

*/

114

public static String findLanguage(File file);

115

116

/**

117

* Detects the language of a URL resource based on path and content

118

* @param url the URL to analyze

119

* @return language identifier string, or null if detection fails

120

*/

121

public static String findLanguage(URL url);

122

123

/**

124

* Detects the MIME type of a file

125

* @param file the file to analyze

126

* @return MIME type string, or null if detection fails

127

*/

128

public static String findMimeType(File file);

129

130

/**

131

* Detects the MIME type of a URL resource

132

* @param url the URL to analyze

133

* @return MIME type string, or null if detection fails

134

*/

135

public static String findMimeType(URL url);

136

```

137

138

**Usage Examples:**

139

140

```java

141

// Automatic language detection

142

File pythonFile = new File("script.py");

143

String detectedLanguage = Source.findLanguage(pythonFile); // "python"

144

145

File unknownFile = new File("mystery_script");

146

String language = Source.findLanguage(unknownFile);

147

if (language != null) {

148

Source source = Source.newBuilder(language, unknownFile).build();

149

} else {

150

// Fallback or manual specification

151

Source source = Source.newBuilder("python", unknownFile).build();

152

}

153

154

// MIME type detection

155

String mimeType = Source.findMimeType(pythonFile); // "text/x-python"

156

157

// URL-based detection

158

URL scriptUrl = new URL("https://raw.githubusercontent.com/user/repo/main/script.py");

159

String urlLanguage = Source.findLanguage(scriptUrl); // "python"

160

String urlMimeType = Source.findMimeType(scriptUrl); // "text/x-python"

161

162

// Combined detection and source creation

163

File sourceFile = new File("algorithms.py");

164

String detectedLang = Source.findLanguage(sourceFile);

165

if ("python".equals(detectedLang)) {

166

Source source = Source.newBuilder(detectedLang, sourceFile)

167

.mimeType(Source.findMimeType(sourceFile))

168

.build();

169

170

Value result = context.eval(source);

171

}

172

```

173

174

### Source Metadata

175

176

Access metadata and content information from Source objects.

177

178

```java { .api }

179

/**

180

* Gets the language identifier for this source

181

* @return the language identifier

182

*/

183

public String getLanguage();

184

185

/**

186

* Gets the name of this source

187

* @return the source name

188

*/

189

public String getName();

190

191

/**

192

* Gets the path of this source (if file-based)

193

* @return the file path, or null if not file-based

194

*/

195

public String getPath();

196

197

/**

198

* Gets the URI of this source

199

* @return the source URI

200

*/

201

public URI getURI();

202

203

/**

204

* Gets the MIME type of this source

205

* @return the MIME type, or null if not specified

206

*/

207

public String getMimeType();

208

209

/**

210

* Checks if this source has character-based content

211

* @return true if the source contains text

212

*/

213

public boolean hasCharacters();

214

215

/**

216

* Checks if this source has byte-based content

217

* @return true if the source contains binary data

218

*/

219

public boolean hasBytes();

220

221

/**

222

* Gets the character content of this source

223

* @return CharSequence containing the source text

224

* @throws UnsupportedOperationException if source has no characters

225

*/

226

public CharSequence getCharacters();

227

228

/**

229

* Gets the byte content of this source

230

* @return ByteSequence containing the source bytes

231

* @throws UnsupportedOperationException if source has no bytes

232

*/

233

public ByteSequence getBytes();

234

235

/**

236

* Gets a Reader for the source content

237

* @return Reader for streaming the source content

238

* @throws UnsupportedOperationException if source has no characters

239

*/

240

public Reader getReader();

241

242

/**

243

* Gets the length of the source content

244

* @return number of characters in the source

245

*/

246

public int getLength();

247

248

/**

249

* Gets the number of lines in the source

250

* @return line count

251

*/

252

public int getLineCount();

253

254

/**

255

* Checks if this source is marked as interactive

256

* @return true if source is for interactive evaluation

257

*/

258

public boolean isInteractive();

259

```

260

261

**Usage Examples:**

262

263

```java

264

// Source metadata inspection

265

Source source = Source.newBuilder("python",

266

"# Python script for data analysis\nimport pandas as pd\nprint('Hello')",

267

"analysis.py")

268

.mimeType("text/x-python")

269

.uri(URI.create("file:///projects/analysis.py"))

270

.build();

271

272

// Basic metadata

273

String language = source.getLanguage(); // "python"

274

String name = source.getName(); // "analysis.py"

275

String mimeType = source.getMimeType(); // "text/x-python"

276

URI uri = source.getURI(); // file:///projects/analysis.py

277

278

// Content inspection

279

boolean hasText = source.hasCharacters(); // true

280

boolean hasBinary = source.hasBytes(); // false (for text sources)

281

282

if (hasText) {

283

CharSequence content = source.getCharacters();

284

int length = source.getLength(); // Number of characters

285

int lines = source.getLineCount(); // Number of lines

286

287

System.out.println("Source length: " + length + " characters");

288

System.out.println("Source lines: " + lines);

289

System.out.println("Content preview: " + content.toString().substring(0, 50));

290

}

291

292

// Reader-based access for large sources

293

try (Reader reader = source.getReader()) {

294

BufferedReader buffered = new BufferedReader(reader);

295

String firstLine = buffered.readLine();

296

System.out.println("First line: " + firstLine);

297

}

298

299

// File path information (for file-based sources)

300

File pythonFile = new File("scripts/calculator.py");

301

Source fileSource = Source.newBuilder("python", pythonFile).build();

302

String filePath = fileSource.getPath(); // "scripts/calculator.py"

303

```

304

305

### Source Building and Configuration

306

307

Configure Source objects with advanced options using the builder pattern.

308

309

```java { .api }

310

/**

311

* Builder class for constructing configured Source objects

312

*/

313

public static final class Source.Builder {

314

/**

315

* Sets the MIME type for this source

316

* @param mimeType the MIME type string

317

* @return this builder

318

*/

319

public Builder mimeType(String mimeType);

320

321

/**

322

* Sets the URI for this source

323

* @param uri the source URI

324

* @return this builder

325

*/

326

public Builder uri(URI uri);

327

328

/**

329

* Marks this source as cached for performance

330

* @param cached true to enable caching

331

* @return this builder

332

*/

333

public Builder cached(boolean cached);

334

335

/**

336

* Marks this source as interactive (REPL-style)

337

* @param interactive true for interactive mode

338

* @return this builder

339

*/

340

public Builder interactive(boolean interactive);

341

342

/**

343

* Marks this source as internal (not user code)

344

* @param internal true for internal sources

345

* @return this builder

346

*/

347

public Builder internal(boolean internal);

348

349

/**

350

* Sets the character encoding for file-based sources

351

* @param encoding the character encoding

352

* @return this builder

353

*/

354

public Builder encoding(Charset encoding);

355

356

/**

357

* Sets content directly as byte array

358

* @param bytes the source content as bytes

359

* @return this builder

360

*/

361

public Builder content(byte[] bytes);

362

363

/**

364

* Sets content directly as string

365

* @param content the source content

366

* @return this builder

367

*/

368

public Builder content(String content);

369

370

/**

371

* Builds the configured Source object

372

* @return new Source instance

373

*/

374

public Source build();

375

}

376

```

377

378

**Usage Examples:**

379

380

```java

381

// Advanced source configuration

382

Source configuredSource = Source.newBuilder("python", "print('Hello')", "hello.py")

383

.mimeType("text/x-python")

384

.uri(URI.create("memory:///hello.py"))

385

.cached(true)

386

.interactive(false)

387

.internal(false)

388

.build();

389

390

// Interactive source for REPL

391

Source replSource = Source.newBuilder("python", "x = 42", "<stdin>")

392

.interactive(true)

393

.build();

394

395

// File source with custom encoding

396

Source encodedSource = Source.newBuilder("python", new File("utf8_script.py"))

397

.encoding(StandardCharsets.UTF_8)

398

.cached(true)

399

.build();

400

401

// Binary content source

402

byte[] pythonBytecode = loadPythonBytecode(); // Custom method

403

Source bytecodeSource = Source.newBuilder("python", "", "compiled.pyc")

404

.content(pythonBytecode)

405

.mimeType("application/x-python-bytecode")

406

.build();

407

408

// Network source with caching

409

URL networkScript = new URL("https://cdn.example.com/utils.py");

410

Source networkSource = Source.newBuilder("python", networkScript)

411

.cached(true) // Cache for performance

412

.build();

413

414

// Internal library source

415

String internalLib = """

416

# Internal utility functions

417

def _internal_helper(value):

418

return value * 2

419

""";

420

421

Source internalSource = Source.newBuilder("python", internalLib, "<internal>")

422

.internal(true) // Mark as internal

423

.build();

424

425

// Template-based source generation

426

String template = "result = calculate(%s, %s)";

427

String pythonCode = String.format(template, 10, 20);

428

Source templateSource = Source.newBuilder("python", pythonCode, "generated.py")

429

.uri(URI.create("generated://template/calculate"))

430

.build();

431

```

432

433

### Source Sections and Debugging

434

435

Work with source sections for error reporting and debugging support.

436

437

```java { .api }

438

/**

439

* Creates a source section representing a portion of this source

440

* @param startIndex character index where section starts

441

* @param length number of characters in section

442

* @return SourceSection representing the specified range

443

*/

444

public SourceSection createSection(int startIndex, int length);

445

446

/**

447

* Creates a source section by line and column numbers

448

* @param startLine starting line (1-based)

449

* @param startColumn starting column (1-based)

450

* @param endLine ending line (1-based)

451

* @param endColumn ending column (1-based)

452

* @return SourceSection representing the specified range

453

*/

454

public SourceSection createSection(int startLine, int startColumn, int endLine, int endColumn);

455

456

/**

457

* Creates a source section for a specific line

458

* @param lineNumber the line number (1-based)

459

* @return SourceSection representing the entire line

460

*/

461

public SourceSection createSection(int lineNumber);

462

```

463

464

**Usage Examples:**

465

466

```java

467

String pythonCode = """

468

def fibonacci(n):

469

if n <= 1:

470

return n

471

return fibonacci(n-1) + fibonacci(n-2)

472

473

result = fibonacci(10)

474

print("Result:", result)

475

""";

476

477

Source source = Source.create("python", pythonCode);

478

479

// Create section for function definition (lines 1-4)

480

SourceSection funcSection = source.createSection(1, 1, 4, 40);

481

482

// Create section for specific line

483

SourceSection resultLine = source.createSection(6); // "result = fibonacci(10)"

484

485

// Create section by character index

486

SourceSection printSection = source.createSection(

487

pythonCode.indexOf("print"),

488

"print(\"Result:\", result)".length()

489

);

490

491

// Use sections for error reporting

492

try {

493

Value result = context.eval(source);

494

} catch (PolyglotException e) {

495

SourceSection errorLocation = e.getSourceLocation();

496

if (errorLocation != null && errorLocation.getSource().equals(source)) {

497

System.err.println("Error at line " + errorLocation.getStartLine() +

498

", column " + errorLocation.getStartColumn());

499

System.err.println("Code: " + errorLocation.getCharacters());

500

}

501

}

502

```

503

504

## Types

505

506

```java { .api }

507

/**

508

* Represents a sequence of bytes for binary source content

509

*/

510

public interface ByteSequence {

511

/**

512

* Gets the length of the byte sequence

513

* @return number of bytes

514

*/

515

int length();

516

517

/**

518

* Gets the byte at specified index

519

* @param index the byte index

520

* @return byte value at index

521

*/

522

byte byteAt(int index);

523

524

/**

525

* Creates a subsequence of bytes

526

* @param startIndex starting index (inclusive)

527

* @param endIndex ending index (exclusive)

528

* @return ByteSequence representing the subsequence

529

*/

530

ByteSequence subSequence(int startIndex, int endIndex);

531

532

/**

533

* Converts to byte array

534

* @return byte array containing the sequence

535

*/

536

byte[] toByteArray();

537

}

538

539

/**

540

* Represents a section within a source for error reporting and debugging

541

*/

542

public final class SourceSection {

543

/**

544

* Checks if this section is available

545

* @return true if section information is available

546

*/

547

public boolean isAvailable();

548

549

/**

550

* Gets the source containing this section

551

* @return the Source object

552

*/

553

public Source getSource();

554

555

/**

556

* Gets the starting line number (1-based)

557

* @return starting line number

558

*/

559

public int getStartLine();

560

561

/**

562

* Gets the ending line number (1-based)

563

* @return ending line number

564

*/

565

public int getEndLine();

566

567

/**

568

* Gets the starting column (1-based)

569

* @return starting column number

570

*/

571

public int getStartColumn();

572

573

/**

574

* Gets the ending column (1-based)

575

* @return ending column number

576

*/

577

public int getEndColumn();

578

579

/**

580

* Gets the character index where section starts

581

* @return starting character index

582

*/

583

public int getCharIndex();

584

585

/**

586

* Gets the character index where section ends

587

* @return ending character index

588

*/

589

public int getCharEndIndex();

590

591

/**

592

* Gets the length of this section in characters

593

* @return section length

594

*/

595

public int getCharLength();

596

597

/**

598

* Gets the text content of this section

599

* @return CharSequence containing the section text

600

*/

601

public CharSequence getCharacters();

602

}

603

```