@@ -461,75 +461,99 @@ def test_rename_table_to_missing_namespace(
461461 catalog .rename_table (test_table_identifier , another_table_identifier )
462462
463463
464- # View-collision tests
465- #
466- # InMemoryCatalog and SqlCatalog don't support views (`view_exists` raises
467- # `NotImplementedError`), so we monkeypatch it to assert the call sites invoke
468- # the helper that maps a view at the target identifier to `TableAlreadyExistsError`.
464+ @pytest .fixture (name = "single_catalog" )
465+ def fixture_single_catalog (tmp_path : Path ) -> Catalog :
466+ from pyiceberg .catalog .memory import InMemoryCatalog
467+ from pyiceberg .io import WAREHOUSE
468+
469+ return InMemoryCatalog ("view_collision_tests" , ** {WAREHOUSE : tmp_path .absolute ().as_posix ()})
470+
471+
472+ def _recording_view_exists (target : Identifier ) -> tuple [list [Identifier ], Any ]:
473+ """Build a `view_exists` fake that records each call and returns True for `target`."""
474+ calls : list [Identifier ] = []
475+
476+ def fake (identifier : str | Identifier ) -> bool :
477+ seen = Catalog .identifier_to_tuple (identifier )
478+ calls .append (seen )
479+ return seen == target
480+
481+ return calls , fake
469482
470483
471484def test_create_table_raises_when_view_exists_at_identifier (
472- catalog : Catalog ,
473- test_table_identifier : Identifier ,
485+ single_catalog : Catalog ,
474486 table_schema_simple : Schema ,
475487 monkeypatch : pytest .MonkeyPatch ,
476488) -> None :
477- namespace = Catalog . namespace_from ( test_table_identifier )
478- catalog .create_namespace (namespace )
479- monkeypatch . setattr (
480- catalog , "view_exists" , lambda identifier : Catalog . identifier_to_tuple ( identifier ) == test_table_identifier
481- )
489+ identifier : Identifier = ( "ns" , "t" )
490+ single_catalog .create_namespace (identifier [: - 1 ] )
491+ calls , fake = _recording_view_exists ( identifier )
492+ monkeypatch . setattr ( single_catalog , "view_exists" , fake )
493+
482494 with pytest .raises (TableAlreadyExistsError , match = "View with same name already exists" ):
483- catalog .create_table (test_table_identifier , table_schema_simple )
495+ single_catalog .create_table (identifier , table_schema_simple )
496+
497+ assert identifier in calls
498+ assert not single_catalog .table_exists (identifier )
484499
485500
486501def test_create_table_transaction_raises_when_view_exists_at_identifier (
487- catalog : Catalog ,
488- test_table_identifier : Identifier ,
502+ single_catalog : Catalog ,
489503 table_schema_simple : Schema ,
490504 monkeypatch : pytest .MonkeyPatch ,
491505) -> None :
492- namespace = Catalog . namespace_from ( test_table_identifier )
493- catalog .create_namespace (namespace )
494- monkeypatch . setattr (
495- catalog , "view_exists" , lambda identifier : Catalog . identifier_to_tuple ( identifier ) == test_table_identifier
496- )
506+ identifier : Identifier = ( "ns" , "t" )
507+ single_catalog .create_namespace (identifier [: - 1 ] )
508+ calls , fake = _recording_view_exists ( identifier )
509+ monkeypatch . setattr ( single_catalog , "view_exists" , fake )
510+
497511 with pytest .raises (TableAlreadyExistsError , match = "View with same name already exists" ):
498- catalog .create_table_transaction (test_table_identifier , table_schema_simple )
512+ single_catalog .create_table_transaction (identifier , table_schema_simple )
513+
514+ assert identifier in calls
515+ assert not single_catalog .table_exists (identifier )
499516
500517
501518def test_register_table_raises_when_view_exists_at_identifier (
502- catalog : Catalog ,
503- test_table_identifier : Identifier ,
519+ single_catalog : Catalog ,
504520 metadata_location : str ,
505521 monkeypatch : pytest .MonkeyPatch ,
506522) -> None :
507- namespace = Catalog . namespace_from ( test_table_identifier )
508- catalog .create_namespace (namespace )
509- monkeypatch . setattr (
510- catalog , "view_exists" , lambda identifier : Catalog . identifier_to_tuple ( identifier ) == test_table_identifier
511- )
523+ identifier : Identifier = ( "ns" , "t" )
524+ single_catalog .create_namespace (identifier [: - 1 ] )
525+ calls , fake = _recording_view_exists ( identifier )
526+ monkeypatch . setattr ( single_catalog , "view_exists" , fake )
527+
512528 with pytest .raises (TableAlreadyExistsError , match = "View with same name already exists" ):
513- catalog .register_table (test_table_identifier , metadata_location )
529+ single_catalog .register_table (identifier , metadata_location )
530+
531+ assert identifier in calls
532+ assert not single_catalog .table_exists (identifier )
514533
515534
516535def test_rename_table_raises_when_view_exists_at_destination (
517- catalog : Catalog ,
536+ single_catalog : Catalog ,
518537 table_schema_simple : Schema ,
519- test_table_identifier : Identifier ,
520- another_table_identifier : Identifier ,
521538 monkeypatch : pytest .MonkeyPatch ,
522539) -> None :
523- from_namespace = Catalog . namespace_from ( test_table_identifier )
524- to_namespace = Catalog . namespace_from ( another_table_identifier )
525- catalog .create_namespace (from_namespace )
526- catalog . create_namespace ( to_namespace )
527- catalog . create_table ( test_table_identifier , table_schema_simple )
528- monkeypatch . setattr (
529- catalog , "view_exists" , lambda identifier : Catalog . identifier_to_tuple ( identifier ) == another_table_identifier
530- )
540+ source : Identifier = ( "ns" , "src" )
541+ destination : Identifier = ( "ns" , "dst" )
542+ single_catalog .create_namespace (( "ns" ,) )
543+ single_catalog . create_table ( source , table_schema_simple )
544+
545+ calls , fake = _recording_view_exists ( destination )
546+ monkeypatch . setattr ( single_catalog , "view_exists" , fake )
547+
531548 with pytest .raises (TableAlreadyExistsError , match = "View with same name already exists" ):
532- catalog .rename_table (test_table_identifier , another_table_identifier )
549+ single_catalog .rename_table (source , destination )
550+
551+ # The check must be on the destination, not the source.
552+ assert destination in calls
553+ assert source not in calls
554+ # Source table must still exist — the rename was rejected before any mutation.
555+ assert single_catalog .table_exists (source )
556+ assert not single_catalog .table_exists (destination )
533557
534558
535559# Drop table tests
0 commit comments