fhirpathpy 2.0.1__tar.gz → 2.0.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/PKG-INFO +8 -1
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/README.md +7 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/__init__.py +2 -4
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/engine/invocations/equality.py +2 -1
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/engine/nodes.py +3 -2
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/parser/ASTPathListener.py +17 -4
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/pyproject.toml +16 -5
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/LICENSE.md +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/engine/__init__.py +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/engine/evaluators/__init__.py +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/engine/invocations/__init__.py +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/engine/invocations/aggregate.py +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/engine/invocations/collections.py +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/engine/invocations/combining.py +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/engine/invocations/constants.py +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/engine/invocations/datetime.py +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/engine/invocations/existence.py +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/engine/invocations/filtering.py +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/engine/invocations/logic.py +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/engine/invocations/math.py +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/engine/invocations/misc.py +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/engine/invocations/navigation.py +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/engine/invocations/strings.py +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/engine/invocations/subsetting.py +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/engine/invocations/types.py +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/engine/util.py +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/models/__init__.py +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/models/dstu2/choiceTypePaths.json +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/models/dstu2/path2Type.json +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/models/dstu2/pathsDefinedElsewhere.json +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/models/dstu2/type2Parent.json +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/models/r4/choiceTypePaths.json +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/models/r4/path2Type.json +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/models/r4/pathsDefinedElsewhere.json +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/models/r4/type2Parent.json +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/models/r5/choiceTypePaths.json +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/models/r5/path2Type.json +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/models/r5/pathsDefinedElsewhere.json +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/models/r5/type2Parent.json +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/models/stu3/choiceTypePaths.json +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/models/stu3/path2Type.json +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/models/stu3/pathsDefinedElsewhere.json +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/models/stu3/type2Parent.json +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/parser/FHIRPath.g4 +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/parser/README.md +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/parser/__init__.py +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/parser/generated/FHIRPath.interp +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/parser/generated/FHIRPath.tokens +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/parser/generated/FHIRPathLexer.interp +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/parser/generated/FHIRPathLexer.py +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/parser/generated/FHIRPathLexer.tokens +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/parser/generated/FHIRPathListener.py +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/parser/generated/FHIRPathParser.py +0 -0
- {fhirpathpy-2.0.1 → fhirpathpy-2.0.3}/fhirpathpy/parser/generated/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fhirpathpy
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.3
|
|
4
4
|
Summary: FHIRPath implementation in Python
|
|
5
5
|
Keywords: fhir,fhirpath
|
|
6
6
|
Author-email: "beda.software" <fhirpath@beda.software>
|
|
@@ -161,3 +161,10 @@ result = evaluate(
|
|
|
161
161
|
|
|
162
162
|
It works similarly to [fhirpath.js](https://github.com/HL7/fhirpath.js/tree/master?tab=readme-ov-file#user-defined-functions)
|
|
163
163
|
|
|
164
|
+
|
|
165
|
+
## Development
|
|
166
|
+
|
|
167
|
+
To activate git pre-commit hook: `autohooks activate`
|
|
168
|
+
|
|
169
|
+
To run tests: `pytest`
|
|
170
|
+
|
|
@@ -129,3 +129,10 @@ result = evaluate(
|
|
|
129
129
|
```
|
|
130
130
|
|
|
131
131
|
It works similarly to [fhirpath.js](https://github.com/HL7/fhirpath.js/tree/master?tab=readme-ov-file#user-defined-functions)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
## Development
|
|
135
|
+
|
|
136
|
+
To activate git pre-commit hook: `autohooks activate`
|
|
137
|
+
|
|
138
|
+
To run tests: `pytest`
|
|
@@ -5,7 +5,7 @@ from fhirpathpy.engine.util import arraify, get_data, set_paths, process_user_in
|
|
|
5
5
|
from fhirpathpy.engine.nodes import FP_Type, ResourceNode
|
|
6
6
|
|
|
7
7
|
__title__ = "fhirpathpy"
|
|
8
|
-
__version__ = "2.0.
|
|
8
|
+
__version__ = "2.0.3"
|
|
9
9
|
__author__ = "beda.software"
|
|
10
10
|
__license__ = "MIT"
|
|
11
11
|
__copyright__ = "Copyright 2025 beda.software"
|
|
@@ -103,6 +103,4 @@ def compile(path, model=None, options=None):
|
|
|
103
103
|
|
|
104
104
|
For example, you could pass in the result of require("fhirpath/fhir-context/r4")
|
|
105
105
|
"""
|
|
106
|
-
return set_paths(
|
|
107
|
-
apply_parsed_path, parsedPath=parse(path), model=model, options=options
|
|
108
|
-
)
|
|
106
|
+
return set_paths(apply_parsed_path, parsedPath=parse(path), model=model, options=options)
|
|
@@ -82,6 +82,7 @@ def equivalence(ctx, x, y):
|
|
|
82
82
|
return x_val.deep_equal(y_val)
|
|
83
83
|
|
|
84
84
|
if isinstance(a, (abc.Mapping, list)) and isinstance(b, (abc.Mapping, list)):
|
|
85
|
+
|
|
85
86
|
def deep_equal(a, b):
|
|
86
87
|
if isinstance(a, abc.Mapping) and isinstance(b, abc.Mapping):
|
|
87
88
|
if a.keys() != b.keys():
|
|
@@ -89,7 +90,7 @@ def equivalence(ctx, x, y):
|
|
|
89
90
|
return all(deep_equal(a[key], b[key]) for key in a)
|
|
90
91
|
elif isinstance(a, list) and isinstance(b, list):
|
|
91
92
|
return len(a) == len(b) and all(
|
|
92
|
-
deep_equal(x, y) for x, y in zip(sorted(a), sorted(b))
|
|
93
|
+
deep_equal(x, y) for x, y in zip(sorted(a), sorted(b), strict=True)
|
|
93
94
|
)
|
|
94
95
|
elif isinstance(a, str) and isinstance(b, str):
|
|
95
96
|
return normalize_string(a) == normalize_string(b)
|
|
@@ -281,7 +281,8 @@ class FP_Quantity(FP_Type):
|
|
|
281
281
|
return FP_Quantity(result, toUnit)
|
|
282
282
|
return None
|
|
283
283
|
|
|
284
|
-
def _compare_years_and_months(self, other, year_units=
|
|
284
|
+
def _compare_years_and_months(self, other, year_units=None):
|
|
285
|
+
year_units = year_units or ["year", "years"]
|
|
285
286
|
self_value_in_months = self.value
|
|
286
287
|
other_value_in_months = other.value
|
|
287
288
|
|
|
@@ -838,7 +839,7 @@ class ResourceNode:
|
|
|
838
839
|
return self.data == value
|
|
839
840
|
|
|
840
841
|
def __hash__(self):
|
|
841
|
-
data_hash = hash(json.dumps(self.data, sort_keys=True))
|
|
842
|
+
data_hash = hash(json.dumps(self.data, sort_keys=True, default=str))
|
|
842
843
|
path_hash = hash(self.path)
|
|
843
844
|
return hash((data_hash, path_hash))
|
|
844
845
|
|
|
@@ -2,19 +2,32 @@ from antlr4.tree.Tree import TerminalNodeImpl
|
|
|
2
2
|
from fhirpathpy.parser.generated.FHIRPathListener import FHIRPathListener
|
|
3
3
|
|
|
4
4
|
|
|
5
|
+
def has_node_type_text(node_type):
|
|
6
|
+
# In general we need mostly terminal nodes (e.g. Identifier and any Literal)
|
|
7
|
+
# But the code also uses TypeSpecifier, InvocationExpression and TermExpression
|
|
8
|
+
return node_type.endswith("Literal") or node_type in [
|
|
9
|
+
"LiteralTerm",
|
|
10
|
+
"Identifier",
|
|
11
|
+
"TypeSpecifier",
|
|
12
|
+
"InvocationExpression",
|
|
13
|
+
"TermExpression",
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
|
|
5
17
|
class ASTPathListener(FHIRPathListener):
|
|
6
18
|
def __init__(self):
|
|
7
19
|
self.parentStack = [{}]
|
|
8
20
|
|
|
9
21
|
def pushNode(self, nodeType, ctx):
|
|
10
22
|
parentNode = self.parentStack[-1]
|
|
11
|
-
node = {"type": nodeType, "
|
|
12
|
-
|
|
23
|
+
node = {"type": nodeType, "terminalNodeText": []}
|
|
24
|
+
if has_node_type_text(nodeType):
|
|
25
|
+
node["text"] = ctx.getText()
|
|
13
26
|
for child in ctx.children:
|
|
14
27
|
if isinstance(child, TerminalNodeImpl):
|
|
15
28
|
node["terminalNodeText"].append(child.getText())
|
|
16
29
|
|
|
17
|
-
if
|
|
30
|
+
if "children" not in parentNode:
|
|
18
31
|
parentNode["children"] = []
|
|
19
32
|
|
|
20
33
|
parentNode["children"].append(node)
|
|
@@ -28,7 +41,7 @@ class ASTPathListener(FHIRPathListener):
|
|
|
28
41
|
def __getattribute__(self, name):
|
|
29
42
|
attr = object.__getattribute__(self, name)
|
|
30
43
|
|
|
31
|
-
if name in FHIRPathListener.__dict__ and
|
|
44
|
+
if name in FHIRPathListener.__dict__ and callable(attr):
|
|
32
45
|
|
|
33
46
|
def newfunc(*args, **kwargs):
|
|
34
47
|
if name.startswith("enter"):
|
|
@@ -12,11 +12,6 @@ exclude = '''
|
|
|
12
12
|
)
|
|
13
13
|
'''
|
|
14
14
|
|
|
15
|
-
[tool.isort]
|
|
16
|
-
profile = "black"
|
|
17
|
-
line_length = 100
|
|
18
|
-
skip = [".gitignore"]
|
|
19
|
-
|
|
20
15
|
[tool.pytest.ini_options]
|
|
21
16
|
minversion = "6.0"
|
|
22
17
|
addopts = "-ra -q --color=yes --cov=fhirpathpy --cov-report=xml"
|
|
@@ -62,3 +57,19 @@ Homepage = "https://github.com/beda-software/fhirpath-py"
|
|
|
62
57
|
Documentation = "https://github.com/beda-software/fhirpath-py#readme"
|
|
63
58
|
Source = "https://github.com/beda-software/fhirpath-py.git"
|
|
64
59
|
Changelog = "https://github.com/beda-software/fhirpath-py/blob/master/CHANGELOG.md"
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
[tool.ruff]
|
|
63
|
+
target-version = "py39"
|
|
64
|
+
line-length = 100
|
|
65
|
+
include = ["app/**/*.py", "tests/**/*.py"]
|
|
66
|
+
|
|
67
|
+
[tool.ruff.lint]
|
|
68
|
+
select = ["B", "F", "I", "E", "UP", "N", "PL", "PERF"]
|
|
69
|
+
# Black is responsible for E501
|
|
70
|
+
ignore = ["E501"]
|
|
71
|
+
unfixable = ["F401"]
|
|
72
|
+
|
|
73
|
+
[tool.autohooks]
|
|
74
|
+
mode = "pipenv"
|
|
75
|
+
pre-commit = ["autohooks.plugins.black", "autohooks.plugins.ruff"]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|