feat: support pylance 4.0.0#6678
Conversation
- Update pylance dependency range to >=0.39.0,<5.0.0 - Pin dev dependency to pylance==4.0.0 - Rename fragment_uuid parameter to index_uuid (pylance 4.0.0 API change) - Fix replace logic in create_scalar_index_internal to include removed_indices - Handle 'not a directory' error in _load_existing_dataset - Update test error message match for new RTREE index type
Greptile SummaryThis PR adapts the Lance integration to pylance 4.0.0 by renaming the
Confidence Score: 4/5Safe to merge after correcting the version lower bound in pyproject.toml; all other findings are minor style/robustness concerns. One P1 finding: the optional-dependency lower bound pyproject.toml — version lower bound needs to be raised to Important Files Changed
Sequence DiagramsequenceDiagram
participant Caller
participant create_scalar_index_internal
participant FragmentIndexHandler
participant lance_ds
Caller->>create_scalar_index_internal: create_scalar_index(uri, column, replace=True)
create_scalar_index_internal->>lance_ds: get_fragments()
create_scalar_index_internal->>FragmentIndexHandler: __call__(fragment_ids)
FragmentIndexHandler->>lance_ds: create_scalar_index(index_uuid=..., fragment_ids=...)
note over FragmentIndexHandler,lance_ds: pylance 4.0.0: index_uuid (was fragment_uuid)
create_scalar_index_internal->>lance_ds: merge_index_metadata(index_id)
create_scalar_index_internal->>lance_ds: list_indices()
note over create_scalar_index_internal: NEW: populate removed_indices for replace=True
create_scalar_index_internal->>lance_ds: LanceDataset.commit(CreateIndex(new_indices, removed_indices))
Reviews (1): Last reviewed commit: "feat: support pylance 4.0.0" | Re-trigger Greptile |
| huggingface = ["huggingface-hub<1.5.0", "datasets<4.6.0"] | ||
| iceberg = ["pyiceberg >= 0.7.0, <= 0.11.0, != 0.9.1, != 0.10.0"] | ||
| lance = ["pylance<0.40.0"] | ||
| lance = ["pylance>=0.39.0,<5.0.0"] |
There was a problem hiding this comment.
Version lower-bound incompatible with renamed API
pylance>=0.39.0 allows versions that do not accept the index_uuid keyword argument introduced in pylance 4.0.0. The FragmentIndexHandler.__call__ now passes index_uuid=self.index_uuid to lance_ds.create_scalar_index(); on pylance 0.39.x (where the parameter was still called fragment_uuid) this raises TypeError: create_scalar_index() got an unexpected keyword argument 'index_uuid' at runtime. The lower bound should be raised to match the new API.
| lance = ["pylance>=0.39.0,<5.0.0"] | |
| lance = ["pylance>=4.0.0,<5.0.0"] |
| except Exception: | ||
| # If we can't check existing indices, continue without removing | ||
| pass |
There was a problem hiding this comment.
Silent failure re-triggers the panic being fixed
If list_indices() raises for any reason (network hiccup, API change, etc.), execution falls through with removed_indices = []. Committing a CreateIndex operation with an empty removed_indices while an index of the same name already exists was exactly the scenario that caused the pylance 4.0.0 panic, so swallowing the exception silently defeats the purpose of this block. Consider logging at warning level:
except Exception as e:
logger.warning(
"Could not fetch existing indices for removal; old index may not be cleaned up: %s", e
)| with pytest.raises( | ||
| NotImplementedError, | ||
| match=r'Only "BTREE", "BITMAP", "NGRAM", "ZONEMAP", "LABEL_LIST", or "INVERTED" or "BLOOMFILTER" are supported for scalar columns. Received INVALID', | ||
| match=r'Only "BTREE", "BITMAP", "NGRAM", "ZONEMAP", "LABEL_LIST", "INVERTED", "BLOOMFILTER" or "RTREE" are supported for scalar columns. Received INVALID', | ||
| ): |
There was a problem hiding this comment.
Error-message match is pylance-version-specific
The regex now matches the exact error text emitted by pylance 4.0.0 (including "RTREE"). Whenever pylance adds or renames index types in a future release the match will fail. A narrower pattern that only captures the invariant part of the message is more robust:
| with pytest.raises( | |
| NotImplementedError, | |
| match=r'Only "BTREE", "BITMAP", "NGRAM", "ZONEMAP", "LABEL_LIST", or "INVERTED" or "BLOOMFILTER" are supported for scalar columns. Received INVALID', | |
| match=r'Only "BTREE", "BITMAP", "NGRAM", "ZONEMAP", "LABEL_LIST", "INVERTED", "BLOOMFILTER" or "RTREE" are supported for scalar columns. Received INVALID', | |
| ): | |
| match=r'Received INVALID', |
| removed_indices.append( | ||
| lance.Index( | ||
| uuid=idx["uuid"], | ||
| name=idx["name"], | ||
| fields=[lance_ds.schema.get_field_index(f) for f in idx["fields"]], | ||
| dataset_version=lance_ds.version, | ||
| fragment_ids=idx.get("fragment_ids", set()), | ||
| index_version=0, | ||
| ) | ||
| ) |
There was a problem hiding this comment.
dataset_version for removed indices uses current version instead of the index's creation version
lance_ds.version here is the version after merge_index_metadata was called, which is later than the version at which the existing (to-be-replaced) index was originally committed. Consider using the version from the index metadata if available:
dataset_version=idx.get("dataset_version", lance_ds.version),- Bump pylance minimum version from 0.39.0 to 4.0.0 (index_uuid API requires 4.0+) - Replace silent 'except Exception: pass' with warning logs - Use index metadata's dataset_version instead of current version for removed_indices - Relax error message match in test to avoid version-specific breakage
Summary
Upgrade pylance dependency to support version 4.0.0 (issue #6677):
pyproject.toml: update optional dependency frompylance<0.40.0topylance>=0.39.0,<5.0.0, and pin dev dependency topylance==4.0.0lance_scalar_index.py: renamefragment_uuidparameter toindex_uuidto adapt pylance 4.0.0 API changelance_scalar_index.py: fix replace logic increate_scalar_index_internalto include old indices inremoved_indiceswhen committing, preventing panic in pylance 4.0.0lance_data_sink.py: handle"not a directory"error in_load_existing_dataset, as pylance 4.0.0 changed the error message format when target path is a filetest_lancedb_scalar_index.py: update error message match for invalid index type test to include the newRTREEindex type added in pylance 4.0.0All changes are backward compatible with pylance >=0.39.0.
Test plan
tests/io/lance/: 56 passed — core lance read/write/scan operationstests/io/lancedb/test_lancedb_writes.py: all passed — includingtest_create_mode_fails_when_target_is_file(fixed error message handling)tests/io/lancedb/test_lancedb_scalar_index.py::TestDistributedIndexing: all passed — includingtest_build_distributed_index_replace_true_overwrite_existing(fixed removed_indices logic) andtest_build_distributed_index_invalid_index_type(updated RTREE match)tests/io/lancedb/: 133 passed, 2 skipped — full lancedb test suite