Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preserve parameters in paths #65

Merged
merged 4 commits into from
Sep 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
runs-on: [ubuntu-latest]
defaults:
run:
Expand Down
4 changes: 2 additions & 2 deletions src/fsspec_xrootd/xrootd.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from __future__ import annotations

Check warning on line 1 in src/fsspec_xrootd/xrootd.py

View workflow job for this annotation

GitHub Actions / Format

Missing module docstring

import asyncio
import io
Expand All @@ -15,18 +15,18 @@
from fsspec.asyn import AsyncFileSystem, _run_coros_in_chunks, sync, sync_wrapper
from fsspec.exceptions import FSTimeoutError
from fsspec.spec import AbstractBufferedFile
from XRootD import client

Check failure on line 18 in src/fsspec_xrootd/xrootd.py

View workflow job for this annotation

GitHub Actions / Format

Unable to import 'XRootD'
from XRootD.client.flags import (

Check failure on line 19 in src/fsspec_xrootd/xrootd.py

View workflow job for this annotation

GitHub Actions / Format

Unable to import 'XRootD.client.flags'
DirListFlags,
MkDirFlags,
OpenFlags,
QueryCode,
StatInfoFlags,
)
from XRootD.client.responses import HostList, XRootDStatus

Check failure on line 26 in src/fsspec_xrootd/xrootd.py

View workflow job for this annotation

GitHub Actions / Format

Unable to import 'XRootD.client.responses'


class ErrorCodes(IntEnum):

Check warning on line 29 in src/fsspec_xrootd/xrootd.py

View workflow job for this annotation

GitHub Actions / Format

Missing class docstring
INVALID_PATH = 400


Expand All @@ -35,7 +35,7 @@


def _async_wrap(
func: Callable[..., XRootDStatus | tuple[XRootDStatus, T]]
func: Callable[..., XRootDStatus | tuple[XRootDStatus, T]],
) -> Callable[..., Coroutine[Any, Any, tuple[XRootDStatus, T]]]:
"""Wraps pyxrootd functions to run asynchronously. Returns an async callable

Expand All @@ -51,13 +51,13 @@
asyncio.get_running_loop().create_future()
)

def callback(status: XRootDStatus, content: T, servers: HostList) -> None:

Check warning on line 54 in src/fsspec_xrootd/xrootd.py

View workflow job for this annotation

GitHub Actions / Format

Unused argument 'servers'
if future.cancelled():
return
loop = future.get_loop()
try:
loop.call_soon_threadsafe(future.set_result, (status, content))
except Exception as exc:

Check warning on line 60 in src/fsspec_xrootd/xrootd.py

View workflow job for this annotation

GitHub Actions / Format

Catching too general exception Exception
loop.call_soon_threadsafe(future.set_exception, exc)

async def wrapped(*args: Any, **kwargs: Any) -> tuple[XRootDStatus, T]:
Expand Down Expand Up @@ -142,7 +142,7 @@
handle: client.File


class ReadonlyFileHandleCache:

Check warning on line 145 in src/fsspec_xrootd/xrootd.py

View workflow job for this annotation

GitHub Actions / Format

Missing class docstring
def __init__(self, loop: Any, max_items: int | None, ttl: int):
self.loop = loop
self._max_items = max_items
Expand Down Expand Up @@ -170,7 +170,7 @@
item.handle.close(callback=lambda *args: None)
cache.clear()

def close_all(self) -> None:

Check warning on line 173 in src/fsspec_xrootd/xrootd.py

View workflow job for this annotation

GitHub Actions / Format

Missing function or method docstring
self._close_all(self.loop, self._cache)

async def _close(self, url: str, timeout: int) -> None:
Expand All @@ -183,7 +183,7 @@
close = sync_wrapper(_close)

async def _start_pruner(self) -> None:
self._prune_task = asyncio.create_task(self._pruner())

Check warning on line 186 in src/fsspec_xrootd/xrootd.py

View workflow job for this annotation

GitHub Actions / Format

Attribute '_prune_task' defined outside __init__

async def _pruner(self) -> None:
while True:
Expand Down Expand Up @@ -220,7 +220,7 @@
return handle


class XRootDFileSystem(AsyncFileSystem): # type: ignore[misc]

Check warning on line 223 in src/fsspec_xrootd/xrootd.py

View workflow job for this annotation

GitHub Actions / Format

Missing class docstring

Check warning on line 223 in src/fsspec_xrootd/xrootd.py

View workflow job for this annotation

GitHub Actions / Format

Method '_cp_file' is abstract in class 'AsyncFileSystem' but is not overridden in child class 'XRootDFileSystem'

Check warning on line 223 in src/fsspec_xrootd/xrootd.py

View workflow job for this annotation

GitHub Actions / Format

Method '_pipe_file' is abstract in class 'AsyncFileSystem' but is not overridden in child class 'XRootDFileSystem'
protocol = "root"
root_marker = "/"
default_timeout = 60
Expand Down Expand Up @@ -302,7 +302,7 @@
def _strip_protocol(cls, path: str | list[str]) -> Any:
if isinstance(path, str):
if path.startswith(cls.protocol):
return client.URL(path).path.rstrip("/") or cls.root_marker
return client.URL(path).path_with_params.rstrip("/") or cls.root_marker
# assume already stripped
return path.rstrip("/") or cls.root_marker
elif isinstance(path, list):
Expand Down
11 changes: 10 additions & 1 deletion tests/test_basicio.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,16 @@ def test_path_parsing():
"root://serv.er//dir/",
]
)
assert paths == ["/blah", "/more", "dir", "/dir"]
assert paths == [
"/blah",
"/more",
"dir",
"/dir",
]
# get_fs_token_paths will expand glob patterns if '*', '?', or '[' are present
# so we need to test parameter parsing using a different method
fs, path = fsspec.url_to_fs("root://server.com//blah?param1=1&param2=2")
assert path == "/blah?param1=1&param2=2"


def test_pickle(localserver, clear_server):
Expand Down
Loading