or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mdindex.mdinteractive-shell.mdscript-execution.mdutilities.md

utilities.mddocs/

0

# Utilities

1

2

Utility functions for Python environment management, syntax checking, version detection, and stream processing. These functions provide helpful tools for working with Python environments and validating code before execution.

3

4

## Capabilities

5

6

### Syntax Checking

7

8

Validate Python code syntax without executing it, useful for code validation and error prevention.

9

10

### Check Code String Syntax

11

12

Validates Python code syntax from a string without execution.

13

14

```typescript { .api }

15

/**

16

* Checks syntax of Python code string without executing

17

* Creates temporary file for syntax validation

18

* @param code - Python code string to validate

19

* @returns Promise that resolves if syntax is valid, rejects with error details if invalid

20

*/

21

static async checkSyntax(code: string): Promise<void>;

22

```

23

24

**Usage Examples:**

25

26

```typescript

27

import { PythonShell } from "python-shell";

28

29

// Valid syntax

30

try {

31

await PythonShell.checkSyntax('print("Hello, World!")');

32

console.log('Syntax is valid');

33

} catch (error) {

34

console.error('Syntax error:', error.message);

35

}

36

37

// Invalid syntax

38

try {

39

await PythonShell.checkSyntax('print("Missing closing quote');

40

} catch (error) {

41

console.error('Syntax error detected:', error.stderr);

42

// Error contains Python compiler error message

43

}

44

45

// Complex code validation

46

const pythonCode = `

47

import json

48

import sys

49

50

def process_data(data):

51

if not isinstance(data, list):

52

raise ValueError("Data must be a list")

53

return [x * 2 for x in data if x > 0]

54

55

if __name__ == "__main__":

56

data = json.loads(sys.argv[1])

57

result = process_data(data)

58

print(json.dumps(result))

59

`;

60

61

try {

62

await PythonShell.checkSyntax(pythonCode);

63

console.log('Complex code syntax is valid');

64

} catch (error) {

65

console.error('Syntax issues found:', error.stderr);

66

}

67

```

68

69

### Check File Syntax

70

71

Validates Python file syntax without execution.

72

73

```typescript { .api }

74

/**

75

* Checks syntax of Python file without executing

76

* Uses py_compile module for validation

77

* @param filePath - Path to Python file to validate

78

* @returns Promise that resolves if syntax is valid, rejects with error details if invalid

79

*/

80

static async checkSyntaxFile(filePath: string): Promise<void>;

81

```

82

83

**Usage Examples:**

84

85

```typescript

86

import { PythonShell } from "python-shell";

87

import { promises as fs } from 'fs';

88

89

// Check individual file

90

try {

91

await PythonShell.checkSyntaxFile('./scripts/data_processor.py');

92

console.log('File syntax is valid');

93

} catch (error) {

94

console.error('File has syntax errors:', error.stderr);

95

}

96

97

// Batch validate multiple files

98

const scriptFiles = [

99

'./scripts/processor.py',

100

'./scripts/validator.py',

101

'./scripts/exporter.py'

102

];

103

104

const results = await Promise.allSettled(

105

scriptFiles.map(file => PythonShell.checkSyntaxFile(file))

106

);

107

108

results.forEach((result, index) => {

109

if (result.status === 'fulfilled') {

110

console.log(`${scriptFiles[index]}: Valid syntax`);

111

} else {

112

console.error(`${scriptFiles[index]}: Syntax error -`, result.reason.stderr);

113

}

114

});

115

116

// Validate before execution

117

async function safeExecute(scriptPath: string, options?: Options) {

118

try {

119

await PythonShell.checkSyntaxFile(scriptPath);

120

return await PythonShell.run(scriptPath, options);

121

} catch (syntaxError) {

122

throw new Error(`Cannot execute ${scriptPath}: ${syntaxError.stderr}`);

123

}

124

}

125

```

126

127

### Python Version Detection

128

129

Get information about Python installations and versions.

130

131

### Get Python Version (Async)

132

133

Asynchronously gets Python version information.

134

135

```typescript { .api }

136

/**

137

* Gets Python version information asynchronously

138

* @param pythonPath - Optional path to specific Python executable

139

* @returns Promise resolving to object with stdout and stderr from version command

140

*/

141

static getVersion(pythonPath?: string): Promise<{stdout: string, stderr: string}>;

142

```

