Feast apply no longer works for Snowflake Source
## Expected Behavior 

## Current Behavior

(python3.9) milesadkins@milesadkins coaxium % feast apply
Traceback (most recent call last):
  File "/Users/milesadkins/python3.9/bin/feast", line 33, in <module>
    sys.exit(load_entry_point('feast', 'console_scripts', 'feast')())
  File "/Users/milesadkins/python3.9/lib/python3.9/site-packages/click/core.py", line 1128, in __call__
    return self.main(*args, **kwargs)
  File "/Users/milesadkins/python3.9/lib/python3.9/site-packages/click/core.py", line 1053, in main
    rv = self.invoke(ctx)
  File "/Users/milesadkins/python3.9/lib/python3.9/site-packages/click/core.py", line 1659, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/Users/milesadkins/python3.9/lib/python3.9/site-packages/click/core.py", line 1395, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/Users/milesadkins/python3.9/lib/python3.9/site-packages/click/core.py", line 754, in invoke
    return __callback(*args, **kwargs)
  File "/Users/milesadkins/python3.9/lib/python3.9/site-packages/click/decorators.py", line 26, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/Users/milesadkins/Documents/feast/sdk/python/feast/cli.py", line 439, in apply_total_command
    apply_total(repo_config, repo, skip_source_validation)
  File "/Users/milesadkins/Documents/feast/sdk/python/feast/usage.py", line 280, in wrapper
    raise exc.with_traceback(traceback)
  File "/Users/milesadkins/Documents/feast/sdk/python/feast/usage.py", line 269, in wrapper
    return func(*args, **kwargs)
  File "/Users/milesadkins/Documents/feast/sdk/python/feast/repo_operations.py", line 249, in apply_total
    project, registry, repo, store = _prepare_registry_and_repo(repo_config, repo_path)
  File "/Users/milesadkins/Documents/feast/sdk/python/feast/repo_operations.py", line 155, in _prepare_registry_and_repo
    repo = parse_repo(repo_path)
  File "/Users/milesadkins/Documents/feast/sdk/python/feast/repo_operations.py", line 112, in parse_repo
    res.data_sources.add(obj)
TypeError: unhashable type: 'SnowflakeSource'

## Steps to reproduce

feast init -t snowflake
...
feast apply

### Specifications

- Version: 0.19
- Platform: Mac/Intel
- Subsystem:

## Possible Solution

fs.apply([[])

diff --git a/sdk/python/feast/infra/offline_stores/redshift_source.py b/sdk/python/feast/infra/offline_stores/redshift_source.py
index 19b88544..fbc42e31 100644
--- a/sdk/python/feast/infra/offline_stores/redshift_source.py
+++ b/sdk/python/feast/infra/offline_stores/redshift_source.py
@@ -90,6 +90,10 @@ class RedshiftSource(DataSource):
             query=data_source.redshift_options.query,
         )
 
+    # Note: Python requires redefining hash in child classes that override __eq__
+    def __hash__(self):
+        return super().__hash__()
+
     def __eq__(self, other):
         if not isinstance(other, RedshiftSource):
             raise TypeError(
diff --git a/sdk/python/feast/infra/offline_stores/snowflake_source.py b/sdk/python/feast/infra/offline_stores/snowflake_source.py
index ff36f1a6..825190b4 100644
--- a/sdk/python/feast/infra/offline_stores/snowflake_source.py
+++ b/sdk/python/feast/infra/offline_stores/snowflake_source.py
@@ -91,6 +91,10 @@ class SnowflakeSource(DataSource):
             query=data_source.snowflake_options.query,
         )
 
+    # Note: Python requires redefining hash in child classes that override __eq__
+    def __hash__(self):
+        return super().__hash__()
+
     def __eq__(self, other):
         if not isinstance(other, SnowflakeSource):
             raise TypeError(
['sdk/python/feast/infra/offline_stores/snowflake_source.py', 'sdk/python/feast/infra/offline_stores/redshift_source.py']