Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
ecbec0e
adds logic for handling requests from new adapter is bucket type os s…
ankitaluthra1 Sep 27, 2025
d506a60
adds logic for hnadling requests from new adapter is bucket type is z…
ankitaluthra1 Oct 1, 2025
9a70933
refactor bucket type enum to include value for HNS bucket type | Fixe…
ankitaluthra1 Oct 3, 2025
eb209f5
adds feature toggle behind which experimental feature support would b…
ankitaluthra1 Oct 6, 2025
0b606b1
updates tests to include experimental feature toggle
ankitaluthra1 Oct 6, 2025
409c86e
minor fix
ankitaluthra1 Oct 6, 2025
8a4ca85
moves mrd creation inside core.py
ankitaluthra1 Oct 11, 2025
c5a9eae
moves mrd creation to separate GCSFile
ankitaluthra1 Oct 12, 2025
e95495f
minor comment
ankitaluthra1 Oct 12, 2025
95440d5
Extend gcsfs to create new filesystem
suni72 Oct 11, 2025
dfcbb7f
Extend gcsfs and gcsfile to override methods. download happens synchr…
suni72 Oct 11, 2025
f3d1031
Merge pull request from ankitaluthra1/lankita-poc-zonal
ankitaluthra1 Oct 13, 2025
20b36fc
fixes new test in test_core.py
ankitaluthra1 Oct 15, 2025
c9f569a
refactors/renames GCS Filesystem Adapter
ankitaluthra1 Oct 15, 2025
e5fc935
Override _cat_file to handle other read methods of gcsfs
suni72 Oct 15, 2025
50d30b3
creates grpc client inside GCSHNSFilesystem
ankitaluthra1 Oct 16, 2025
cbf00b3
refactors to reuse grpc client in cat_ranges
ankitaluthra1 Oct 16, 2025
a202579
Move classmethods in ZonalFile to a util file
suni72 Oct 17, 2025
5064a97
Implement logic to process limits as offset and length
suni72 Oct 19, 2025
ac276f6
Add fallback logic for non zonal buckets
suni72 Oct 19, 2025
dbecb12
Add unit tests for zb_hns_utils
suni72 Oct 20, 2025
37a495b
Add test for GCSFSAdapter with read_block
suni72 Oct 21, 2025
cba7d27
Update _get_storage_layout to use a single return statement
suni72 Oct 24, 2025
4ff9fe4
Updated gcs_adapter.open to pass on correct default values to GCSFile
suni72 Oct 27, 2025
389a4b0
Move logic for handing 0 length in MRD to zb_hns_utils
suni72 Oct 27, 2025
133b4fa
Add comments for clarity
suni72 Oct 27, 2025
31b2a2f
Merge pull request #4 from ankitaluthra1/zb-features
suni72 Oct 27, 2025
e36b7ed
Updated zonal file to only create mrd for read mode.
suni72 Oct 27, 2025
25cd0ef
Updated gcs_adapter fixture to not setup bucket when real gcs endpoin…
suni72 Oct 27, 2025
8425464
Updated gcs_adapter.open to pass on correct default values to GCSFile
suni72 Oct 27, 2025
75fecce
Move logic for handing 0 length in MRD to zb_hns_utils
suni72 Oct 27, 2025
2b6af9c
Updated zonal file to only create mrd for read mode.
suni72 Oct 27, 2025
b648df4
Updated gcs_adapter fixture to not setup bucket when real gcs endpoin…
suni72 Oct 27, 2025
f71f4e8
Merge branch 'zb-ft-2' into zb-features
suni72 Oct 27, 2025
1c99137
Update test_read_block_zb to use subtests to avoid frequent setup run
suni72 Oct 28, 2025
1099375
fix: Optimizes info() and exists() methods
Mahalaxmibejugam Oct 29, 2025
d834b07
fix: Optimizes info() and exists() methods
Mahalaxmibejugam Oct 29, 2025
bfd513f
fixes lint errors
ankitaluthra1 Oct 29, 2025
efabe35
fixes comments
ankitaluthra1 Oct 29, 2025
2ed3cc6
fixes lint errors
ankitaluthra1 Oct 29, 2025
957d7b5
adds grpc and google-iam dependency
ankitaluthra1 Oct 29, 2025
cd222cb
Fix missing argument in open
suni72 Oct 30, 2025
17618d5
Fix: Raise NotImplementedError for modes other than read in Zonal bucket
suni72 Oct 30, 2025
064c286
Add ClientInfo in AsyncGrpcClient
suni72 Oct 30, 2025
8b2a8d9
refactors storage layout to use sdk control client
ankitaluthra1 Oct 31, 2025
b1f0117
fixes lint errors
ankitaluthra1 Oct 31, 2025
b254a14
Merge branch 'internal-main' into zb-features
ankitaluthra1 Nov 2, 2025
7983528
Merge pull request #5 from ankitaluthra1/zb-features
ankitaluthra1 Nov 2, 2025
cdf574a
Merge pull request from ankitaluthra1/internal-main
ankitaluthra1 Nov 2, 2025
b411bef
Merge branch 'fsspec:main' into main
ankitaluthra1 Nov 2, 2025
c47b53f
fixes lint errors
ankitaluthra1 Nov 3, 2025
e37d0fb
fixes lint errors
ankitaluthra1 Nov 3, 2025
11af000
fixes conda install error
ankitaluthra1 Nov 3, 2025
c4cf777
mocks fake test credentials for grpc client
ankitaluthra1 Nov 3, 2025
5714012
fixes conflicting lint rules black and isort
ankitaluthra1 Nov 3, 2025
fccd43a
adds missing pytest package in conda install
ankitaluthra1 Nov 3, 2025
11dd722
refactor get bucket type
ankitaluthra1 Nov 4, 2025
a2b5077
Implement Zonal Read Stream Cleanup (#7)
suni72 Nov 4, 2025
0c3df8e
adds GCSFS_EXPERIMENTAL_ZB_HNS_SUPPORT as env variable instead of kwargs
ankitaluthra1 Nov 9, 2025
0e9c2ab
removes timeout from pytest fixture coming as mark has no effect on t…
ankitaluthra1 Nov 9, 2025
c3ad9b2
Refactor: Rename GcsFileSystemAdapter to ExtendedGcsFileSystem & Fix …
suni72 Nov 12, 2025
a8945c2
Replaces __new__ with conditional import in init
ankitaluthra1 Nov 12, 2025
774b53d
Merge branch 'main' into main
ankitaluthra1 Nov 14, 2025
90d0cf4
fixes lint errors
ankitaluthra1 Nov 14, 2025
8672c28
simplified logic in cleanup_gcs for unit tests
suni72 Nov 15, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,22 @@ jobs:
- name: install
run: |
pip install -e .
- name: Run tests
- name: Run Standard Tests
run: |
export GOOGLE_APPLICATION_CREDENTIALS=$(pwd)/gcsfs/tests/fake-secret.json
pytest -vv -s \
--log-format="%(asctime)s %(levelname)s %(message)s" \
--log-date-format="%H:%M:%S" \
gcsfs/
gcsfs/ \
--ignore=gcsfs/tests/test_extended_gcsfs.py
- name: Run Extended Tests
run: |
export GOOGLE_APPLICATION_CREDENTIALS=$(pwd)/gcsfs/tests/fake-secret.json
export GCSFS_EXPERIMENTAL_ZB_HNS_SUPPORT="true"
pytest -vv -s \
--log-format="%(asctime)s %(levelname)s %(message)s" \
--log-date-format="%H:%M:%S" \
gcsfs/tests/test_extended_gcsfs.py

lint:
name: lint
Expand Down
17 changes: 17 additions & 0 deletions gcsfs/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,27 @@
import logging
import os

from ._version import get_versions

logger = logging.getLogger(__name__)
__version__ = get_versions()["version"]
del get_versions
from .core import GCSFileSystem
from .mapping import GCSMap

if os.getenv("GCSFS_EXPERIMENTAL_ZB_HNS_SUPPORT", "false").lower() in ("true", "1"):
try:
from .extended_gcsfs import ExtendedGcsFileSystem as GCSFileSystem

logger.info(
"gcsfs experimental features enabled via GCSFS_EXPERIMENTAL_ZB_HNS_SUPPORT."
)
except ImportError as e:
logger.warning(
f"GCSFS_EXPERIMENTAL_ZB_HNS_SUPPORT is set, but failed to import experimental features: {e}"
)
# Fallback to core GCSFileSystem, do not register here

__all__ = ["GCSFileSystem", "GCSMap"]

from . import _version
Expand Down
16 changes: 0 additions & 16 deletions gcsfs/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,22 +282,6 @@ class GCSFileSystem(asyn.AsyncFileSystem):
protocol = "gs", "gcs"
async_impl = True

def __new__(cls, *args, **kwargs):
"""
Factory to return a ExtendedGcsFileSystem instance if the experimental
flag is enabled.
"""
experimental_multi_bucket_support = os.environ.get(
"GCSFS_EXPERIMENTAL_ZB_HNS_SUPPORT", "false"
).lower() in ("true", "1")

if experimental_multi_bucket_support:
from .extended_gcsfs import ExtendedGcsFileSystem

return object.__new__(ExtendedGcsFileSystem)
else:
return object.__new__(cls)

def __init__(
self,
project=DEFAULT_PROJECT,
Expand Down
26 changes: 0 additions & 26 deletions gcsfs/tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from datetime import datetime, timezone
from itertools import chain
from unittest import mock
from unittest.mock import patch
from urllib.parse import parse_qs, unquote, urlparse
from uuid import uuid4

Expand All @@ -19,7 +18,6 @@
from gcsfs import __version__ as version
from gcsfs.core import GCSFileSystem, quote
from gcsfs.credentials import GoogleCredentials
from gcsfs.extended_gcsfs import ExtendedGcsFileSystem
from gcsfs.tests.conftest import a, allfiles, b, csv_files, files, text_files
from gcsfs.tests.utils import tempdir, tmpfile

Expand Down Expand Up @@ -1733,27 +1731,3 @@ def test_near_find(gcs):
def test_get_error(gcs):
with pytest.raises(FileNotFoundError):
gcs.get_file(f"{TEST_BUCKET}/doesnotexist", "other")


def test_gcs_filesystem_when_experimental_zonal_toggle_is_not_present(gcs_factory):
gcs = gcs_factory()

assert isinstance(
gcs, gcsfs.GCSFileSystem
), "Expected File system instance to be GCSFileSystem"
assert not isinstance(
gcs, ExtendedGcsFileSystem
), "Expected File system instance to be GCSFileSystem"


def test_extended_gcs_filesystem_when_experimental_zonal_toggle_is_true(gcs_factory):
try:
with patch("google.auth.default", return_value=(None, "fake-project")):
os.environ["GCSFS_EXPERIMENTAL_ZB_HNS_SUPPORT"] = "true"
gcs = gcs_factory()

assert isinstance(
gcs, ExtendedGcsFileSystem
), "Expected File system instance to be ExtendedGcsFileSystem"
finally:
del os.environ["GCSFS_EXPERIMENTAL_ZB_HNS_SUPPORT"]
67 changes: 67 additions & 0 deletions gcsfs/tests/test_init.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import os
import sys


class TestConditionalImport:
def setup_method(self, method):
"""Setup for each test method."""
self.original_env = os.environ.get("GCSFS_EXPERIMENTAL_ZB_HNS_SUPPORT")

# Snapshot original gcsfs modules
self.original_modules = {
name: mod for name, mod in sys.modules.items() if name.startswith("gcsfs")
}

# Unload gcsfs modules to force re-import during the test
modules_to_remove = list(self.original_modules.keys())
for name in modules_to_remove:
if name in sys.modules:
del sys.modules[name]

def teardown_method(self, method):
"""Teardown after each test method."""
# Reset environment variable to its original state
if self.original_env is not None:
os.environ["GCSFS_EXPERIMENTAL_ZB_HNS_SUPPORT"] = self.original_env
elif "GCSFS_EXPERIMENTAL_ZB_HNS_SUPPORT" in os.environ:
del os.environ["GCSFS_EXPERIMENTAL_ZB_HNS_SUPPORT"]

# Clear any gcsfs modules loaded/modified during this test
modules_to_remove = [name for name in sys.modules if name.startswith("gcsfs")]
for name in modules_to_remove:
if name in sys.modules:
del sys.modules[name]

# Restore the original gcsfs modules from the snapshot to avoid side effect
# affecting other tests
sys.modules.update(self.original_modules)

def test_experimental_env_unset(self):
"""
Tests gcsfs.GCSFileSystem is core.GCSFileSystem when
GCSFS_EXPERIMENTAL_ZB_HNS_SUPPORT is NOT set.
"""
if "GCSFS_EXPERIMENTAL_ZB_HNS_SUPPORT" in os.environ:
del os.environ["GCSFS_EXPERIMENTAL_ZB_HNS_SUPPORT"]

import gcsfs

assert (
gcsfs.GCSFileSystem is gcsfs.core.GCSFileSystem
), "Should be core.GCSFileSystem"
assert not hasattr(
gcsfs, "ExtendedGcsFileSystem"
), "ExtendedGcsFileSystem should not be imported directly on gcsfs"

def test_experimental_env_set(self):
"""
Tests gcsfs.GCSFileSystem is extended_gcsfs.ExtendedGcsFileSystem when
GCSFS_EXPERIMENTAL_ZB_HNS_SUPPORT IS set.
"""
os.environ["GCSFS_EXPERIMENTAL_ZB_HNS_SUPPORT"] = "true"

import gcsfs

assert (
gcsfs.GCSFileSystem is gcsfs.extended_gcsfs.ExtendedGcsFileSystem
), "Should be ExtendedGcsFileSystem"
Loading