|
| 1 | +# Known Issues and Uncovered Code |
| 2 | + |
| 3 | +**Status**: Documentation of bugs, peculiarities, and technical debt for future iteration in the Python client |
| 4 | +**Date**: January 2026 |
| 5 | + |
| 6 | +This document comes from improving test coverage in the python client and exists to document issues that remain to be addressed. |
| 7 | + |
| 8 | +## Overview |
| 9 | + |
| 10 | +This document catalogs known issues, bugs, peculiarities, and uncovered code paths in the TerminusDB Python client. Issues are organized by category and client area to facilitate future systematic fixes. |
| 11 | + |
| 12 | +--- |
| 13 | + |
| 14 | +## 1. Known Bugs |
| 15 | + |
| 16 | +### 1.1 Query Builder - Args Introspection Issues |
| 17 | + |
| 18 | +**Area**: `woqlquery/woql_query.py` |
| 19 | +**Severity**: Medium |
| 20 | +**Lines**: 1056, 1092, 1128, 1775, 1807 |
| 21 | + |
| 22 | +**Issue**: Quad methods (`quad`, `added_quad`, `removed_quad`, `delete_quad`, `add_quad`) attempt to call `.append()` or `.concat()` on `WOQLQuery` objects when handling args introspection which is a deprecated feature that is inconsistently implemented across javascript and python (disabled in the javascript client). |
| 23 | + |
| 24 | +**Details**: |
| 25 | +- When `sub == "args"`, methods call `triple()` which returns a `WOQLQuery` object |
| 26 | +- Code then tries: `return arguments.append("graph")` or `return arguments.concat(["graph"])` |
| 27 | +- `WOQLQuery` objects don't have `append()` or `concat()` methods |
| 28 | +- Should return a list like: `return triple_args + ["graph"]` |
| 29 | + |
| 30 | +**Blocked Tests**: |
| 31 | +- `test_woql_graph_operations.py::test_removed_quad_with_args_subject` |
| 32 | +- `test_woql_graph_operations.py::test_added_quad_with_args_subject` |
| 33 | +- `test_woql_path_operations.py::test_quad_with_special_args_subject` |
| 34 | + |
| 35 | +**Impact**: Args introspection feature doesn't work for quad operations |
| 36 | + |
| 37 | +--- |
| 38 | + |
| 39 | +### 1.2 Query Builder - Missing Method |
| 40 | + |
| 41 | +**Area**: `woqlquery/woql_query.py` |
| 42 | +**Severity**: Medium |
| 43 | +**Line**: 3230 |
| 44 | + |
| 45 | +**Issue**: `graph()` method calls non-existent `_set_context()` method. |
| 46 | + |
| 47 | +**Details**: |
| 48 | +- Line 3230: `return self._set_context({"graph": g})` |
| 49 | +- Method `_set_context()` is not defined in the class |
| 50 | +- Should directly set context: `self._triple_builder_context["graph"] = g` |
| 51 | + |
| 52 | +**Blocked Tests**: |
| 53 | +- `test_woql_graph_operations.py::test_graph_method_basic` |
| 54 | +- `test_woql_graph_operations.py::test_graph_with_subquery` |
| 55 | +- `test_woql_graph_operations.py::test_multiple_graph_operations` |
| 56 | + |
| 57 | +**Impact**: Graph context setting is completely broken |
| 58 | + |
| 59 | +--- |
| 60 | + |
| 61 | +### 1.3 Query Validation - Unreachable Logic |
| 62 | + |
| 63 | +**Area**: `woqlquery/woql_query.py` |
| 64 | +**Severity**: High |
| 65 | +**Lines**: 784-785, 821-822 |
| 66 | + |
| 67 | +**Issue**: Logically impossible validation conditions prevent proper error handling. |
| 68 | + |
| 69 | +**Details**: |
| 70 | +```python |
| 71 | +# Line 784 in select() method: |
| 72 | +if queries != [] and not queries: |
| 73 | + raise ValueError("Select must be given a list of variable names") |
| 74 | + |
| 75 | +# Line 821-822 in distinct() method: |
| 76 | +if queries != [] and not queries: |
| 77 | + raise ValueError("Distinct must be given a list of variable names") |
| 78 | +``` |
| 79 | + |
| 80 | +**Analysis**: |
| 81 | +- After `queries = list(args)`, queries is always a list |
| 82 | +- If `queries == []`, then `queries != []` is False |
| 83 | +- If `queries != []`, then `not queries` is False |
| 84 | +- Condition can never be True, so ValueError is never raised |
| 85 | +- Should be: `if not queries:` or `if len(queries) == 0:` |
| 86 | + |
| 87 | +Same issue across both. Probably `select()` should allow to have no variables (to verify against terminusdb), and `distinct()` should have at least one variable (it can't be distinct otherwise…). |
| 88 | + |
| 89 | +**Blocked Tests**: |
| 90 | +- `test_woql_schema_validation.py::test_select_with_no_arguments_should_raise_error` |
| 91 | + |
| 92 | +**Impact**: Invalid queries with no arguments are not properly validated |
| 93 | + |
| 94 | +--- |
| 95 | + |
| 96 | +### 1.4 From Method - Cursor Wrapping Edge Case |
| 97 | + |
| 98 | +**Area**: `woqlquery/woql_query.py` |
| 99 | +**Severity**: Low |
| 100 | +**Line**: 907 |
| 101 | + |
| 102 | +**Issue**: The `woql_from()` method's cursor wrapping logic is not covered by tests. |
| 103 | + |
| 104 | +**Details**: |
| 105 | +```python |
| 106 | +# Line 906-907 in woql_from() method: |
| 107 | +if self._cursor.get("@type"): |
| 108 | + self._wrap_cursor_with_and() # Line 907 - uncovered |
| 109 | +``` |
| 110 | + |
| 111 | +**Analysis**: |
| 112 | +- Line 907 wraps the existing cursor with an `And` operation when the cursor already has a `@type` |
| 113 | +- This is defensive programming to handle chaining `from()` after other operations |
| 114 | +- JavaScript client has identical logic: `if (this.cursor['@type']) this.wrapCursorWithAnd();` |
| 115 | +- Test attempts `query.limit(10).start(5)` but doesn't test `from()` with existing cursor |
| 116 | + |
| 117 | +**Correct Test Scenario**: |
| 118 | +```python |
| 119 | +query = WOQLQuery() |
| 120 | +query.triple("v:X", "v:P", "v:O") # Set cursor @type |
| 121 | +result = query.woql_from("admin/mydb") # Should trigger line 907 |
| 122 | +``` |
| 123 | + |
| 124 | +**Blocked Tests**: |
| 125 | +- `test_woql_advanced_features.py::test_subquery_with_limit_offset` (incorrectly named/implemented) |
| 126 | + |
| 127 | +**Impact**: Low - defensive code path, basic functionality works |
| 128 | + |
| 129 | +--- |
| 130 | + |
| 131 | +## 2. Deprecated Code (Technical Debt) |
| 132 | + |
| 133 | +### 2.1 Data Value List Method |
| 134 | + |
| 135 | +**Area**: `woqlquery/woql_query.py` |
| 136 | +**Severity**: Low (Dead Code) |
| 137 | +**Lines**: 357-361 |
| 138 | + |
| 139 | +**Issue**: `_data_value_list()` method is never called anywhere in the codebase. |
| 140 | + |
| 141 | +**Details**: |
| 142 | +- Method exists but has no callers |
| 143 | +- Similar functionality exists in `_value_list()` which is actively used |
| 144 | +- Originally had a bug (called `clean_data_value` instead of `_clean_data_value`) |
| 145 | +- Bug was fixed but method remains unused |
| 146 | + |
| 147 | +**Blocked Tests**: |
| 148 | +- `test_woql_path_operations.py::test_data_value_list_with_various_types` |
| 149 | +- `test_woql_query_builder.py::test_data_value_list_with_mixed_items` |
| 150 | + |
| 151 | +**Recommendation**: Remove in future major version after deprecation period |
| 152 | + |
| 153 | +--- |
| 154 | + |
| 155 | +## 3. Uncovered Edge Cases |
| 156 | + |
| 157 | +### 3.1 Args Introspection Paths |
| 158 | + |
| 159 | +**Area**: `woqlquery/woql_query.py` |
| 160 | +**Lines**: 907, 1572, 1693, 2301, 2560, 2562, 2584, 2586, 2806, 2832, 2836, 2877, 2897, 2932, 2957, 2959, 3001, 3008, 3015, 3021, 3062, 3065, 3108, 3135, 3137, 3157, 3159, 3230 |
| 161 | + |
| 162 | +**Issue**: Args introspection feature (when first param == "args") is not covered by tests for many methods. |
| 163 | + |
| 164 | +**Details**: |
| 165 | +- Args introspection allows API discovery by passing "args" as first parameter |
| 166 | +- Methods return list of parameter names instead of executing |
| 167 | +- Many methods have this feature but it's not tested |
| 168 | +- Tests exist in `test_woql_remaining_edge_cases.py` but some paths remain uncovered |
| 169 | + |
| 170 | +**Methods Affected**: |
| 171 | +- `woql_or()` (907) |
| 172 | +- `start()` (1572) |
| 173 | +- `comment()` (1693) |
| 174 | +- `limit()` (2301) |
| 175 | +- `get()` (2560) |
| 176 | +- `put()` (2562) |
| 177 | +- `file()` (2584) |
| 178 | +- `remote()` (2586) |
| 179 | +- Math operations: `minus()`, `divide()`, `div()` (2806, 2832, 2836) |
| 180 | +- Comparison: `less()`, `lte()` (2877, 2897) |
| 181 | +- Logical: `once()`, `count()`, `cast()` (2932, 2957, 2959) |
| 182 | +- Type operations: `type_of()`, `order_by()`, `group_by()`, `length()` (3001, 3008, 3015, 3021) |
| 183 | +- String operations: `lower()`, `pad()` (3062, 3065) |
| 184 | +- Regex: `split()`, `regexp()`, `like()` (3108, 3135, 3137) |
| 185 | +- Substring operations (3157, 3159) |
| 186 | +- `trim()` (3230) |
| 187 | + |
| 188 | +**Impact**: Low - feature works but lacks test coverage |
| 189 | + |
| 190 | +--- |
| 191 | + |
| 192 | +### 3.2 As() Method Edge Cases |
| 193 | + |
| 194 | +**Area**: `woqlquery/woql_query.py` |
| 195 | +**Lines**: 1490-1495, 1501, 1508 |
| 196 | + |
| 197 | +**Issue**: Complex argument handling in `woql_as()` method not fully covered. |
| 198 | + |
| 199 | +**Details**: |
| 200 | +- Lines 1490-1495: List of lists with optional type parameter |
| 201 | +- Line 1501: XSD prefix in second argument |
| 202 | +- Line 1508: Objects with `to_dict()` method |
| 203 | + |
| 204 | +**Impact**: Low - basic functionality tested, edge cases uncovered |
| 205 | + |
| 206 | +--- |
| 207 | + |
| 208 | +### 3.3 Cursor Wrapping Edge Cases |
| 209 | + |
| 210 | +**Area**: `woqlquery/woql_query.py` |
| 211 | +**Lines**: 2652, 2679, 2713 |
| 212 | + |
| 213 | +**Issue**: `_wrap_cursor_with_and()` calls when cursor already has @type. |
| 214 | + |
| 215 | +**Details**: |
| 216 | +- `join()` line 2652 |
| 217 | +- `sum()` line 2679 |
| 218 | +- `slice()` line 2713 |
| 219 | + |
| 220 | +**Impact**: Low - defensive programming, rarely triggered |
| 221 | + |
| 222 | +--- |
| 223 | + |
| 224 | +### 3.4 Utility Method Edge Cases |
| 225 | + |
| 226 | +**Area**: `woqlquery/woql_query.py` |
| 227 | +**Lines**: 3247-3254, 3280-3283, 3328-3358 |
| 228 | + |
| 229 | +**Issue**: Complex utility methods with uncovered branches. |
| 230 | + |
| 231 | +**Details**: |
| 232 | +- Lines 3247-3254: `_find_last_subject()` with And query iteration |
| 233 | +- Lines 3280-3283: `_same_entry()` dictionary comparison |
| 234 | +- Lines 3328-3358: `_add_partial()` triple builder context logic |
| 235 | + |
| 236 | +**Impact**: Low - internal utilities, basic paths covered |
| 237 | + |
| 238 | +--- |
| 239 | + |
| 240 | +### 3.5 Vocabulary and Type Handling |
| 241 | + |
| 242 | +**Area**: `woqlquery/woql_query.py` |
| 243 | +**Lines**: 338, 706, 785, 3389 |
| 244 | + |
| 245 | +**Issue**: Specific edge cases in type and vocabulary handling. |
| 246 | + |
| 247 | +**Details**: |
| 248 | +- Line 338: `_clean_arithmetic()` with dict having `to_dict` method |
| 249 | +- Line 706: Vocabulary extraction with prefixed terms |
| 250 | +- Line 785: Select validation (see bug 1.3) |
| 251 | +- Line 3389: Final line of file (likely closing brace or comment) |
| 252 | + |
| 253 | +**Impact**: Very Low - rare edge cases |
| 254 | + |
| 255 | +--- |
| 256 | + |
| 257 | +## 4. Infrastructure and Integration Issues |
| 258 | + |
| 259 | +### 4.1 Cloud Infrastructure Tests |
| 260 | + |
| 261 | +**Area**: `integration_tests/` |
| 262 | +**Severity**: N/A (External Dependency) |
| 263 | + |
| 264 | +**Issue**: TerminusX cloud infrastructure no longer operational (use DFRNT.com instead) |
| 265 | + |
| 266 | +**Skipped Tests**: |
| 267 | +- `test_client.py::test_diff_ops_no_auth` |
| 268 | +- `test_client.py::test_terminusx` |
| 269 | +- `test_client.py::test_terminusx_crazy_path` |
| 270 | +- `test_scripts.py::test_script_happy_path` |
| 271 | + |
| 272 | +**Impact**: Cannot test cloud integration features |
| 273 | + |
| 274 | +--- |
| 275 | + |
| 276 | +### 4.2 JWT Authentication Tests |
| 277 | + |
| 278 | +**Area**: `integration_tests/test_client.py` |
| 279 | +**Severity**: N/A (Optional Feature) |
| 280 | + |
| 281 | +**Issue**: JWT tests require environment variable `TERMINUSDB_TEST_JWT=1`. |
| 282 | + |
| 283 | +**Skipped Tests**: |
| 284 | +- `test_client.py::test_jwt` |
| 285 | + |
| 286 | +**Impact**: JWT authentication not tested in CI |
| 287 | + |
| 288 | +--- |
| 289 | + |
| 290 | +## 5. Schema and Type System Peculiarities |
| 291 | + |
| 292 | +### 5.1 Relaxed Type Checking |
| 293 | + |
| 294 | +**Area**: `test_Schema.py` |
| 295 | +**Severity**: N/A (Design Decision) |
| 296 | + |
| 297 | +**Issue**: Type constraints intentionally relaxed. |
| 298 | + |
| 299 | +**Skipped Tests**: |
| 300 | +- `test_Schema.py::test_abstract_class` |
| 301 | +- `test_Schema.py::test_type_check` |
| 302 | + |
| 303 | +**Details**: Tests skipped with reason "Relaxing type constraints" and "relaxing type checking" |
| 304 | + |
| 305 | +**Impact**: Type system is more permissive than originally designed |
| 306 | + |
| 307 | +--- |
| 308 | + |
| 309 | +### 5.2 Backend-Dependent Features |
| 310 | + |
| 311 | +**Area**: `test_Schema.py` |
| 312 | +**Severity**: N/A (Backend Dependency) |
| 313 | + |
| 314 | +**Issue**: Import objects feature requires backend implementation. |
| 315 | + |
| 316 | +**Skipped Tests**: |
| 317 | +- `test_Schema.py::test_import_objects` |
| 318 | + |
| 319 | +**Impact**: Cannot test object import without backend |
| 320 | + |
| 321 | +--- |
| 322 | + |
| 323 | +### 5.3 Client Triple Retrieval |
| 324 | + |
| 325 | +**Area**: `test_Client.py` |
| 326 | +**Severity**: N/A (Temporarily Unavailable) |
| 327 | + |
| 328 | +**Issue**: Triple retrieval features temporarily unavailable. |
| 329 | + |
| 330 | +**Skipped Tests**: |
| 331 | +- `test_Client.py::test_get_triples` |
| 332 | +- `test_Client.py::test_get_triples_with_enum` |
| 333 | + |
| 334 | +**Impact**: Cannot test triple retrieval functionality |
| 335 | + |
| 336 | +--- |
| 337 | + |
| 338 | +## 6. Summary Statistics |
| 339 | + |
| 340 | +### Coverage Metrics |
| 341 | +- **Total Lines**: 1478 |
| 342 | +- **Covered Lines**: 1388 |
| 343 | +- **Uncovered Lines**: 90 |
| 344 | +- **Coverage**: 94% |
| 345 | + |
| 346 | +### Test Metrics |
| 347 | +- **Total Tests**: 1356 passing |
| 348 | +- **Skipped Tests**: 20 |
| 349 | +- **Test Files**: 50+ |
| 350 | + |
| 351 | +### Issue Breakdown |
| 352 | +- **Critical Bugs**: 3 (validation logic, missing method, args introspection) |
| 353 | +- **Deprecated Code**: 1 (dead code to remove) |
| 354 | +- **Uncovered Edge Cases**: 60+ lines (mostly args introspection) |
| 355 | +- **Infrastructure Issues**: 5 (cloud/JWT tests) |
| 356 | +- **Design Decisions**: 4 (relaxed constraints, backend dependencies) |
| 357 | + |
| 358 | +--- |
| 359 | + |
| 360 | +## 7. Recommendations for Future Iteration |
| 361 | + |
| 362 | +### High Priority |
| 363 | +1. **Fix validation logic** (lines 784-785, 821-822) - Critical for query correctness |
| 364 | +2. **Implement `_set_context()` or fix `graph()` method** (line 3230) - Broken feature |
| 365 | +3. **Fix quad args introspection** (lines 1056, 1092, 1128, 1775, 1807) - Consistent API |
| 366 | + |
| 367 | +### Medium Priority |
| 368 | +4. **Add tests for args introspection** - Improve coverage to 95%+ |
| 369 | +5. **Investigate subquery limit/offset** (line 903) - Unknown issue |
| 370 | +6. **Document type system decisions** - Clarify relaxed constraints |
| 371 | + |
| 372 | +### Low Priority |
| 373 | +7. **Remove deprecated `_data_value_list()`** - Clean up dead code |
| 374 | +8. **Add edge case tests** - Cover remaining utility methods |
| 375 | +9. **Document cloud infrastructure status** - Update integration test docs |
| 376 | + |
| 377 | +### Future Considerations |
| 378 | +10. **JWT test automation** - Add to CI pipeline |
| 379 | +11. **Backend integration tests** - Coordinate with backend team |
| 380 | +12. **Triple retrieval feature** - Investigate "temporarily unavailable" status |
| 381 | + |
| 382 | +--- |
| 383 | + |
| 384 | +## 8. Maintenance Notes |
| 385 | + |
| 386 | +**Last Updated**: January 2026 |
| 387 | +**Next Review**: After addressing high-priority bugs |
| 388 | + |
| 389 | +**Note**: This document should be updated whenever: |
| 390 | +- Bugs are fixed (move to resolved section) |
| 391 | +- New issues are discovered |
| 392 | +- Coverage improves |
| 393 | +- Design decisions change |
0 commit comments