|
98 | 98 | DoubleType, |
99 | 99 | FixedType, |
100 | 100 | FloatType, |
| 101 | + GeographyType, |
| 102 | + GeometryType, |
101 | 103 | IntegerType, |
102 | 104 | ListType, |
103 | 105 | LongType, |
@@ -596,6 +598,108 @@ def test_binary_type_to_pyarrow() -> None: |
596 | 598 | assert visit(iceberg_type, _ConvertToArrowSchema()) == pa.large_binary() |
597 | 599 |
|
598 | 600 |
|
| 601 | +def test_geometry_type_to_pyarrow_without_geoarrow() -> None: |
| 602 | + """Test geometry type falls back to large_binary when geoarrow is not available.""" |
| 603 | + import sys |
| 604 | + |
| 605 | + iceberg_type = GeometryType() |
| 606 | + |
| 607 | + # Remove geoarrow from sys.modules if present and block re-import |
| 608 | + saved_modules = {} |
| 609 | + for mod_name in list(sys.modules.keys()): |
| 610 | + if mod_name.startswith("geoarrow"): |
| 611 | + saved_modules[mod_name] = sys.modules.pop(mod_name) |
| 612 | + |
| 613 | + import builtins |
| 614 | + |
| 615 | + original_import = builtins.__import__ |
| 616 | + |
| 617 | + def mock_import(name: str, *args: Any, **kwargs: Any) -> Any: |
| 618 | + if name.startswith("geoarrow"): |
| 619 | + raise ImportError(f"No module named '{name}'") |
| 620 | + return original_import(name, *args, **kwargs) |
| 621 | + |
| 622 | + try: |
| 623 | + builtins.__import__ = mock_import |
| 624 | + result = visit(iceberg_type, _ConvertToArrowSchema()) |
| 625 | + assert result == pa.large_binary() |
| 626 | + finally: |
| 627 | + builtins.__import__ = original_import |
| 628 | + sys.modules.update(saved_modules) |
| 629 | + |
| 630 | + |
| 631 | +def test_geography_type_to_pyarrow_without_geoarrow() -> None: |
| 632 | + """Test geography type falls back to large_binary when geoarrow is not available.""" |
| 633 | + import sys |
| 634 | + |
| 635 | + iceberg_type = GeographyType() |
| 636 | + |
| 637 | + # Remove geoarrow from sys.modules if present and block re-import |
| 638 | + saved_modules = {} |
| 639 | + for mod_name in list(sys.modules.keys()): |
| 640 | + if mod_name.startswith("geoarrow"): |
| 641 | + saved_modules[mod_name] = sys.modules.pop(mod_name) |
| 642 | + |
| 643 | + import builtins |
| 644 | + |
| 645 | + original_import = builtins.__import__ |
| 646 | + |
| 647 | + def mock_import(name: str, *args: Any, **kwargs: Any) -> Any: |
| 648 | + if name.startswith("geoarrow"): |
| 649 | + raise ImportError(f"No module named '{name}'") |
| 650 | + return original_import(name, *args, **kwargs) |
| 651 | + |
| 652 | + try: |
| 653 | + builtins.__import__ = mock_import |
| 654 | + result = visit(iceberg_type, _ConvertToArrowSchema()) |
| 655 | + assert result == pa.large_binary() |
| 656 | + finally: |
| 657 | + builtins.__import__ = original_import |
| 658 | + sys.modules.update(saved_modules) |
| 659 | + |
| 660 | + |
| 661 | +def test_geometry_type_to_pyarrow_with_geoarrow() -> None: |
| 662 | + """Test geometry type uses geoarrow WKB extension type when available.""" |
| 663 | + pytest.importorskip("geoarrow.pyarrow") |
| 664 | + import geoarrow.pyarrow as ga |
| 665 | + |
| 666 | + # Test default CRS |
| 667 | + iceberg_type = GeometryType() |
| 668 | + result = visit(iceberg_type, _ConvertToArrowSchema()) |
| 669 | + expected = ga.wkb().with_crs("OGC:CRS84") |
| 670 | + assert result == expected |
| 671 | + |
| 672 | + # Test custom CRS |
| 673 | + iceberg_type_custom = GeometryType("EPSG:4326") |
| 674 | + result_custom = visit(iceberg_type_custom, _ConvertToArrowSchema()) |
| 675 | + expected_custom = ga.wkb().with_crs("EPSG:4326") |
| 676 | + assert result_custom == expected_custom |
| 677 | + |
| 678 | + |
| 679 | +def test_geography_type_to_pyarrow_with_geoarrow() -> None: |
| 680 | + """Test geography type uses geoarrow WKB extension type with edge type when available.""" |
| 681 | + pytest.importorskip("geoarrow.pyarrow") |
| 682 | + import geoarrow.pyarrow as ga |
| 683 | + |
| 684 | + # Test default (spherical algorithm) |
| 685 | + iceberg_type = GeographyType() |
| 686 | + result = visit(iceberg_type, _ConvertToArrowSchema()) |
| 687 | + expected = ga.wkb().with_crs("OGC:CRS84").with_edge_type(ga.EdgeType.SPHERICAL) |
| 688 | + assert result == expected |
| 689 | + |
| 690 | + # Test custom CRS with spherical |
| 691 | + iceberg_type_custom = GeographyType("EPSG:4326", "spherical") |
| 692 | + result_custom = visit(iceberg_type_custom, _ConvertToArrowSchema()) |
| 693 | + expected_custom = ga.wkb().with_crs("EPSG:4326").with_edge_type(ga.EdgeType.SPHERICAL) |
| 694 | + assert result_custom == expected_custom |
| 695 | + |
| 696 | + # Test planar algorithm (no edge type set, uses default) |
| 697 | + iceberg_type_planar = GeographyType("OGC:CRS84", "planar") |
| 698 | + result_planar = visit(iceberg_type_planar, _ConvertToArrowSchema()) |
| 699 | + expected_planar = ga.wkb().with_crs("OGC:CRS84") |
| 700 | + assert result_planar == expected_planar |
| 701 | + |
| 702 | + |
599 | 703 | def test_struct_type_to_pyarrow(table_schema_simple: Schema) -> None: |
600 | 704 | expected = pa.struct( |
601 | 705 | [ |
|
0 commit comments