mirror of
https://github.com/lancedb/lancedb.git
synced 2026-10-30 23:36:52 +00:00
fix(python): reject invalid punctuation in UDF names (#4724)
Function names containing periods or hyphens passed `@udf` validation and failed only when registered with the server. Restrict the name pattern to ASCII letters, digits, and underscores, preserving the existing first-character rule so invalid names fail when the decorator runs. Document the accepted format and add regression coverage for dotted and hyphenated names, including trailing punctuation, alongside valid name overrides. Fixes #4720 Validation: - The four new invalid-name cases failed before the validator change because no `ValueError` was raised. - `cd python && uv run --extra tests pytest python/tests/test_first_class_function_slice2.py -q`: 86 passed. - Ruff 0.9.9: `ruff check python` and `ruff format --check python` passed. - Repository-root `ruff check .` reports 48 pre-existing errors in `docs/web-tests/`. <!-- lance-gatekeeper-fix:v1 agent=5e2441d3d264b685a6cee3c3c21ab048 generation=1 --> Co-authored-by: Gatefixer <313497061+lancedb-gatefixer[bot]@users.noreply.github.com>
This commit is contained in:
@@ -674,7 +674,7 @@ class RefreshColumnResult(_RemoteValue):
|
||||
return self.published_version
|
||||
|
||||
|
||||
_FUNCTION_NAME = re.compile(r"^[A-Za-z_][A-Za-z0-9_.-]*$")
|
||||
_FUNCTION_NAME = re.compile(r"^[A-Za-z_][A-Za-z0-9_]*$")
|
||||
|
||||
_FUNCTION_BLOB_V2_TYPE = "blob_v2"
|
||||
_ARROW_EXTENSION_NAME_KEY = "ARROW:extension:name"
|
||||
@@ -2106,6 +2106,8 @@ def udf(
|
||||
The synchronous callable, or the class whose instances are called.
|
||||
name : str, optional
|
||||
The remote Function name. Defaults to the callable name.
|
||||
Must start with an ASCII letter or underscore and contain only ASCII
|
||||
letters, digits, and underscores.
|
||||
input_schema : pyarrow.Schema, optional
|
||||
Explicit input fields in the exact order of the callable parameters.
|
||||
Must be provided together with ``output_schema``.
|
||||
|
||||
@@ -89,6 +89,27 @@ def test_scalar_udf_matches_shared_registration_golden_and_remains_callable():
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"name", ["examples.image_info", "image-info", "image_info.", "image_info-"]
|
||||
)
|
||||
def test_udf_rejects_function_names_with_periods_or_hyphens(name):
|
||||
with pytest.raises(ValueError, match="invalid Function name"):
|
||||
|
||||
@udf(name=name)
|
||||
def image_info(value: int) -> int:
|
||||
return value
|
||||
|
||||
|
||||
@pytest.mark.parametrize("name", ["image_info", "ImageInfo123", "_image_info", "f"])
|
||||
def test_udf_accepts_function_names_with_letters_digits_and_underscores(name):
|
||||
@udf(name=name)
|
||||
def image_info(value: int) -> int:
|
||||
return value
|
||||
|
||||
assert image_info.registration_request.name == name
|
||||
assert image_info(1) == 1
|
||||
|
||||
|
||||
def test_secret_bound_udf_matches_its_shared_registration_golden():
|
||||
assert analyze_caption(" hello ") == "hello"
|
||||
bound = analyze_caption.bind_secrets(
|
||||
|
||||
Reference in New Issue
Block a user