Skip to content

Commit 9305be2

Browse files
committed
Revert to requiring Python import callbacks to return bytes rather than string, and add version string to python module
1 parent 040f670 commit 9305be2

File tree

2 files changed

+20
-123
lines changed

2 files changed

+20
-123
lines changed

python/_jsonnet.c

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -247,33 +247,21 @@ static int cpython_import_callback(void *ctx_, const char *base, const char *rel
247247
PyObject *file_name = PyTuple_GetItem(result, 0);
248248
PyObject *file_content = PyTuple_GetItem(result, 1);
249249
#if PY_MAJOR_VERSION >= 3
250-
if (!PyUnicode_Check(file_name) || !(PyUnicode_Check(file_content) || PyBytes_Check(file_content))) {
250+
if (!PyUnicode_Check(file_name) || !PyBytes_Check(file_content)) {
251251
#else
252-
if (!PyString_Check(file_name) || !(PyString_Check(file_content) || PyBytes_Check(file_content))) {
252+
if (!PyString_Check(file_name) || !PyBytes_Check(file_content)) {
253253
#endif
254-
*buf = jsonnet_str_nonull(ctx->vm, "import_callback did not return (string, bytes) or (string, string)", buflen);
254+
*buf = jsonnet_str_nonull(ctx->vm, "import_callback did not return (string, bytes) Since 0.19.0 imports should be returned as bytes instead of as a string. You may want to call .encode() on your string.", buflen);
255255
success = 0;
256256
} else {
257-
const char *content_buf;
257+
char *content_buf;
258258
ssize_t content_len;
259259
#if PY_MAJOR_VERSION >= 3
260260
const char *found_here_cstr = PyUnicode_AsUTF8(file_name);
261261
#else
262262
const char *found_here_cstr = PyString_AsString(file_name);
263263
#endif
264-
if (PyBytes_Check(file_content)) {
265-
char *content_buf2;
266-
PyBytes_AsStringAndSize(file_content, &content_buf2, &content_len);
267-
content_buf = content_buf2;
268-
} else {
269-
#if PY_MAJOR_VERSION >= 3
270-
content_buf = PyUnicode_AsUTF8(file_content);
271-
content_len = strlen(content_buf);
272-
#else
273-
content_buf = PyString_AsString(file_content);
274-
content_len = strlen(content_buf);
275-
#endif
276-
}
264+
PyBytes_AsStringAndSize(file_content, &content_buf, &content_len);
277265
*found_here = jsonnet_str(ctx->vm, found_here_cstr);
278266
*buflen = content_len;
279267
*buf = jsonnet_realloc(ctx->vm, NULL, *buflen);
@@ -677,11 +665,18 @@ static struct PyModuleDef _jsonnet =
677665

678666
PyMODINIT_FUNC PyInit__jsonnet(void)
679667
{
680-
return PyModule_Create(&_jsonnet);
668+
PyObject *module = PyModule_Create(&_jsonnet);
669+
PyObject *version_str = PyUnicode_FromString(LIB_JSONNET_VERSION);
670+
PyModule_AddObjectRef(module, "version", version_str);
671+
return module;
681672
}
682673
#else
683674
PyMODINIT_FUNC init_jsonnet(void)
684675
{
685-
Py_InitModule3("_jsonnet", module_methods, "A Python interface to Jsonnet.");
676+
PyObject *module = Py_InitModule3("_jsonnet", module_methods, "A Python interface to Jsonnet.");
677+
PyObject *version_str = PyUnicode_FromString(LIB_JSONNET_VERSION);
678+
if (PyModule_AddObject(module, "version", PyString_FromString(LIB_JSONNET_VERSION)) < 0) {
679+
Py_XDECREF(version_str);
680+
}
686681
}
687682
#endif

python/_jsonnet_test.py

Lines changed: 6 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,7 @@
2424
# is invalid or an IO error occured.
2525
# It caches both hits and misses in the `cache` dict. Exceptions
2626
# do not need to be cached, because they abort the computation anyway.
27-
# if do_encode is True, then the file is returned as bytes
28-
# instead of as a string (this does not make a difference in Python2).
29-
def try_path_cached(cache, dir, rel, do_encode):
27+
def try_path_cached(cache, dir, rel):
3028
if not rel:
3129
raise RuntimeError('Got invalid filename (empty string).')
3230
if rel[0] == '/':
@@ -40,22 +38,12 @@ def try_path_cached(cache, dir, rel, do_encode):
4038
cache[full_path] = None
4139
else:
4240
with open(full_path) as f:
43-
if do_encode:
44-
cache[full_path] = f.read().encode()
45-
else:
46-
cache[full_path] = f.read()
41+
cache[full_path] = f.read().encode()
4742
return full_path, cache[full_path]
4843

4944
def import_callback_encode(dir, rel):
5045
cache = {}
51-
full_path, content = try_path_cached(cache, dir, rel, do_encode=True)
52-
if content:
53-
return full_path, content
54-
raise RuntimeError('File not found')
55-
56-
def import_callback_no_encode(dir, rel):
57-
cache = {}
58-
full_path, content = try_path_cached(cache, dir, rel, do_encode=False)
46+
full_path, content = try_path_cached(cache, dir, rel)
5947
if content:
6048
return full_path, content
6149
raise RuntimeError('File not found')
@@ -64,10 +52,6 @@ def import_callback_empty_file_encode(dir, rel):
6452
return dir, b''
6553

6654

67-
def import_callback_empty_file_no_encode(dir, rel):
68-
return dir, ''
69-
70-
7155
# Test native extensions
7256
def concat(a, b):
7357
return a + b
@@ -101,6 +85,9 @@ def setUp(self):
10185
with open(self.input_filename, "r") as infile:
10286
self.input_snippet = infile.read()
10387

88+
def test_version(self):
89+
self.assertEqual(type(_jsonnet.version), str)
90+
10491
def test_evaluate_file_encode(self):
10592
json_str = _jsonnet.evaluate_file(
10693
self.input_filename,
@@ -109,14 +96,6 @@ def test_evaluate_file_encode(self):
10996
)
11097
self.assertEqual(json_str, "true\n")
11198

112-
def test_evaluate_file_no_encode(self):
113-
json_str = _jsonnet.evaluate_file(
114-
self.input_filename,
115-
import_callback=import_callback_no_encode,
116-
native_callbacks=native_callbacks,
117-
)
118-
self.assertEqual(json_str, "true\n")
119-
12099
def test_evaluate_snippet_encode(self):
121100
json_str = _jsonnet.evaluate_snippet(
122101
self.test_filename,
@@ -126,15 +105,6 @@ def test_evaluate_snippet_encode(self):
126105
)
127106
self.assertEqual(json_str, "true\n")
128107

129-
def test_evaluate_snippet_no_encode(self):
130-
json_str = _jsonnet.evaluate_snippet(
131-
self.test_filename,
132-
self.input_snippet,
133-
import_callback=import_callback_no_encode,
134-
native_callbacks=native_callbacks,
135-
)
136-
self.assertEqual(json_str, "true\n")
137-
138108
def test_evaluate_snippet_encode(self):
139109
json_str = _jsonnet.evaluate_snippet(
140110
self.test_filename,
@@ -144,15 +114,6 @@ def test_evaluate_snippet_encode(self):
144114
)
145115
self.assertEqual(json_str, "true\n")
146116

147-
def test_evaluate_snippet_no_encode(self):
148-
json_str = _jsonnet.evaluate_snippet(
149-
self.test_filename,
150-
self.input_snippet,
151-
import_callback=import_callback_no_encode,
152-
native_callbacks=native_callbacks,
153-
)
154-
self.assertEqual(json_str, "true\n")
155-
156117
def test_import_encode(self):
157118
json_str = _jsonnet.evaluate_snippet(
158119
self.test_filename,
@@ -162,15 +123,6 @@ def test_import_encode(self):
162123
)
163124
self.assertEqual(json_str, "42\n")
164125

165-
def test_import_no_encode(self):
166-
json_str = _jsonnet.evaluate_snippet(
167-
self.test_filename,
168-
"import 'trivial.jsonnet'",
169-
import_callback=import_callback_no_encode,
170-
native_callbacks=native_callbacks,
171-
)
172-
self.assertEqual(json_str, "42\n")
173-
174126
def test_import_no_eol_encode(self):
175127
json_str = _jsonnet.evaluate_snippet(
176128
self.test_filename,
@@ -180,15 +132,6 @@ def test_import_no_eol_encode(self):
180132
)
181133
self.assertEqual(json_str, "42\n")
182134

183-
def test_import_no_eol_no_encode(self):
184-
json_str = _jsonnet.evaluate_snippet(
185-
self.test_filename,
186-
"import 'trivial_no_eol.jsonnet'",
187-
import_callback=import_callback_no_encode,
188-
native_callbacks=native_callbacks,
189-
)
190-
self.assertEqual(json_str, "42\n")
191-
192135
def test_import_binary_encode(self):
193136
json_str = _jsonnet.evaluate_snippet(
194137
self.test_filename,
@@ -198,15 +141,6 @@ def test_import_binary_encode(self):
198141
)
199142
self.assertEqual(json_str, "[\n 1,\n 2,\n 3\n]\n")
200143

201-
def test_import_binary_no_encode(self):
202-
json_str = _jsonnet.evaluate_snippet(
203-
self.test_filename,
204-
"importbin 'binary123.bin'",
205-
import_callback=import_callback_no_encode,
206-
native_callbacks=native_callbacks,
207-
)
208-
self.assertEqual(json_str, "[\n 1,\n 2,\n 3\n]\n")
209-
210144
def test_import_binary_sentinel_encode(self):
211145
json_str = _jsonnet.evaluate_snippet(
212146
self.test_filename,
@@ -216,20 +150,6 @@ def test_import_binary_sentinel_encode(self):
216150
)
217151
self.assertEqual(json_str, "[\n 1,\n 2,\n 3,\n 0,\n 1,\n 2,\n 3\n]\n")
218152

219-
def test_import_binary_sentinel_no_encode(self):
220-
json_str = _jsonnet.evaluate_snippet(
221-
self.test_filename,
222-
"importbin 'binary1230123.bin'",
223-
import_callback=import_callback_no_encode,
224-
native_callbacks=native_callbacks,
225-
)
226-
if sys.version_info.major < 3:
227-
# In Python2, the string can actually have a 0 in the middle
228-
self.assertEqual(json_str, "[\n 1,\n 2,\n 3,\n 0,\n 1,\n 2,\n 3\n]\n")
229-
else:
230-
# In Pyton3, the string is truncated
231-
self.assertEqual(json_str, "[\n 1,\n 2,\n 3\n]\n")
232-
233153
def test_import_str_empty_file_encode(self):
234154
json_str = _jsonnet.evaluate_snippet(
235155
self.test_filename,
@@ -239,15 +159,6 @@ def test_import_str_empty_file_encode(self):
239159
)
240160
self.assertEqual(json_str, "\"\"\n")
241161

242-
def test_import_str_empty_file_no_encode(self):
243-
json_str = _jsonnet.evaluate_snippet(
244-
self.test_filename,
245-
"importstr 'binary123.bin'",
246-
import_callback=import_callback_empty_file_no_encode,
247-
native_callbacks=native_callbacks,
248-
)
249-
self.assertEqual(json_str, "\"\"\n")
250-
251162
def test_import_binary_empty_file_encode(self):
252163
json_str = _jsonnet.evaluate_snippet(
253164
self.test_filename,
@@ -257,15 +168,6 @@ def test_import_binary_empty_file_encode(self):
257168
)
258169
self.assertEqual(json_str, "[ ]\n")
259170

260-
def test_import_binary_empty_file_no_encode(self):
261-
json_str = _jsonnet.evaluate_snippet(
262-
self.test_filename,
263-
"importbin 'binary123.bin'",
264-
import_callback=import_callback_empty_file_no_encode,
265-
native_callbacks=native_callbacks,
266-
)
267-
self.assertEqual(json_str, "[ ]\n")
268-
269171
def test_double_import(self):
270172
json_str = _jsonnet.evaluate_snippet(
271173
self.test_filename,

0 commit comments

Comments
 (0)