Skip to content

Commit 3a32e8a

Browse files
EXPEbdodlaBhargav Dodla
and
Bhargav Dodla
authored
fix: Using get_type_hints instead of inspect signature for udf return annotation (feast-dev#4391)
fix: Using get_type_hints instead of inspect for udf return type Signed-off-by: Bhargav Dodla <bdodla@expediagroup.com> Co-authored-by: Bhargav Dodla <bdodla@expediagroup.com>
1 parent e90ac88 commit 3a32e8a

File tree

2 files changed

+57
-3
lines changed

2 files changed

+57
-3
lines changed

sdk/python/feast/on_demand_feature_view.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import inspect
44
import warnings
55
from types import FunctionType
6-
from typing import Any, Optional, Union
6+
from typing import Any, Optional, Union, get_type_hints
77

88
import dill
99
import pandas as pd
@@ -631,7 +631,7 @@ def mainify(obj) -> None:
631631
obj.__module__ = "__main__"
632632

633633
def decorator(user_function):
634-
return_annotation = inspect.signature(user_function).return_annotation
634+
return_annotation = get_type_hints(user_function).get("return", inspect._empty)
635635
udf_string = dill.source.getsource(user_function)
636636
mainify(user_function)
637637
if mode == "pandas":

sdk/python/tests/unit/infra/scaffolding/test_repo_operations.py

+55-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import os
2+
import tempfile
13
from contextlib import contextmanager
24
from pathlib import Path
35
from tempfile import TemporaryDirectory
@@ -6,7 +8,13 @@
68

79
import assertpy
810

9-
from feast.repo_operations import get_ignore_files, get_repo_files, read_feastignore
11+
from feast.repo_operations import (
12+
get_ignore_files,
13+
get_repo_files,
14+
parse_repo,
15+
read_feastignore,
16+
)
17+
from tests.utils.cli_repo_creator import CliRunner
1018

1119

1220
@contextmanager
@@ -140,3 +148,49 @@ def test_feastignore_with_stars2():
140148
(repo_root / "foo1/c.py").resolve(),
141149
]
142150
)
151+
152+
153+
def test_parse_repo():
154+
"Test to ensure that the repo is parsed correctly"
155+
runner = CliRunner()
156+
with tempfile.TemporaryDirectory(dir=os.getcwd()) as temp_dir:
157+
# Make sure the path is absolute by resolving any symlinks
158+
temp_path = Path(temp_dir).resolve()
159+
result = runner.run(["init", "my_project"], cwd=temp_path)
160+
repo_path = Path(temp_path / "my_project" / "feature_repo")
161+
assert result.returncode == 0
162+
163+
repo_contents = parse_repo(repo_path)
164+
165+
assert len(repo_contents.data_sources) == 3
166+
assert len(repo_contents.feature_views) == 2
167+
assert len(repo_contents.on_demand_feature_views) == 2
168+
assert len(repo_contents.stream_feature_views) == 0
169+
assert len(repo_contents.entities) == 2
170+
assert len(repo_contents.feature_services) == 3
171+
172+
173+
def test_parse_repo_with_future_annotations():
174+
"Test to ensure that the repo is parsed correctly when using future annotations"
175+
runner = CliRunner()
176+
with tempfile.TemporaryDirectory(dir=os.getcwd()) as temp_dir:
177+
# Make sure the path is absolute by resolving any symlinks
178+
temp_path = Path(temp_dir).resolve()
179+
result = runner.run(["init", "my_project"], cwd=temp_path)
180+
repo_path = Path(temp_path / "my_project" / "feature_repo")
181+
assert result.returncode == 0
182+
183+
with open(repo_path / "example_repo.py", "r") as f:
184+
existing_content = f.read()
185+
186+
with open(repo_path / "example_repo.py", "w") as f:
187+
f.write("from __future__ import annotations" + "\n" + existing_content)
188+
189+
repo_contents = parse_repo(repo_path)
190+
191+
assert len(repo_contents.data_sources) == 3
192+
assert len(repo_contents.feature_views) == 2
193+
assert len(repo_contents.on_demand_feature_views) == 2
194+
assert len(repo_contents.stream_feature_views) == 0
195+
assert len(repo_contents.entities) == 2
196+
assert len(repo_contents.feature_services) == 3

0 commit comments

Comments
 (0)