Repository navigation
Description
Expected Behavior
Comparing two Feast objects of different concrete types (e.g. FileSource vs SnowflakeSource)
returns False, per Python's data model. In particular, changing a feature view's data source
type and re-running feast apply over an existing registry succeeds.
Current Behavior
__eq__ raises TypeError on a cross-type comparison instead of returning False. Because the
apply/diff path compares registered objects against incoming ones, changing a source type and
re-applying crashes:
TypeError: Comparisons should only involve FileSource class objects.
Minimal repro:
from feast import FileSource
from feast.infra.offline_stores.snowflake_source import SnowflakeSource
a = FileSource(name="x", path="/tmp/x.parquet", timestamp_field="ts")
b = SnowflakeSource(name="x", database="D", schema="S", table="T", timestamp_field="ts")
a == b # TypeError — should be FalseRoot cause: the affected __eq__ methods do
if not isinstance(other, X): raise TypeError("Comparisons should only involve X class objects.").
Python's data model requires __eq__ to return NotImplemented for an unrecognized operand (so
the interpreter can try the reflected op and fall back to identity → False), never raise.
This is systemic — the pattern appears in ~35 __eq__ methods across the object model:
DataSource and its Kafka/Request/Kinesis subclasses; all offline sources (file,
snowflake, bigquery, redshift, and the ray/couchbase/trino/oracle/athena/mssql/
postgres contrib sources); plus Entity, FeatureView, BaseFeatureView, OnDemandFeatureView,
StreamFeatureView, FeatureService, SavedDataset, Project, ProjectMetadata, the four
transformation/* classes, Aggregation, LabelView, Permission, and the RoleBasedPolicy /
GroupBasedPolicy / NamespaceBasedPolicy / CombinedGroupNamespacePolicy policies.
PushSource.__eq__ already does the right thing (return False), so the correct pattern is
already in-tree.
Steps to reproduce
Run the snippet above, or: define a feature view on a FileSource and feast apply; change that
feature view's source to a SnowflakeSource (same name) and feast apply again → crash.
Specifications
- Version: 0.64.0 and 0.65.0 / master (verified; pattern unchanged)
- Subsystem: core object model (
sdk/python/feast)
Possible Solution
Replace each raise TypeError("Comparisons should only involve …") in these __eq__ methods with
return False, matching PushSource.__eq__, which already handles a cross-type comparison this
way. PushSource is the one __eq__ that does this correctly today, and there is no
return NotImplemented anywhere in the codebase, so return False keeps a single consistent
convention rather than introducing a new one. (NotImplemented would be the stricter data-model
answer and would also let a reflected/matcher __eq__ participate, but the codebase already
forgoes that everywhere.)
Add a unit test asserting cross-type equality returns False (not a raise). This can be one sweep
across all 35 sites (uniform and mechanical) or scoped to the DataSource hierarchy (where the
crash reproduces) with a follow-up for the rest — happy to do whichever the maintainers prefer.
PR incoming.
Activity
ShumzZzZz commentedon Jul 28, 2026
Good finding, hope your PR gets merged soon. I ran into the same issue when trying to update the data source from
FileSourcetoSparkSourcefor the same FeatureView.fix: Guard SparkSource, Feature, and data format __eq__ against cross…
larrysingleton007 commentedon Jul 28, 2026
@ShumzZzZz thanks for confirming. Your exact case (FileSource swapped to SparkSource on the same FeatureView) turned out to only be half covered, SparkSource compared in the other direction still blew up with an AttributeError. Just pushed a guard for that to the PR along with a test reproducing your scenario, so both directions now compare False.
larrysingleton007 commentedon Jul 28, 2026
@ntkathole @franciscojavierarceo @jyejare @aniketpalu pinging here as well since a second user has now hit this (see the comment above, swapping a FeatureView source from FileSource to SparkSource). The fix is ready in #6637 with green checks and covers that scenario too, it just needs a reviewer.
fix: Guard SparkSource, Feature, and data format __eq__ against cross…
fix: Guard SparkSource, Feature, and data format __eq__ against cross…
fix: Return False from __eq__ on cross-type comparison (#6637)
chore(release): release 0.66.0
chore(release): release 0.66.0