143

144

**Usage Examples:**

145

146

```typescript

147

import { PythonShell } from "python-shell";

148

149

// Get default Python version

150

try {

151

const version = await PythonShell.getVersion();

152

console.log('Python version:', version.stdout.trim());

153

// Output: "Python 3.9.7"

154

} catch (error) {

155

console.error('Python not found or error getting version:', error.message);

156

}

157

158

// Check specific Python installation

159

try {

160

const version = await PythonShell.getVersion('/usr/bin/python3.10');

161

console.log('Python 3.10 version:', version.stdout.trim());

162

} catch (error) {

163

console.error('Python 3.10 not found:', error.message);

164

}

165

166

// Check multiple Python versions

167

const pythonPaths = ['python', 'python3', 'python3.9', 'python3.10'];

168

const versionChecks = pythonPaths.map(async (path) => {

169

try {

170

const version = await PythonShell.getVersion(path);

171

return { path, version: version.stdout.trim(), available: true };

172

} catch (error) {

173

return { path, error: error.message, available: false };

174

}

175

});

176

177

const results = await Promise.all(versionChecks);

178

results.forEach(result => {

179

if (result.available) {

180

console.log(`${result.path}: ${result.version}`);

181

} else {

182

console.log(`${result.path}: Not available - ${result.error}`);

183

}

184

});

185

```

186

187

### Get Python Version (Sync)

188

189

Synchronously gets Python version information.

190

191

```typescript { .api }

192

/**

193

* Gets Python version information synchronously

194

* @param pythonPath - Optional path to specific Python executable

195

* @returns Python version string

196

*/

197

static getVersionSync(pythonPath?: string): string;

198

```

199

200

**Usage Examples:**

201

202

```typescript

203

import { PythonShell } from "python-shell";

204

205

// Get default Python version synchronously

206

try {

207

const version = PythonShell.getVersionSync();

208

console.log('Python version:', version.trim());

209

} catch (error) {

210

console.error('Error getting Python version:', error.message);

211

}

212

213

// Check specific Python executable

214

try {

215

const version = PythonShell.getVersionSync('./venv/bin/python');

216

console.log('Virtual environment Python:', version.trim());

217

} catch (error) {

218

console.error('Virtual environment Python not found');

219

}

220

221

// Version comparison utility

222

function comparePythonVersions() {

223

try {

224

const systemVersion = PythonShell.getVersionSync('python');

225

const python3Version = PythonShell.getVersionSync('python3');

226

227

console.log('System Python:', systemVersion.trim());

228

console.log('Python3:', python3Version.trim());

229

230

// Extract version numbers for comparison

231

const systemMatch = systemVersion.match(/Python (\d+\.\d+\.\d+)/);

232

const python3Match = python3Version.match(/Python (\d+\.\d+\.\d+)/);

233

234

if (systemMatch && python3Match) {

235

console.log('System version number:', systemMatch[1]);

236

console.log('Python3 version number:', python3Match[1]);

237

}

238

} catch (error) {

239

console.error('Error comparing versions:', error.message);

240

}

241

}

242

```

243

244

### Get Python Path

245

246

Gets the currently configured Python executable path.

247

248

```typescript { .api }

249

/**

250

* Gets the current Python path configuration

251

* Returns either defaultOptions.pythonPath or defaultPythonPath

252

* @returns Current Python executable path

253

*/

254

static getPythonPath(): string;

255

```

256

257

**Usage Examples:**

258

259

```typescript

260

import { PythonShell } from "python-shell";

261

262

// Get current Python path

263

const currentPath = PythonShell.getPythonPath();

264

console.log('Current Python path:', currentPath);

265

// Default: "python3" on Unix, "python" on Windows

266

267

// After setting custom default

268

PythonShell.defaultOptions = { pythonPath: '/usr/bin/python3.9' };

269

const customPath = PythonShell.getPythonPath();

270

console.log('Custom Python path:', customPath); // "/usr/bin/python3.9"

271

272

// Utility to validate current Python setup

273

async function validatePythonSetup() {

274

const pythonPath = PythonShell.getPythonPath();

275

console.log('Using Python executable:', pythonPath);

276

277

try {

278

const version = await PythonShell.getVersion(pythonPath);

279

console.log('Version:', version.stdout.trim());

280

281

// Test basic functionality

282

await PythonShell.checkSyntax('print("Hello")');

283

console.log('Python setup is working correctly');

284

} catch (error) {

285

console.error('Python setup has issues:', error.message);

286

}

287

}

288

```

