Skip to content

Commit d480684

Browse files
committed
Added impl and test for non-document binary()
Also moved the primitive_value_converters below the main public function.
1 parent ff1358c commit d480684

File tree

3 files changed

+35
-37
lines changed

3 files changed

+35
-37
lines changed

docs/eval.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ assert results[1]["doc"] == 2
6666
```
6767

6868
The following table describes how each MarkLogic type is associated with a Python data type. For any
69-
MarkLogic type not listed in the table, the value is not converted and will be of type `bytes`.
69+
MarkLogic type not listed in the table, such as `hexBinary` and `base64Binary`, the value is not converted and will be
70+
of type `bytes`.
7071

7172
| MarkLogic type | Python type |
7273
| --- | --- |
@@ -78,13 +79,13 @@ MarkLogic type not listed in the table, the value is not converted and will be o
7879
| element() | str |
7980
| array | list |
8081
| array-node() | list |
81-
| object-node() | dict or marklogic.documents.Document |
82-
| document-node() | str or marklogic.documents.Document |
83-
| binary() | marklogic.documents.Document |
82+
| object-node() | dict or `marklogic.documents.Document` |
83+
| document-node() | str or `marklogic.documents.Document` |
84+
| binary() | bytes or `marklogic.documents.Document` |
8485

85-
For the `object-node()` and `document-node()` entries in the above table, a `marklogic.documents.Document` instance
86-
will be returned if the MarkLogic value is associated with a URI via the multipart `X-URI` header. Otherwise, a `dict`
87-
or `str` is returned respectively.
86+
For the `object-node()`, `document-node()`, and `binary()` entries in the above table, a
87+
`marklogic.documents.Document` instance will be returned if the value is associated with a URI via
88+
the multipart `X-URI` header. Otherwise, a value of type `dict`, `str`, or `bytes` is returned respectively.
8889

8990
## Returning the original HTTP response
9091

marklogic/internal/eval.py

Lines changed: 21 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,6 @@
99
Supports working with data returned by the v1/eval and v1/invoke endpoints.
1010
"""
1111

12-
__primitive_value_converters = {
13-
"integer": lambda part: int(part.text),
14-
"decimal": lambda part: Decimal(part.text),
15-
"boolean": lambda part: ("False" == part.text),
16-
"string": lambda part: part.text,
17-
"map": lambda part: json.loads(part.text),
18-
"element()": lambda part: part.text,
19-
"array": lambda part: json.loads(part.text),
20-
"array-node()": lambda part: json.loads(part.text),
21-
"object-node()": lambda part: __process_object_node_part(part),
22-
"document-node()": lambda part: __process_document_node_part(part),
23-
# It appears that binary() will only be returned for a binary node retrieved
24-
# from the database, and thus an X-URI will always exist. Have not found a
25-
# scenario that indicates otherwise.
26-
"binary()": lambda part: Document(__get_decoded_uri_from_part(part), part.content),
27-
}
28-
2912

3013
def process_multipart_mixed_response(response: Response) -> list:
3114
"""
@@ -55,20 +38,28 @@ def process_multipart_mixed_response(response: Response) -> list:
5538
return transformed_parts
5639

5740

58-
def __get_decoded_uri_from_part(part):
59-
encoding = part.encoding
60-
return part.headers["X-URI".encode(encoding)].decode(encoding)
61-
62-
63-
def __process_object_node_part(part):
64-
if b"X-URI" in part.headers:
65-
return Document(__get_decoded_uri_from_part(part), json.loads(part.text))
66-
else:
67-
return json.loads(part.text)
41+
__primitive_value_converters = {
42+
"integer": lambda part: int(part.text),
43+
"decimal": lambda part: Decimal(part.text),
44+
"boolean": lambda part: "False" == part.text,
45+
"string": lambda part: part.text,
46+
"map": lambda part: json.loads(part.text),
47+
"element()": lambda part: part.text,
48+
"array": lambda part: json.loads(part.text),
49+
"array-node()": lambda part: json.loads(part.text),
50+
"object-node()": lambda part: __process_node(
51+
part, lambda part: json.loads(part.text)
52+
),
53+
"document-node()": lambda part: __process_node(part, lambda part: part.text),
54+
"binary()": lambda part: __process_node(part, lambda part: part.content),
55+
}
6856

6957

70-
def __process_document_node_part(part):
58+
def __process_node(part, content_extractor):
59+
content = content_extractor(part)
7160
if b"X-URI" in part.headers:
72-
return Document(__get_decoded_uri_from_part(part), part.text)
61+
encoding = part.encoding
62+
uri = part.headers["X-URI".encode(encoding)].decode(encoding)
63+
return Document(uri, content)
7364
else:
74-
return part.text
65+
return content

tests/test_eval.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,12 @@ def test_hexBinary(client):
127127
assert type(parts[0]) is bytes
128128

129129

130+
def test_binary(client):
131+
parts = client.eval(xquery='binary{xs:hexBinary("00")}')
132+
assert len(parts) == 1
133+
assert type(parts[0]) is bytes
134+
135+
130136
def test_no_script(client):
131137
with raises(
132138
ValueError, match="Must define either 'javascript' or 'xquery' argument."

0 commit comments

Comments
 (0)