Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 4c9e327

Browse files
authored
Merge pull request #269 from NoamGaash/feat/promisify
feat: promisify the "run" command
2 parents c648860 + 21571c6 commit 4c9e327

File tree

3 files changed

+60
-14
lines changed

3 files changed

+60
-14
lines changed

‎index.ts‎

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -309,10 +309,32 @@ export class PythonShell extends EventEmitter {
309309
* Runs a Python script and returns collected messages
310310
* @param {string} scriptPath The path to the script to execute
311311
* @param {Options} options The execution options
312-
* @param {Function} callback The callback function to invoke with the script results
313-
* @return {PythonShell} The PythonShell instance
312+
* @param {Function} (deprecated argument) callback The callback function to invoke with the script results
313+
* @return {Promise<string[]> | PythonShell} the output from the python script
314314
*/
315-
static run(scriptPath: string, options?: Options, callback?: (err?: PythonShellError, output?: any[]) => any) {
315+
static run(scriptPath: string, options?: Options, callback?: (err?: PythonShellError, output?: any[]) => any) {
316+
317+
if(callback) {
318+
console.warn('PythonShell.run() callback is deprecated. Use PythonShell.run() promise instead.')
319+
320+
return this.runLegacy(scriptPath, options, callback);
321+
}
322+
else {
323+
return new Promise((resolve, reject) => {
324+
let pyshell = new PythonShell(scriptPath, options);
325+
let output = [];
326+
327+
pyshell.on('message', function (message) {
328+
output.push(message);
329+
}).end(function (err) {
330+
if(err) reject(err);
331+
else resolve(output);
332+
});
333+
});
334+
}
335+
};
336+
337+
private static runLegacy(scriptPath: string, options?: Options, callback?: (err?: PythonShellError, output?: any[]) => any) {
316338
let pyshell = new PythonShell(scriptPath, options);
317339
let output = [];
318340

@@ -323,14 +345,16 @@ export class PythonShell extends EventEmitter {
323345
});
324346
};
325347

348+
349+
326350
/**
327351
* Runs the inputted string of python code and returns collected messages. DO NOT ALLOW UNTRUSTED USER INPUT HERE!
328352
* @param {string} code The python code to execute
329353
* @param {Options} options The execution options
330354
* @param {Function} callback The callback function to invoke with the script results
331355
* @return {PythonShell} The PythonShell instance
332356
*/
333-
static runString(code: string, options?: Options, callback?: (err: PythonShellError, output?: any[]) => any) {
357+
static runString(code: string, options?: Options, callback?: (err: PythonShellError, output?: any[]) => any) {
334358

335359
// put code in temp file
336360
const randomInt = getRandomInt();

‎package-lock.json‎

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎test/test-python-shell.ts‎

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -117,13 +117,20 @@ describe('PythonShell', function () {
117117
before(() => {
118118
PythonShell.defaultOptions = {};
119119
})
120-
it('should be able to execute a string of python code', function (done) {
121-
PythonShell.runString('print("hello");print("world")', null, function (err, results) {
120+
it('should be able to execute a string of python code using callbacks', function (done) {
121+
letpythonshell=PythonShell.runString('print("hello");print("world")', null, function (err, results) {
122122
if (err) return done(err);
123123
results.should.be.an.Array().and.have.lengthOf(2);
124124
results.should.eql(['hello', 'world']);
125125
done();
126126
});
127+
128+
pythonshell.should.be.an.instanceOf(PythonShell);
129+
});
130+
it('should be able to execute a string of python code using promises', async function () {
131+
let results = await PythonShell.runString('print("hello");print("world")');
132+
results.should.be.an.Array().and.have.lengthOf(2);
133+
results.should.eql(['hello', 'world']);
127134
});
128135
after(() => {
129136
PythonShell.defaultOptions = {
@@ -134,7 +141,7 @@ describe('PythonShell', function () {
134141
});
135142

136143
describe('#run(script, options)', function () {
137-
it('should run the script and return output data', function (done) {
144+
it('should run the script and return output data using callbacks', function (done) {
138145
PythonShell.run('echo_args.py', {
139146
args: ['hello', 'world']
140147
}, function (err, results) {
@@ -144,13 +151,29 @@ describe('PythonShell', function () {
144151
done();
145152
});
146153
});
154+
it('should run the script and return output data using promise', async function () {
155+
let results = await PythonShell.run('echo_args.py', {
156+
args: ['hello', 'world']
157+
});
158+
results.should.be.an.Array().and.have.lengthOf(2);
159+
results.should.eql(['hello', 'world']);
160+
});
147161
it('should try to run the script and fail appropriately', function (done) {
148162
PythonShell.run('unknown_script.py', null, function (err, results) {
149163
err.should.be.an.Error;
150164
err.exitCode.should.be.exactly(2);
151165
done();
152166
});
153167
});
168+
it('should try to run the script and fail appropriately', async function () {
169+
try {
170+
let results = await PythonShell.run('unknown_script.py');
171+
throw new Error(`should not get here because the script should fail` + results);
172+
} catch (err) {
173+
err.should.be.an.Error;
174+
err.exitCode.should.be.exactly(2);
175+
}
176+
});
154177
it('should include both output and error', function (done) {
155178
PythonShell.run('echo_hi_then_error.py', null, function (err, results) {
156179
err.should.be.an.Error;
@@ -250,8 +273,8 @@ describe('PythonShell', function () {
250273
};
251274
})
252275

253-
it('should run PythonShell normally without access to std streams', function (done) {
254-
var pyshell = PythonShell.run('exit-code.py', {
276+
it('should run PythonShell normally without access to std streams', asyncfunction () {
277+
var pyshell = awaitPythonShell.run('exit-code.py', {
255278
// 3 different ways of assigning values to the std streams in child_process.spawn()
256279
// * ignore - pipe to /dev/null
257280
// * inherit - inherit fd from parent process;
@@ -261,12 +284,10 @@ describe('PythonShell', function () {
261284
// although the user shouldn't be doing this. We are just testing for
262285
// increased code coverage
263286
args: "0"
264-
},done);
287+
});
265288

266-
should(pyshell.stdin).be.eql(null);
267-
should(pyshell.stdout).be.eql(null);
268-
should(pyshell.stderr).be.eql(null);
269-
should.throws(() => { pyshell.send("asd") });
289+
should(pyshell).be.eql([]);
290+
270291
});
271292
});
272293

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /