@@ -387,7 +387,7 @@ def _get_stream_feature_view(self, name: str, project: str):
387387 )
388388
389389 def _list_stream_feature_views (
390- self , project : str , tags : Optional [dict [str , str ]]
390+ self , project : str , tags : Optional [dict [str , str ]], ** kwargs
391391 ) -> List [StreamFeatureView ]:
392392 return self ._list_objects (
393393 stream_feature_views ,
@@ -396,6 +396,7 @@ def _list_stream_feature_views(
396396 StreamFeatureView ,
397397 "feature_view_proto" ,
398398 tags = tags ,
399+ ** kwargs ,
399400 )
400401
401402 def apply_entity (self , entity : Entity , project : str , commit : bool = True ):
@@ -537,7 +538,7 @@ def _get_validation_reference(self, name: str, project: str) -> ValidationRefere
537538 )
538539
539540 def _list_validation_references (
540- self , project : str , tags : Optional [dict [str , str ]] = None
541+ self , project : str , tags : Optional [dict [str , str ]] = None , ** kwargs
541542 ) -> List [ValidationReference ]:
542543 return self ._list_objects (
543544 table = validation_references ,
@@ -546,13 +547,20 @@ def _list_validation_references(
546547 python_class = ValidationReference ,
547548 proto_field_name = "validation_reference_proto" ,
548549 tags = tags ,
550+ ** kwargs ,
549551 )
550552
551553 def _list_entities (
552- self , project : str , tags : Optional [dict [str , str ]]
554+ self , project : str , tags : Optional [dict [str , str ]], ** kwargs
553555 ) -> List [Entity ]:
554556 return self ._list_objects (
555- entities , project , EntityProto , Entity , "entity_proto" , tags = tags
557+ entities ,
558+ project ,
559+ EntityProto ,
560+ Entity ,
561+ "entity_proto" ,
562+ tags = tags ,
563+ ** kwargs ,
556564 )
557565
558566 def delete_entity (self , name : str , project : str , commit : bool = True ):
@@ -614,7 +622,7 @@ def _get_data_source(self, name: str, project: str) -> DataSource:
614622 )
615623
616624 def _list_data_sources (
617- self , project : str , tags : Optional [dict [str , str ]]
625+ self , project : str , tags : Optional [dict [str , str ]], ** kwargs
618626 ) -> List [DataSource ]:
619627 return self ._list_objects (
620628 data_sources ,
@@ -623,6 +631,7 @@ def _list_data_sources(
623631 DataSource ,
624632 "data_source_proto" ,
625633 tags = tags ,
634+ ** kwargs ,
626635 )
627636
628637 def apply_data_source (
@@ -878,7 +887,7 @@ def delete_data_source(self, name: str, project: str, commit: bool = True):
878887 raise DataSourceObjectNotFoundException (name , project )
879888
880889 def _list_feature_services (
881- self , project : str , tags : Optional [dict [str , str ]]
890+ self , project : str , tags : Optional [dict [str , str ]], ** kwargs
882891 ) -> List [FeatureService ]:
883892 return self ._list_objects (
884893 feature_services ,
@@ -887,10 +896,11 @@ def _list_feature_services(
887896 FeatureService ,
888897 "feature_service_proto" ,
889898 tags = tags ,
899+ ** kwargs ,
890900 )
891901
892902 def _list_feature_views (
893- self , project : str , tags : Optional [dict [str , str ]]
903+ self , project : str , tags : Optional [dict [str , str ]], ** kwargs
894904 ) -> List [FeatureView ]:
895905 return self ._list_objects (
896906 feature_views ,
@@ -899,10 +909,11 @@ def _list_feature_views(
899909 FeatureView ,
900910 "feature_view_proto" ,
901911 tags = tags ,
912+ ** kwargs ,
902913 )
903914
904915 def _list_saved_datasets (
905- self , project : str , tags : Optional [dict [str , str ]] = None
916+ self , project : str , tags : Optional [dict [str , str ]] = None , ** kwargs
906917 ) -> List [SavedDataset ]:
907918 return self ._list_objects (
908919 saved_datasets ,
@@ -911,10 +922,11 @@ def _list_saved_datasets(
911922 SavedDataset ,
912923 "saved_dataset_proto" ,
913924 tags = tags ,
925+ ** kwargs ,
914926 )
915927
916928 def _list_on_demand_feature_views (
917- self , project : str , tags : Optional [dict [str , str ]]
929+ self , project : str , tags : Optional [dict [str , str ]], ** kwargs
918930 ) -> List [OnDemandFeatureView ]:
919931 return self ._list_objects (
920932 on_demand_feature_views ,
@@ -923,6 +935,7 @@ def _list_on_demand_feature_views(
923935 OnDemandFeatureView ,
924936 "feature_view_proto" ,
925937 tags = tags ,
938+ ** kwargs ,
926939 )
927940
928941 def _list_project_metadata (self , project : str ) -> List [ProjectMetadata ]:
@@ -1232,26 +1245,29 @@ def process_project(project: Project):
12321245 r .projects .extend ([project .to_proto ()])
12331246 last_updated_timestamps .append (last_updated_timestamp )
12341247
1248+ # proto_only=True: return raw protos without calling from_proto(),
1249+ # which would trigger dill.loads() on UDFs and fail for cross-project
1250+ # modules. The _list_* helpers hit the DB directly (no cache), avoiding
1251+ # infinite recursion since proto() itself builds the cache.
12351252 for lister , registry_proto_field in [
1236- (self .list_entities , r .entities ),
1237- (self .list_feature_views , r .feature_views ),
1238- (self .list_data_sources , r .data_sources ),
1239- (self .list_on_demand_feature_views , r .on_demand_feature_views ),
1240- (self .list_stream_feature_views , r .stream_feature_views ),
1241- (self .list_feature_services , r .feature_services ),
1242- (self .list_saved_datasets , r .saved_datasets ),
1243- (self .list_validation_references , r .validation_references ),
1244- (self .list_permissions , r .permissions ),
1253+ (self ._list_entities , r .entities ),
1254+ (self ._list_feature_views , r .feature_views ),
1255+ (self ._list_data_sources , r .data_sources ),
1256+ (self ._list_on_demand_feature_views , r .on_demand_feature_views ),
1257+ (self ._list_stream_feature_views , r .stream_feature_views ),
1258+ (self ._list_feature_services , r .feature_services ),
1259+ (self ._list_saved_datasets , r .saved_datasets ),
1260+ (self ._list_validation_references , r .validation_references ),
1261+ (self ._list_permissions , r .permissions ),
12451262 ]:
1246- objs : List [Any ] = lister (project_name , allow_cache = False ) # type: ignore
1263+ objs : List [Any ] = lister (project_name , tags = None , proto_only = True ) # type: ignore
12471264 if objs :
1248- obj_protos = [obj .to_proto () for obj in objs ]
1249- for obj_proto in obj_protos :
1265+ for obj_proto in objs :
12501266 if "spec" in obj_proto .DESCRIPTOR .fields_by_name :
12511267 obj_proto .spec .project = project_name
12521268 else :
12531269 obj_proto .project = project_name
1254- registry_proto_field .extend (obj_protos )
1270+ registry_proto_field .extend (objs )
12551271
12561272 # This is suuuper jank. Because of https://github.com/feast-dev/feast/issues/2783,
12571273 # the registry proto only has a single infra field, which we're currently setting as the "last" project.
@@ -1486,18 +1502,21 @@ def _list_objects(
14861502 python_class : Any ,
14871503 proto_field_name : str ,
14881504 tags : Optional [dict [str , str ]] = None ,
1505+ proto_only : bool = False ,
14891506 ):
14901507 with self .read_engine .begin () as conn :
14911508 stmt = select (table ).where (table .c .project_id == project )
14921509 rows = conn .execute (stmt ).all ()
14931510 if rows :
14941511 objects = []
14951512 for row in rows :
1496- obj = python_class .from_proto (
1497- proto_class .FromString (row ._mapping [proto_field_name ])
1498- )
1499- if utils .has_all_tags (obj .tags , tags ):
1500- objects .append (obj )
1513+ proto = proto_class .FromString (row ._mapping [proto_field_name ])
1514+ if proto_only :
1515+ objects .append (proto )
1516+ else :
1517+ obj = python_class .from_proto (proto )
1518+ if utils .has_all_tags (obj .tags , tags ):
1519+ objects .append (obj )
15011520 return objects
15021521 return []
15031522
@@ -1568,7 +1587,7 @@ def _get_permission(self, name: str, project: str) -> Permission:
15681587 )
15691588
15701589 def _list_permissions (
1571- self , project : str , tags : Optional [dict [str , str ]]
1590+ self , project : str , tags : Optional [dict [str , str ]], ** kwargs
15721591 ) -> List [Permission ]:
15731592 return self ._list_objects (
15741593 permissions ,
@@ -1577,6 +1596,7 @@ def _list_permissions(
15771596 Permission ,
15781597 "permission_proto" ,
15791598 tags = tags ,
1599+ ** kwargs ,
15801600 )
15811601
15821602 def apply_permission (
0 commit comments