Skip to content

Commit 3b67f6b

Browse files
whitewhite
authored andcommitted
Add fail-fast parameter validation to PythonEmbed public methods
Reject null/blank inputs with clear IllegalArgumentException instead of cryptic downstream failures. Covers eval, exec, execFile, warmup, batchEval, batchExec, stream, ref, and all Map-based variants. Includes 24 new validation tests.
1 parent 7b2c610 commit 3b67f6b

2 files changed

Lines changed: 323 additions & 0 deletions

File tree

python-embed-runtime/src/main/java/io/github/howtis/pythonembed/PythonEmbed.java

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,9 @@ private Properties loadProperties() {
295295
* communication with the Python process fails, or the request times out
296296
*/
297297
public PythonValue eval(String code) {
298+
if (code == null || code.isBlank()) {
299+
throw new IllegalArgumentException("code must not be null or blank");
300+
}
298301
try {
299302
return protocol.sendEval(writer, code);
300303
} catch (TimeoutException | IOException e) {
@@ -313,6 +316,9 @@ public PythonValue eval(String code) {
313316
* communication with the Python process fails, or the request times out
314317
*/
315318
public PythonValue eval(String code, long timeoutMs) {
319+
if (code == null || code.isBlank()) {
320+
throw new IllegalArgumentException("code must not be null or blank");
321+
}
316322
try {
317323
return protocol.sendEval(writer, code, timeoutMs);
318324
} catch (TimeoutException | IOException e) {
@@ -329,6 +335,9 @@ public PythonValue eval(String code, long timeoutMs) {
329335
* communication with the Python process fails, or the request times out
330336
*/
331337
public void exec(String code) {
338+
if (code == null || code.isBlank()) {
339+
throw new IllegalArgumentException("code must not be null or blank");
340+
}
332341
try {
333342
protocol.sendExec(writer, code);
334343
} catch (TimeoutException | IOException e) {
@@ -346,6 +355,9 @@ public void exec(String code) {
346355
* communication with the Python process fails, or the request times out
347356
*/
348357
public void exec(String code, long timeoutMs) {
358+
if (code == null || code.isBlank()) {
359+
throw new IllegalArgumentException("code must not be null or blank");
360+
}
349361
try {
350362
protocol.sendExec(writer, code, timeoutMs);
351363
} catch (TimeoutException | IOException e) {
@@ -366,6 +378,9 @@ public void exec(String code, long timeoutMs) {
366378
* @throws IOException if the file cannot be read
367379
*/
368380
public void execFile(Path scriptPath) throws IOException {
381+
if (scriptPath == null) {
382+
throw new IllegalArgumentException("scriptPath must not be null");
383+
}
369384
String code = Files.readString(scriptPath);
370385
exec(code);
371386
}
@@ -381,6 +396,9 @@ public void execFile(Path scriptPath) throws IOException {
381396
* @throws IOException if the file cannot be read
382397
*/
383398
public void execFile(Path scriptPath, long timeoutMs) throws IOException {
399+
if (scriptPath == null) {
400+
throw new IllegalArgumentException("scriptPath must not be null");
401+
}
384402
String code = Files.readString(scriptPath);
385403
exec(code, timeoutMs);
386404
}
@@ -411,6 +429,12 @@ public void execFile(Path scriptPath, long timeoutMs) throws IOException {
411429
* communication with the Python process fails, or the request times out
412430
*/
413431
public PythonValue eval(Map<String, Object> variables, String code) {
432+
if (variables == null) {
433+
throw new IllegalArgumentException("variables must not be null");
434+
}
435+
if (code == null || code.isBlank()) {
436+
throw new IllegalArgumentException("code must not be null or blank");
437+
}
414438
if (variables.isEmpty()) {
415439
try {
416440
return protocol.sendEval(writer, code);
@@ -440,6 +464,12 @@ public PythonValue eval(Map<String, Object> variables, String code) {
440464
* communication with the Python process fails, or the request times out
441465
*/
442466
public PythonValue eval(Map<String, Object> variables, String code, long timeoutMs) {
467+
if (variables == null) {
468+
throw new IllegalArgumentException("variables must not be null");
469+
}
470+
if (code == null || code.isBlank()) {
471+
throw new IllegalArgumentException("code must not be null or blank");
472+
}
443473
if (variables.isEmpty()) {
444474
try {
445475
return protocol.sendEval(writer, code, timeoutMs);
@@ -468,6 +498,12 @@ public PythonValue eval(Map<String, Object> variables, String code, long timeout
468498
* communication with the Python process fails, or the request times out
469499
*/
470500
public void exec(Map<String, Object> variables, String code) {
501+
if (variables == null) {
502+
throw new IllegalArgumentException("variables must not be null");
503+
}
504+
if (code == null || code.isBlank()) {
505+
throw new IllegalArgumentException("code must not be null or blank");
506+
}
471507
String fullCode = buildWithVariables(variables, code);
472508
try {
473509
protocol.sendExec(writer, fullCode);
@@ -488,6 +524,12 @@ public void exec(Map<String, Object> variables, String code) {
488524
* communication with the Python process fails, or the request times out
489525
*/
490526
public void exec(Map<String, Object> variables, String code, long timeoutMs) {
527+
if (variables == null) {
528+
throw new IllegalArgumentException("variables must not be null");
529+
}
530+
if (code == null || code.isBlank()) {
531+
throw new IllegalArgumentException("code must not be null or blank");
532+
}
491533
String fullCode = buildWithVariables(variables, code);
492534
try {
493535
protocol.sendExec(writer, fullCode, timeoutMs);
@@ -535,6 +577,9 @@ static String buildWithVariables(Map<String, Object> variables, String code) {
535577
* communication with the Python process fails, or the request times out
536578
*/
537579
public void warmup(String script) {
580+
if (script == null || script.isBlank()) {
581+
throw new IllegalArgumentException("script must not be null or blank");
582+
}
538583
try {
539584
protocol.sendExec(writer, script, options.timeoutMs());
540585
} catch (TimeoutException | IOException e) {
@@ -570,6 +615,9 @@ public List<PythonValue> batchEval(List<String> codes) {
570615
* communication with the Python process fails, or the batch times out
571616
*/
572617
public List<PythonValue> batchEval(List<String> codes, long timeoutMs) {
618+
if (codes == null) {
619+
throw new IllegalArgumentException("codes must not be null");
620+
}
573621
try {
574622
return protocol.sendBatchEval(writer, codes, timeoutMs);
575623
} catch (TimeoutException | IOException e) {
@@ -602,6 +650,9 @@ public void batchExec(List<String> codes) {
602650
* communication with the Python process fails, or the batch times out
603651
*/
604652
public void batchExec(List<String> codes, long timeoutMs) {
653+
if (codes == null) {
654+
throw new IllegalArgumentException("codes must not be null");
655+
}
605656
try {
606657
protocol.sendBatchExec(writer, codes, timeoutMs);
607658
} catch (TimeoutException | IOException e) {
@@ -619,6 +670,9 @@ public void batchExec(List<String> codes, long timeoutMs) {
619670
* communication with the Python process fails, or the request times out
620671
*/
621672
public PythonHandle ref(String variableName) {
673+
if (variableName == null || variableName.isBlank()) {
674+
throw new IllegalArgumentException("variableName must not be null or blank");
675+
}
622676
try {
623677
Map<String, Object> refInfo = protocol.sendRef(writer, variableName);
624678
int refId = ((Number) refInfo.get("ref_id")).intValue();
@@ -719,6 +773,9 @@ public <T> T proxy(String variableName, Class<T> interfaceClass) {
719773
* @throws PythonExecutionException if the stream request fails
720774
*/
721775
public Iterator<PythonValue> stream(String code) {
776+
if (code == null || code.isBlank()) {
777+
throw new IllegalArgumentException("code must not be null or blank");
778+
}
722779
try {
723780
return protocol.sendStream(writer, code);
724781
} catch (IOException e) {
@@ -736,6 +793,9 @@ public Iterator<PythonValue> stream(String code) {
736793
* @throws PythonExecutionException if the stream request fails
737794
*/
738795
public Iterator<PythonValue> stream(String code, long pollTimeoutMs) {
796+
if (code == null || code.isBlank()) {
797+
throw new IllegalArgumentException("code must not be null or blank");
798+
}
739799
try {
740800
return protocol.sendStream(writer, code, pollTimeoutMs);
741801
} catch (IOException e) {

0 commit comments

Comments
 (0)