11import { EventEmitter } from 'events' ;
22import { ChildProcess , spawn , SpawnOptions , exec , execSync } from 'child_process' ;
3- import { EOL as newline , tmpdir } from 'os' ;
3+ import { EOL as newline , tmpdir } from 'os' ;
44import { join , sep } from 'path'
55import { Readable , Writable } from 'stream'
66import { writeFile , writeFileSync } from 'fs' ;
77import { promisify } from 'util' ;
88
9- function toArray < T > ( source ?:T | T [ ] ) :T [ ] {
9+ function toArray < T > ( source ?: T | T [ ] ) : T [ ] {
1010 if ( typeof source === 'undefined' || source === null ) {
1111 return [ ] ;
1212 } else if ( ! Array . isArray ( source ) ) {
@@ -18,7 +18,7 @@ function toArray<T>(source?:T|T[]):T[] {
1818/**
1919 * adds arguments as properties to obj
2020 */
21- function extend ( obj :{ } , ...args ) {
21+ function extend ( obj : { } , ...args ) {
2222 Array . prototype . slice . call ( arguments , 1 ) . forEach ( function ( source ) {
2323 if ( source ) {
2424 for ( let key in source ) {
@@ -32,20 +32,20 @@ function extend(obj:{}, ...args) {
3232/**
3333 * gets a random int from 0-10000000000
3434 */
35- function getRandomInt ( ) {
36- return Math . floor ( Math . random ( ) * 10000000000 ) ;
35+ function getRandomInt ( ) {
36+ return Math . floor ( Math . random ( ) * 10000000000 ) ;
3737}
3838
3939const execPromise = promisify ( exec )
4040
41- export interface Options extends SpawnOptions {
41+ export interface Options extends SpawnOptions {
4242 /**
4343 * if binary is enabled message and stderr events will not be emitted
4444 */
45- mode ?: 'text' | 'json' | 'binary'
46- formatter ?: ( param :string ) => any
47- parser ?: ( param :string ) => any
48- stderrParser ?: ( param :string ) => any
45+ mode ?: 'text' | 'json' | 'binary'
46+ formatter ?: ( param : string ) => any
47+ parser ?: ( param : string ) => any
48+ stderrParser ?: ( param : string ) => any
4949 encoding ?: string
5050 pythonPath ?: string
5151 /**
@@ -62,9 +62,9 @@ export interface Options extends SpawnOptions{
6262 args ?: string [ ]
6363}
6464
65- export class PythonShellError extends Error {
65+ export class PythonShellError extends Error {
6666 traceback : string | Buffer ;
67- exitCode ?:number ;
67+ exitCode ?: number ;
6868}
6969
7070/**
@@ -73,42 +73,42 @@ export class PythonShellError extends Error{
7373 * @param {object } [options] The launch options (also passed to child_process.spawn)
7474 * @constructor
7575 */
76- export class PythonShell extends EventEmitter {
77- scriptPath :string
78- command :string [ ]
79- mode :string
80- formatter :( param :string | Object ) => any
81- parser :( param :string ) => any
82- stderrParser :( param :string ) => any
83- terminated :boolean
84- childProcess :ChildProcess
76+ export class PythonShell extends EventEmitter {
77+ scriptPath : string
78+ command : string [ ]
79+ mode : string
80+ formatter : ( param : string | Object ) => any
81+ parser : ( param : string ) => any
82+ stderrParser : ( param : string ) => any
83+ terminated : boolean
84+ childProcess : ChildProcess
8585 stdin : Writable ;
8686 stdout : Readable ;
8787 stderr : Readable ;
88- exitSignal :string ;
89- exitCode :number ;
90- private stderrHasEnded :boolean ;
91- private stdoutHasEnded :boolean ;
92- private _remaining :string
93- private _endCallback :( err :PythonShellError , exitCode :number , exitSignal :string ) => any
88+ exitSignal : string ;
89+ exitCode : number ;
90+ private stderrHasEnded : boolean ;
91+ private stdoutHasEnded : boolean ;
92+ private _remaining : string
93+ private _endCallback : ( err : PythonShellError , exitCode : number , exitSignal : string ) => any
9494
9595 // starting 2020 python2 is deprecated so we choose 3 as default
9696 static defaultPythonPath = process . platform != "win32" ? "python3" : "py" ;
9797
98- static defaultOptions :Options = { } ; //allow global overrides for options
99-
98+ static defaultOptions : Options = { } ; //allow global overrides for options
99+
100100 /**
101101 * spawns a python process
102102 * @param scriptPath path to script. Relative to current directory or options.scriptFolder if specified
103103 * @param options
104104 */
105- constructor ( scriptPath :string , options ?:Options ) {
105+ constructor ( scriptPath : string , options ?: Options ) {
106106 super ( ) ;
107107
108108 /**
109109 * returns either pythonshell func (if val string) or custom func (if val Function)
110110 */
111- function resolve ( type , val :string | Function ) {
111+ function resolve ( type , val : string | Function ) {
112112 if ( typeof val === 'string' ) {
113113 // use a built-in function using its name
114114 return PythonShell [ type ] [ val ] ;
@@ -118,14 +118,14 @@ export class PythonShell extends EventEmitter{
118118 }
119119 }
120120
121- if ( scriptPath . trim ( ) . length == 0 ) throw Error ( "scriptPath cannot be empty! You must give a script for python to run" )
121+ if ( scriptPath . trim ( ) . length == 0 ) throw Error ( "scriptPath cannot be empty! You must give a script for python to run" )
122122
123123 let self = this ;
124124 let errorData = '' ;
125125 EventEmitter . call ( this ) ;
126126
127127 options = < Options > extend ( { } , PythonShell . defaultOptions , options ) ;
128- let pythonPath :string ;
128+ let pythonPath : string ;
129129 if ( ! options . pythonPath ) {
130130 pythonPath = PythonShell . defaultPythonPath ;
131131 } else pythonPath = options . pythonPath ;
@@ -161,7 +161,7 @@ export class PythonShell extends EventEmitter{
161161 this . stderr . on ( 'data' , function ( data ) {
162162 errorData += '' + data ;
163163 } ) ;
164- this . stderr . on ( 'end' , function ( ) {
164+ this . stderr . on ( 'end' , function ( ) {
165165 self . stderrHasEnded = true ;
166166 terminateIfNeeded ( ) ;
167167 } ) ;
@@ -170,24 +170,24 @@ export class PythonShell extends EventEmitter{
170170 }
171171
172172 if ( this . stdout ) {
173- this . stdout . on ( 'end' , function ( ) {
173+ this . stdout . on ( 'end' , function ( ) {
174174 self . stdoutHasEnded = true ;
175175 terminateIfNeeded ( ) ;
176176 } ) ;
177177 } else {
178178 self . stdoutHasEnded = true ;
179179 }
180180
181- this . childProcess . on ( 'exit' , function ( code , signal ) {
181+ this . childProcess . on ( 'exit' , function ( code , signal ) {
182182 self . exitCode = code ;
183183 self . exitSignal = signal ;
184184 terminateIfNeeded ( ) ;
185185 } ) ;
186186
187187 function terminateIfNeeded ( ) {
188- if ( ! self . stderrHasEnded || ! self . stdoutHasEnded || ( self . exitCode == null && self . exitSignal == null ) ) return ;
188+ if ( ! self . stderrHasEnded || ! self . stdoutHasEnded || ( self . exitCode == null && self . exitSignal == null ) ) return ;
189189
190- let err :PythonShellError ;
190+ let err : PythonShellError ;
191191 if ( self . exitCode && self . exitCode !== 0 ) {
192192 if ( errorData ) {
193193 err = self . parseError ( errorData ) ;
@@ -209,13 +209,13 @@ export class PythonShell extends EventEmitter{
209209
210210 self . terminated = true ;
211211 self . emit ( 'close' ) ;
212- self . _endCallback && self . _endCallback ( err , self . exitCode , self . exitSignal ) ;
212+ self . _endCallback && self . _endCallback ( err , self . exitCode , self . exitSignal ) ;
213213 } ;
214214 }
215215
216216 // built-in formatters
217217 static format = {
218- text : function toText ( data ) :string {
218+ text : function toText ( data ) : string {
219219 if ( ! data ) return '' ;
220220 else if ( typeof data !== 'string' ) return data . toString ( ) ;
221221 return data ;
@@ -227,10 +227,10 @@ export class PythonShell extends EventEmitter{
227227
228228 //built-in parsers
229229 static parse = {
230- text : function asText ( data ) :string {
230+ text : function asText ( data ) : string {
231231 return data ;
232232 } ,
233- json : function asJson ( data :string ) {
233+ json : function asJson ( data : string ) {
234234 return JSON . parse ( data ) ;
235235 }
236236 } ;
@@ -239,25 +239,25 @@ export class PythonShell extends EventEmitter{
239239 * checks syntax without executing code
240240 * @returns rejects promise w/ string error output if syntax failure
241241 */
242- static async checkSyntax ( code :string ) {
242+ static async checkSyntax ( code : string ) {
243243 const randomInt = getRandomInt ( ) ;
244244 const filePath = tmpdir ( ) + sep + `pythonShellSyntaxCheck${ randomInt } .py`
245245
246246 const writeFilePromise = promisify ( writeFile )
247- return writeFilePromise ( filePath , code ) . then ( ( ) => {
247+ return writeFilePromise ( filePath , code ) . then ( ( ) => {
248248 return this . checkSyntaxFile ( filePath )
249249 } )
250250 }
251251
252- static getPythonPath ( ) {
253- return this . defaultOptions . pythonPath ? this . defaultOptions . pythonPath : this . defaultPythonPath ;
252+ static getPythonPath ( ) {
253+ return this . defaultOptions . pythonPath ? this . defaultOptions . pythonPath : this . defaultPythonPath ;
254254 }
255255
256256 /**
257257 * checks syntax without executing code
258258 * @returns {Promise } rejects w/ stderr if syntax failure
259259 */
260- static async checkSyntaxFile ( filePath :string ) {
260+ static async checkSyntaxFile ( filePath : string ) {
261261 const pythonPath = this . getPythonPath ( )
262262 let compileCommand = `${ pythonPath } -m py_compile ${ filePath } `
263263 return execPromise ( compileCommand )
@@ -270,14 +270,14 @@ export class PythonShell extends EventEmitter{
270270 * @param {Function } callback The callback function to invoke with the script results
271271 * @return {PythonShell } The PythonShell instance
272272 */
273- static run ( scriptPath :string , options ?:Options , callback ?:( err ?:PythonShellError , output ?:any [ ] ) => any ) {
273+ static run ( scriptPath : string , options ?: Options , callback ?: ( err ?: PythonShellError , output ?: any [ ] ) => any ) {
274274 let pyshell = new PythonShell ( scriptPath , options ) ;
275275 let output = [ ] ;
276276
277277 return pyshell . on ( 'message' , function ( message ) {
278278 output . push ( message ) ;
279279 } ) . end ( function ( err ) {
280- return callback ( err ? err : null , output . length ? output : null ) ;
280+ return callback ( err ? err : null , output . length ? output : null ) ;
281281 } ) ;
282282 } ;
283283
@@ -288,7 +288,7 @@ export class PythonShell extends EventEmitter{
288288 * @param {Function } callback The callback function to invoke with the script results
289289 * @return {PythonShell } The PythonShell instance
290290 */
291- static runString ( code :string , options ?:Options , callback ?:( err :PythonShellError , output ?:any [ ] ) => any ) {
291+ static runString ( code : string , options ?: Options , callback ?: ( err : PythonShellError , output ?: any [ ] ) => any ) {
292292
293293 // put code in temp file
294294 const randomInt = getRandomInt ( ) ;
@@ -298,13 +298,13 @@ export class PythonShell extends EventEmitter{
298298 return PythonShell . run ( filePath , options , callback ) ;
299299 } ;
300300
301- static getVersion ( pythonPath ?:string ) {
302- if ( ! pythonPath ) pythonPath = this . getPythonPath ( )
301+ static getVersion ( pythonPath ?: string ) {
302+ if ( ! pythonPath ) pythonPath = this . getPythonPath ( )
303303 return execPromise ( pythonPath + " --version" ) ;
304304 }
305305
306- static getVersionSync ( pythonPath ?:string ) {
307- if ( ! pythonPath ) pythonPath = this . getPythonPath ( )
306+ static getVersionSync ( pythonPath ?: string ) {
307+ if ( ! pythonPath ) pythonPath = this . getPythonPath ( )
308308 return execSync ( pythonPath + " --version" ) . toString ( )
309309 }
310310
@@ -313,9 +313,9 @@ export class PythonShell extends EventEmitter{
313313 * @param {string|Buffer } data The stderr contents to parse
314314 * @return {Error } The parsed error with extended stack trace when traceback is available
315315 */
316- private parseError ( data :string | Buffer ) {
317- let text = '' + data ;
318- let error :PythonShellError ;
316+ private parseError ( data : string | Buffer ) {
317+ let text = '' + data ;
318+ let error : PythonShellError ;
319319
320320 if ( / ^ T r a c e b a c k / . test ( text ) ) {
321321 // traceback data is available
@@ -324,8 +324,8 @@ export class PythonShell extends EventEmitter{
324324 error = new PythonShellError ( exception ) ;
325325 error . traceback = data ;
326326 // extend stack trace
327- error . stack += newline + ' ----- Python Traceback -----' + newline + ' ' ;
328- error . stack += lines . slice ( 1 ) . join ( newline + ' ' ) ;
327+ error . stack += newline + ' ----- Python Traceback -----' + newline + ' ' ;
328+ error . stack += lines . slice ( 1 ) . join ( newline + ' ' ) ;
329329 } else {
330330 // otherwise, create a simpler error with stderr contents
331331 error = new PythonShellError ( text ) ;
@@ -339,7 +339,7 @@ export class PythonShell extends EventEmitter{
339339 * Override this method to format data to be sent to the Python process
340340 * @returns {PythonShell } The same instance for chaining calls
341341 */
342- send ( message :string | Object ) {
342+ send ( message : string | Object ) {
343343 if ( ! this . stdin ) throw new Error ( "stdin not open for writing" ) ;
344344 let data = this . formatter ? this . formatter ( message ) : message ;
345345 if ( this . mode !== 'binary' ) data += newline ;
@@ -353,7 +353,7 @@ export class PythonShell extends EventEmitter{
353353 * Override this method to parse incoming data from the Python process into messages
354354 * @param {string|Buffer } data The data to parse into messages
355355 */
356- receive ( data :string | Buffer ) {
356+ receive ( data : string | Buffer ) {
357357 return this . receiveInternal ( data , 'message' ) ;
358358 } ;
359359
@@ -363,13 +363,13 @@ export class PythonShell extends EventEmitter{
363363 * Override this method to parse incoming logs from the Python process into messages
364364 * @param {string|Buffer } data The data to parse into messages
365365 */
366- receiveStderr ( data :string | Buffer ) {
366+ receiveStderr ( data : string | Buffer ) {
367367 return this . receiveInternal ( data , 'stderr' ) ;
368368 } ;
369369
370- private receiveInternal ( data :string | Buffer , emitType :'message' | 'stderr' ) {
370+ private receiveInternal ( data : string | Buffer , emitType : 'message' | 'stderr' ) {
371371 let self = this ;
372- let parts = ( '' + data ) . split ( newline ) ;
372+ let parts = ( '' + data ) . split ( newline ) ;
373373
374374 if ( parts . length === 1 ) {
375375 // an incomplete record, keep buffering
@@ -384,8 +384,8 @@ export class PythonShell extends EventEmitter{
384384 this . _remaining = lastLine ;
385385
386386 parts . forEach ( function ( part ) {
387- if ( emitType == 'message' ) self . emit ( emitType , self . parser ( part ) ) ;
388- else if ( emitType == 'stderr' ) self . emit ( emitType , self . stderrParser ( part ) ) ;
387+ if ( emitType == 'message' ) self . emit ( emitType , self . parser ( part ) ) ;
388+ else if ( emitType == 'stderr' ) self . emit ( emitType , self . stderrParser ( part ) ) ;
389389 } ) ;
390390
391391 return this ;
@@ -396,7 +396,7 @@ export class PythonShell extends EventEmitter{
396396 * this should cause the process to finish its work and close.
397397 * @returns {PythonShell } The same instance for chaining calls
398398 */
399- end ( callback :( err :PythonShellError , exitCode :number , exitSignal :string ) => any ) {
399+ end ( callback : ( err : PythonShellError , exitCode : number , exitSignal : string ) => any ) {
400400 if ( this . childProcess . stdin ) {
401401 this . childProcess . stdin . end ( ) ;
402402 }
@@ -448,7 +448,7 @@ export interface PythonShell {
448448 prependOnceListener ( event : "stderr" , listener : ( parsedChunk : any ) => void ) : this;
449449
450450 addListener ( event : "close" , listener : ( ) => void ) : this;
451- emit ( event : "close" , ) : boolean ;
451+ emit ( event : "close" , ) : boolean ;
452452 on ( event : "close" , listener : ( ) => void ) : this;
453453 once ( event : "close" , listener : ( ) => void ) : this;
454454 prependListener ( event : "close" , listener : ( ) => void ) : this;
0 commit comments