289

290

### Stream Processing Utilities

291

292

Utility class for processing streams with custom delimiters.

293

294

### NewlineTransformer

295

296

Stream transformer that splits data into chunks separated by newlines.

297

298

```typescript { .api }

299

/**

300

* Stream transformer for splitting data by newlines

301

* Used internally as default stdout/stderr splitter

302

*/

303

class NewlineTransformer extends Transform {

304

/**

305

* Transform stream chunks, splitting by newlines

306

* @param chunk - Input data chunk

307

* @param encoding - Character encoding

308

* @param callback - Completion callback

309

*/

310

_transform(chunk: any, encoding: string, callback: TransformCallback): void;

311

312

/**

313

* Flush remaining data when stream ends

314

* @param done - Completion callback

315

*/

316

_flush(done: TransformCallback): void;

317

}

318

```

319

320

**Usage Examples:**

321

322

```typescript

323

import { PythonShell, NewlineTransformer } from "python-shell";

324

import { Transform } from 'stream';

325

326

// Using NewlineTransformer for custom streams

327

const customPipe = someReadableStream;

328

const newlineTransformer = new NewlineTransformer();

329

330

customPipe

331

.pipe(newlineTransformer)

332

.on('data', (line) => {

333

console.log('Received line:', line.toString());

334

});

335

336

// Custom splitter for special delimiters

337

class CustomSplitter extends Transform {

338

private buffer = '';

339

340

_transform(chunk: any, encoding: string, callback: TransformCallback) {

341

this.buffer += chunk.toString();

342

const parts = this.buffer.split('||'); // Custom delimiter

343

this.buffer = parts.pop() || '';

344

345

parts.forEach(part => this.push(part));

346

callback();

347

}

348

349

_flush(callback: TransformCallback) {

350

if (this.buffer) this.push(this.buffer);

351

callback();

352

}

353

}

354

355

// Use custom splitter with PythonShell

356

const customSplitter = new CustomSplitter();

357

const pyshell = new PythonShell('script.py', {}, customSplitter);

358

359

// Advanced stream processing with multiple custom pipes

360

const options = {

361

stdio: ['pipe', 'pipe', 'pipe', 'pipe'] // stdin, stdout, stderr, custom

362

};

363

364

const pyshell = new PythonShell('advanced_script.py', options);

365

const customStream = pyshell.childProcess.stdio[3];

366

367

if (customStream) {

368

customStream

369

.pipe(new NewlineTransformer())

370

.on('data', (customData) => {

371

console.log('Custom stream data:', customData.toString());

372

});

373

}

374

```

375

376

### Environment Validation Utility

377

378

Combined utility function for comprehensive Python environment validation:

379

380

```typescript

381

// Example comprehensive validation function

382

async function validatePythonEnvironment(options?: Options) {

383

const pythonPath = options?.pythonPath || PythonShell.getPythonPath();

384

385

console.log('Validating Python environment...');

386

console.log('Python path:', pythonPath);

387

388

try {

389

// Check if Python is accessible

390

const version = await PythonShell.getVersion(pythonPath);

391

console.log('✓ Python version:', version.stdout.trim());

392

393

// Test syntax checking

394

await PythonShell.checkSyntax('import sys; print("Hello")');

395

console.log('✓ Syntax checking works');

396

397

// Test basic execution

398

const result = await PythonShell.runString('print("test")', { pythonPath });

399

console.log('✓ Basic execution works:', result);

400

401

// Test with provided options

402

if (options?.pythonOptions) {

403

const testResult = await PythonShell.runString('print("options test")', options);

404

console.log('✓ Custom options work:', testResult);

405

}

406

407

console.log('✓ Python environment validation complete');

408

return true;

409

410

} catch (error) {

411

console.error('✗ Python environment validation failed:', error.message);

412

return false;

413

}

414

}

415

```