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

Accept PathLike objects in rasterio.open #2231

Merged
merged 5 commits into from
Jul 27, 2021
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
11 changes: 5 additions & 6 deletions rasterio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from contextlib import contextmanager
import logging
from logging import NullHandler
from pathlib import Path
import os

import rasterio._loading
with rasterio._loading.add_gdal_dll_directories():
Expand Down Expand Up @@ -72,7 +72,7 @@ def open(fp, mode='r', driver=None, width=None, height=None, count=None,

Parameters
----------
fp : str, file object or pathlib.Path object
fp : str, file object or PathLike object
A filename or URL, a file object opened in binary ('rb') mode,
or a Path object.
mode : str, optional
Expand Down Expand Up @@ -156,7 +156,7 @@ def open(fp, mode='r', driver=None, width=None, height=None, count=None,
"""

if not isinstance(fp, str):
if not (hasattr(fp, 'read') or hasattr(fp, 'write') or isinstance(fp, Path)):
if not (hasattr(fp, 'read') or hasattr(fp, 'write') or isinstance(fp, os.PathLike)):
raise TypeError("invalid path or file: {0!r}".format(fp))
if mode and not isinstance(mode, str):
raise TypeError("invalid mode: {0!r}".format(mode))
Expand Down Expand Up @@ -209,9 +209,8 @@ def fp_writer(fp):
return fp_writer(fp)

else:
# If a pathlib.Path instance is given, convert it to a string path.
if isinstance(fp, Path):
fp = str(fp)
# If a PathLike instance is given, convert it to a string path.
fp = os.fspath(fp)

# The 'normal' filename or URL path.
path = parse_path(fp)
Expand Down
7 changes: 4 additions & 3 deletions rasterio/merge.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from contextlib import contextmanager
import logging
import os
import math
from pathlib import Path
import warnings
Expand Down Expand Up @@ -92,7 +93,7 @@ def merge(

Parameters
----------
datasets : list of dataset objects opened in 'r' mode, filenames or pathlib.Path objects
datasets : list of dataset objects opened in 'r' mode, filenames or PathLike objects
source datasets to be merged.
bounds: tuple, optional
Bounds of the output image (left, bottom, right, top).
Expand Down Expand Up @@ -148,7 +149,7 @@ def function(merged_data, new_data, merged_mask, new_mask, index=None, roff=None
Whether to adjust output image bounds so that pixel coordinates
are integer multiples of pixel size, matching the ``-tap``
options of GDAL utilities. Default: False.
dst_path : str or Pathlike, optional
dst_path : str or PathLike, optional
Path of output dataset
dst_kwds : dict, optional
Dictionary of creation options and other paramters that will be
Expand Down Expand Up @@ -177,7 +178,7 @@ def function(merged_data, new_data, merged_mask, new_mask, index=None, roff=None
.format(method, list(MERGE_METHODS.keys())))

# Create a dataset_opener object to use in several places in this function.
if isinstance(datasets[0], str) or isinstance(datasets[0], Path):
if isinstance(datasets[0], (str, os.PathLike)):
dataset_opener = rasterio.open
else:

Expand Down
31 changes: 13 additions & 18 deletions rasterio/shutil.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,7 @@
include "gdal.pxi"

import logging

try:
from pathlib import Path
except ImportError: # pragma: no cover
class Path:
pass
import os

from rasterio._io cimport DatasetReaderBase
from rasterio._err cimport exc_wrap_int, exc_wrap_pointer
Expand Down Expand Up @@ -63,9 +58,9 @@ def copy(src, dst, driver=None, strict=True, **creation_options):

Parameters
----------
src : str or pathlib.Path or dataset object opened in 'r' mode
src : str or PathLike or dataset object opened in 'r' mode
Source dataset
dst : str or pathlib.Path
dst : str or PathLike
Output dataset path
driver : str, optional
Output driver name
Expand Down Expand Up @@ -100,10 +95,10 @@ def copy(src, dst, driver=None, strict=True, **creation_options):
c_strictness = strict

# Convert src and dst Paths to strings.
if isinstance(src, Path):
src = str(src)
if isinstance(dst, Path):
dst = str(dst)
if isinstance(src, os.PathLike):
src = os.fspath(src)
if isinstance(dst, os.PathLike):
dst = os.fspath(dst)

if driver is None:
driver = driver_from_extension(dst)
Expand Down Expand Up @@ -162,9 +157,9 @@ def copyfiles(src, dst):

Parameters
----------
src : str or pathlib.Path
src : str or PathLike
Source dataset
dst : str or pathlib.Path
dst : str or PathLike
Target dataset

Returns
Expand All @@ -177,10 +172,10 @@ def copyfiles(src, dst):
cdef GDALDriverH h_driver = NULL

# Convert src and dst Paths to strings.
if isinstance(src, Path):
src = str(src)
if isinstance(dst, Path):
dst = str(dst)
if isinstance(src, os.PathLike):
src = os.fspath(src)
if isinstance(dst, os.PathLike):
dst = os.fspath(dst)

src_path = parse_path(src)
dst_path = parse_path(dst)
Expand Down
13 changes: 9 additions & 4 deletions tests/test_open.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import pytest
import rasterio
from pathlib import Path


def test_open_bad_path():
Expand All @@ -23,10 +24,14 @@ def test_open_bad_driver():


def test_open_pathlib_path():
try:
from pathlib import Path
except ImportError:
return
tif = Path.cwd() / 'tests' / 'data' / 'RGB.byte.tif'
with rasterio.open(tif) as src:
assert src.count == 3


def test_open_pathlike():
class MyPath:
def __fspath__(self):
return str(Path.cwd() / 'tests' / 'data' / 'RGB.byte.tif')
with rasterio.open(MyPath()) as src:
assert src.count == 3
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes!

2 changes: 1 addition & 1 deletion tests/test_rio_merge.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import os
import sys
import textwrap
from pathlib import Path

import affine
from click.testing import CliRunner
Expand All @@ -12,7 +13,6 @@
import pytest

import rasterio
from rasterio import Path
from rasterio.enums import Resampling
from rasterio.merge import merge
from rasterio.rio.main import main_group
Expand Down