@@ -29,14 +29,18 @@ function extend(obj:{}, ...args) {
2929interface Options extends SpawnOptions {
3030 mode : 'text' | 'json' | 'binary'
3131 formatter : ( param :string ) => any
32- parser : Function
32+ parser : ( param : string ) => any
3333 encoding : string
3434 pythonPath : string
3535 pythonOptions : string [ ]
3636 scriptPath : string
3737 args : string [ ]
3838}
3939
40+ class PythonShellError extends Error {
41+ traceback : string | Buffer ;
42+ }
43+
4044/**
4145 * An interactive Python shell exchanging data through stdio
4246 * @param {string } script The python script to execute
@@ -45,28 +49,31 @@ interface Options extends SpawnOptions{
4549 */
4650class PythonShell extends EventEmitter {
4751 script :string
48- command :any [ ]
52+ command :string [ ]
4953 mode :string
50- formatter :any
51- parser :any
54+ formatter :( param : string | Object ) => any
55+ parser :( param : string ) => any
5256 terminated :boolean
5357 childProcess :ChildProcess
5458 stdin : NodeJS . WriteStream ; //or writeable stream? Whats difference?
5559 stdout : NodeJS . ReadStream ;
5660 stderr : NodeJS . ReadStream ;
57- stderrHasEnded :boolean ;
58- stdoutHasEnded :boolean ;
59- exitCode :number ;
60- exitSignal :string ;
61+ private stderrHasEnded :boolean ;
62+ private stdoutHasEnded :boolean ;
63+ private exitCode :number ;
64+ private exitSignal :string ;
6165 private _remaining :string
62- private _endCallback :( err :any , exitCode :number , exitSignal :string ) => any
66+ private _endCallback :( err :PythonShellError , exitCode :number , exitSignal :string ) => any
6367
6468 //@ts -ignore keeping it initialized to {} for backwards API compatability
6569 static defaultOptions :Options = { } ; //allow global overrides for options
6670
6771 constructor ( script :string , options :Options ) {
6872 super ( ) ;
6973
74+ /**
75+ * returns either pythonshell func (if val string) or custom func (if val Function)
76+ */
7077 function resolve ( type , val :string | Function ) {
7178 if ( typeof val === 'string' ) {
7279 // use a built-in function using its name
@@ -84,6 +91,8 @@ class PythonShell extends EventEmitter{
8491 options = < Options > extend ( { } , PythonShell . defaultOptions , options ) ;
8592 let pythonPath ;
8693 if ( ! options . pythonPath ) {
94+ // starting 2020 python2 is deprecated so we choose 3 as default
95+ // except for windows which just has "python" command
8796 pythonPath = process . platform != "win32" ? "python3" : "python"
8897 } else pythonPath = options . pythonPath ;
8998 let pythonOptions = toArray ( options . pythonOptions ) ;
@@ -131,14 +140,14 @@ class PythonShell extends EventEmitter{
131140 function terminateIfNeeded ( ) {
132141 if ( ! self . stderrHasEnded || ! self . stdoutHasEnded || ( self . exitCode == null && self . exitSignal == null ) ) return ;
133142
134- let err ;
143+ let err : PythonShellError ;
135144 if ( errorData || ( self . exitCode && self . exitCode !== 0 ) ) {
136145 if ( errorData ) {
137146 err = self . parseError ( errorData ) ;
138147 } else {
139- err = new Error ( 'process exited with code ' + self . exitCode ) ;
148+ err = new PythonShellError ( 'process exited with code ' + self . exitCode ) ;
140149 }
141- err = extend ( err , {
150+ err = < PythonShellError > extend ( err , {
142151 executable : pythonPath ,
143152 options : pythonOptions . length ? pythonOptions : null ,
144153 script : self . script ,
@@ -159,7 +168,7 @@ class PythonShell extends EventEmitter{
159168
160169 // built-in formatters
161170 static format = {
162- text : function toText ( data ) {
171+ text : function toText ( data ) : string {
163172 if ( ! data ) return '' ;
164173 else if ( typeof data !== 'string' ) return data . toString ( ) ;
165174 return data ;
@@ -171,7 +180,7 @@ class PythonShell extends EventEmitter{
171180
172181 //built-in parsers
173182 static parse = {
174- text : function asText ( data ) {
183+ text : function asText ( data ) : string {
175184 return data ;
176185 } ,
177186 json : function asJson ( data :string ) {
@@ -186,7 +195,7 @@ class PythonShell extends EventEmitter{
186195 * @param {Function } callback The callback function to invoke with the script results
187196 * @return {PythonShell } The PythonShell instance
188197 */
189- static run ( script :string , options :Options , callback :( err :any , output ?:any [ ] ) => any ) {
198+ static run ( script :string , options :Options , callback :( err :PythonShellError , output ?:any [ ] ) => any ) {
190199 if ( typeof options === 'function' ) {
191200 callback = options ;
192201 options = null ;
@@ -210,20 +219,20 @@ class PythonShell extends EventEmitter{
210219 */
211220 private parseError ( data :string | Buffer ) {
212221 let text = '' + data ;
213- let error ;
222+ let error : PythonShellError ;
214223
215224 if ( / ^ T r a c e b a c k / . test ( text ) ) {
216225 // traceback data is available
217226 let lines = ( '' + data ) . trim ( ) . split ( new RegExp ( newline , 'g' ) ) ;
218227 let exception = lines . pop ( ) ;
219- error = new Error ( exception ) ;
228+ error = new PythonShellError ( exception ) ;
220229 error . traceback = data ;
221230 // extend stack trace
222231 error . stack += newline + ' ----- Python Traceback -----' + newline + ' ' ;
223232 error . stack += lines . slice ( 1 ) . join ( newline + ' ' ) ;
224233 } else {
225234 // otherwise, create a simpler error with stderr contents
226- error = new Error ( text ) ;
235+ error = new PythonShellError ( text ) ;
227236 }
228237
229238 return error ;
@@ -275,7 +284,7 @@ class PythonShell extends EventEmitter{
275284 * Closes the stdin stream, which should cause the process to finish its work and close
276285 * @returns {PythonShell } The same instance for chaining calls
277286 */
278- end ( callback :( err :any , exitCode :number , exitSignal :string ) => any ) {
287+ end ( callback :( err :PythonShellError , exitCode :number , exitSignal :string ) => any ) {
279288 this . childProcess . stdin . end ( ) ;
280289 this . _endCallback = callback ;
281290 return this ;
0 commit comments