Skip to content
Open
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
9 changes: 7 additions & 2 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ You can set up a development environment by running:
```bash
python3 -m venv .venv
source ./.venv/bin/activate
pip install -v -e .[dev,xrootd]
pip install -v -e .[dev]
```

If you have the
Expand All @@ -41,7 +41,7 @@ can instead do:

```bash
py -m venv .venv
py -m install -v -e .[dev,xrootd]
py -m install -v -e .[dev]
```

# Post setup
Expand All @@ -65,6 +65,11 @@ Use pytest to run the unit checks:
pytest
```

The local integration tests also start an `xrootd` server process. If the Python
wheel does not provide an `xrootd` executable in your environment, install one
separately, for example via `conda install -c conda-forge xrootd` or
`brew install xrootd`.

# Building docs

You can build the docs using:
Expand Down
12 changes: 12 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,18 @@ jobs:
run: mamba install -c conda-forge xrootd
- name: Install package
run: python -m pip install ".[test]"
- name: Configure XRootD wheel library path
if: runner.os == 'macOS'
run: |
PYXROOTD_DIR=$(python - <<'PY'
import pathlib

import pyxrootd

print(pathlib.Path(pyxrootd.__file__).parent)
PY
)
echo "DYLD_LIBRARY_PATH=${PYXROOTD_DIR}${DYLD_LIBRARY_PATH:+:${DYLD_LIBRARY_PATH}}" >> "${GITHUB_ENV}"
- name: Test package
run: |
python -m pytest -vv tests --reruns 3 --reruns-delay 5 --only-rerun "(?i)OSError|FileNotFoundError|timeout|expired|connection|socket"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
python-version: "3.14"

- name: Install package
run: python -m pip install -e ".[docs,xrootd]"
run: python -m pip install -e ".[docs]"

- name: Build documentation
run: |
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,6 @@ cython_debug/

# setuptools_scm
src/*/_version.py

# JetBrains IDEs
.idea/
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,21 @@ An XRootD implementation for fsspec.
## Install

```bash
pip install "fsspec-xrootd[xrootd]"
pip install fsspec-xrootd
```

Supports Python 3.9 and newer.

## Purpose

To allow fsspec to use XRootD accessible storage systems. Install fsspec-xrootd
with the optional `xrootd` extra alongside fsspec and have easy access to files
stored on XRootD servers. Once installed, fsspec will be able to work with urls
with the 'root' protocol. Only tested with Linux at this time.
alongside fsspec and have easy access to files stored on XRootD servers. Once
installed, fsspec will be able to work with urls with the 'root' protocol. Only
tested with Linux at this time.

The Python package depends on the XRootD client bindings directly. If you want
to run the local integration tests, you will also need an `xrootd` server
executable available on `PATH`.

## Documentation

Expand Down
12 changes: 8 additions & 4 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,19 @@ Install

.. code:: bash

pip install "fsspec-xrootd[xrootd]"
pip install fsspec-xrootd

Purpose
-------

To allow fsspec to use XRootD accessible storage systems. Install
``fsspec-xrootd[xrootd]`` alongside fsspec and have easy access to files stored
on XRootD servers. Once installed, fsspec will be able to work with urls with
the ``root`` protocol. Only tested with Linux at this time.
``fsspec-xrootd`` alongside fsspec and have easy access to files stored on
XRootD servers. Once installed, fsspec will be able to work with urls with the
``root`` protocol. Only tested with Linux at this time.

The Python package depends on the XRootD client bindings directly. Running the
local integration tests also requires an ``xrootd`` server executable on
``PATH``.

.. toctree::
:maxdepth: 3
Expand Down
4 changes: 2 additions & 2 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def tests(session: nox.Session) -> None:
"""
Run the unit and regular tests.
"""
session.install(".[test,xrootd]")
session.install(".[test]")
session.run("pytest", *session.posargs)


Expand All @@ -34,7 +34,7 @@ def docs(session: nox.Session) -> None:
Build the docs. Pass "serve" to serve.
"""

session.install(".[docs,xrootd]")
session.install(".[docs]")
session.chdir("docs")
session.run("sphinx-build", "-M", "html", ".", "_build")

Expand Down
3 changes: 1 addition & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ classifiers = [
"Programming Language :: Python :: 3.14",
"Topic :: Scientific/Engineering",
]
dependencies = ["fsspec"]
dependencies = ["fsspec", "xrootd>=6.0.1"]

[project.urls]
Documentation = "https://fsspec_xrootd.readthedocs.io/"
Expand All @@ -50,7 +50,6 @@ docs = [
"sphinx-copybutton",
]
test = ["pytest>=6", "pytest-rerunfailures", "pytest-timeout"]
xrootd = ["xrootd>=6.0.0"]

[tool.setuptools]
include-package-data = true
Expand Down
27 changes: 1 addition & 26 deletions src/fsspec_xrootd/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,7 @@

from __future__ import annotations

from typing import TYPE_CHECKING, Any

from ._version import version as __version__

if TYPE_CHECKING:
from .xrootd import XRootDFile, XRootDFileSystem
from .xrootd import XRootDFile, XRootDFileSystem

__all__ = ("__version__", "XRootDFileSystem", "XRootDFile")


def __getattr__(name: str) -> Any:
if name not in {"XRootDFile", "XRootDFileSystem"}:
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")

try:
from .xrootd import XRootDFile, XRootDFileSystem
except ModuleNotFoundError as exc:
if exc.name == "XRootD":
raise ModuleNotFoundError(
"The 'xrootd' package is required to use fsspec-xrootd. "
'Install it with `pip install "fsspec-xrootd[xrootd]"`.'
) from exc
raise

globals().update({
"XRootDFile": XRootDFile,
"XRootDFileSystem": XRootDFileSystem,
})
return globals()[name]
25 changes: 0 additions & 25 deletions tests/test_package.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,7 @@
from __future__ import annotations

import builtins
import importlib
import sys

import pytest

import fsspec_xrootd as m


def test_version():
assert m.__version__


def test_import_without_xrootd(monkeypatch):
original_import = builtins.__import__

def raising_import(name, *args, **kwargs):
if name == "XRootD":
raise ModuleNotFoundError("No module named 'XRootD'", name="XRootD")
return original_import(name, *args, **kwargs)

monkeypatch.setattr(builtins, "__import__", raising_import)
for module_name in ("fsspec_xrootd", "fsspec_xrootd.xrootd", "XRootD"):
sys.modules.pop(module_name, None)

module = importlib.import_module("fsspec_xrootd")

assert module.__version__
with pytest.raises(ModuleNotFoundError, match="Install it with"):
_ = module.XRootDFileSystem
Loading