From a1cb28a77ebca80c8a804f24d09350e02ed9bf63 Mon Sep 17 00:00:00 2001 From: Sean Gillies Date: Fri, 11 Dec 2020 16:30:23 -0700 Subject: [PATCH] Remove compat module (#2067) * Remove compat imports in tests * Remove compat module and future namespace imports --- CHANGES.txt | 5 +++++ rasterio/__init__.py | 26 ++++++-------------------- rasterio/_base.pyx | 7 ++----- rasterio/_crs.pyx | 5 ++--- rasterio/_io.pyx | 17 ++++++----------- rasterio/_warp.pyx | 5 +++-- rasterio/compat.py | 35 ----------------------------------- rasterio/crs.py | 4 ++-- rasterio/env.py | 4 ++-- rasterio/merge.py | 3 +-- rasterio/path.py | 5 +++-- rasterio/plot.py | 4 +--- rasterio/profiles.py | 2 +- rasterio/rio/stack.py | 4 ++-- rasterio/transform.py | 5 +---- rasterio/warp.py | 8 +++----- rasterio/windows.py | 3 +-- tests/test_path.py | 5 ++--- tests/test_rio_blocks.py | 3 +-- 19 files changed, 44 insertions(+), 106 deletions(-) delete mode 100644 rasterio/compat.py diff --git a/CHANGES.txt b/CHANGES.txt index f3a2c3d8..ccb96b9b 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,6 +1,11 @@ Changes ======= +1.2b1 +----- + +- Remove compat module and future namespace imports (#2067). + 1.2a1 ----- diff --git a/rasterio/__init__.py b/rasterio/__init__.py index 0498c659..f0f19d2d 100644 --- a/rasterio/__init__.py +++ b/rasterio/__init__.py @@ -1,23 +1,10 @@ """Rasterio""" -from __future__ import absolute_import - from collections import namedtuple from contextlib import contextmanager import logging - -try: - from pathlib import Path -except ImportError: # pragma: no cover - class Path: - pass - -try: - from logging import NullHandler -except ImportError: # pragma: no cover - class NullHandler(logging.Handler): - def emit(self, record): - pass +from logging import NullHandler +from pathlib import Path from rasterio._base import gdal_version from rasterio.drivers import driver_from_extension, is_blacklisted @@ -26,7 +13,6 @@ from rasterio.dtypes import ( complex_, check_dtype) from rasterio.env import ensure_env_with_credentials, Env from rasterio.errors import RasterioIOError, DriverCapabilityError -from rasterio.compat import string_types from rasterio.io import ( DatasetReader, get_writer_for_path, get_writer_for_driver, MemoryFile) from rasterio.profiles import default_gtiff_profile @@ -41,7 +27,7 @@ import rasterio.enums import rasterio.path __all__ = ['band', 'open', 'pad', 'Env'] -__version__ = "1.2a1" +__version__ = "1.2b1" __gdal_version__ = gdal_version() # Rasterio attaches NullHandler to the 'rasterio' logger and its @@ -153,12 +139,12 @@ def open(fp, mode='r', driver=None, width=None, height=None, count=None, ... dataset.write(...) """ - if not isinstance(fp, string_types): + if not isinstance(fp, str): if not (hasattr(fp, 'read') or hasattr(fp, 'write') or isinstance(fp, Path)): raise TypeError("invalid path or file: {0!r}".format(fp)) - if mode and not isinstance(mode, string_types): + if mode and not isinstance(mode, str): raise TypeError("invalid mode: {0!r}".format(mode)) - if driver and not isinstance(driver, string_types): + if driver and not isinstance(driver, str): raise TypeError("invalid driver: {0!r}".format(driver)) if dtype and not check_dtype(dtype): raise TypeError("invalid dtype: {0!r}".format(dtype)) diff --git a/rasterio/_base.pyx b/rasterio/_base.pyx index fde5f3b3..81dde4b0 100644 --- a/rasterio/_base.pyx +++ b/rasterio/_base.pyx @@ -2,13 +2,12 @@ """Numpy-free base classes.""" -from __future__ import absolute_import - from collections import defaultdict import logging import math import os import warnings + from libc.string cimport strncmp from rasterio._err import ( @@ -17,7 +16,6 @@ from rasterio._err import ( from rasterio._err cimport exc_wrap_pointer, exc_wrap_int, exc_wrap from rasterio._shim cimport open_dataset, osr_get_name, osr_set_traditional_axis_mapping_strategy -from rasterio.compat import string_types from rasterio.control import GroundControlPoint from rasterio.rpc import RPC from rasterio import dtypes @@ -37,7 +35,6 @@ from rasterio import windows include "gdal.pxi" - log = logging.getLogger(__name__) @@ -251,7 +248,7 @@ cdef class DatasetBase(object): # driver may be a string or list of strings. If the # former, we put it into a list. - if isinstance(driver, string_types): + if isinstance(driver, str): driver = [driver] # Read-only + Rasters + Sharing + Errors diff --git a/rasterio/_crs.pyx b/rasterio/_crs.pyx index 72e4a671..4b0d33b8 100644 --- a/rasterio/_crs.pyx +++ b/rasterio/_crs.pyx @@ -5,7 +5,6 @@ import logging import rasterio._env from rasterio._err import CPLE_BaseError, CPLE_NotSupportedError -from rasterio.compat import string_types from rasterio.errors import CRSError from rasterio._base cimport _osr_from_crs as osr_from_crs @@ -379,7 +378,7 @@ cdef class _CRS(object): """ cdef char *wkt_c = NULL - if not isinstance(wkt, string_types): + if not isinstance(wkt, str): raise ValueError("A string is expected") wkt_b= wkt.encode('utf-8') @@ -416,7 +415,7 @@ cdef class _CRS(object): """ cdef const char *text_c = NULL - if not isinstance(text, string_types): + if not isinstance(text, str): raise ValueError("A string is expected") text_b = text.encode('utf-8') diff --git a/rasterio/_io.pyx b/rasterio/_io.pyx index ab5104d5..408e6316 100644 --- a/rasterio/_io.pyx +++ b/rasterio/_io.pyx @@ -1,9 +1,6 @@ """Rasterio input/output.""" - # cython: boundscheck=False, c_string_type=unicode, c_string_encoding=utf8 -from __future__ import absolute_import - include "directives.pxi" include "gdal.pxi" @@ -21,7 +18,6 @@ from rasterio._base import tastes_like_gdal, gdal_version from rasterio._err import ( GDALError, CPLE_OpenFailedError, CPLE_IllegalArgError, CPLE_BaseError, CPLE_AWSObjectNotFoundError) from rasterio.crs import CRS -from rasterio.compat import text_type, string_types from rasterio import dtypes from rasterio.enums import ColorInterp, MaskFlags, Resampling from rasterio.errors import ( @@ -44,7 +40,6 @@ from rasterio._err cimport exc_wrap_int, exc_wrap_pointer, exc_wrap_vsilfile from rasterio._shim cimport ( open_dataset, delete_nodata_value, io_band, io_multi_band, io_multi_mask) - log = logging.getLogger(__name__) @@ -1052,7 +1047,7 @@ cdef class DatasetWriterBase(DatasetReaderBase): # Validate write mode arguments. log.debug("Path: %s, mode: %s, driver: %s", path, mode, driver) if mode in ('w', 'w+'): - if not isinstance(driver, string_types): + if not isinstance(driver, str): raise TypeError("A driver name string is required.") try: width = int(width) @@ -1165,7 +1160,7 @@ cdef class DatasetWriterBase(DatasetReaderBase): # driver may be a string or list of strings. If the # former, put it into a list. - if isinstance(driver, string_types): + if isinstance(driver, str): driver = [driver] # flags: Update + Raster + Errors @@ -1431,8 +1426,8 @@ cdef class DatasetWriterBase(DatasetReaderBase): GDALGetMetadata(hobj, domain_c)) for key, value in kwargs.items(): - key_b = text_type(key).encode('utf-8') - value_b = text_type(value).encode('utf-8') + key_b = str(key).encode('utf-8') + value_b = str(value).encode('utf-8') key_c = key_b value_c = value_b papszStrList = CSLSetNameValue( @@ -1948,7 +1943,7 @@ cdef class BufferedDatasetWriterBase(DatasetWriterBase): log.debug("Path: %s, mode: %s, driver: %s", path, mode, driver) if mode in ('w', 'w+'): - if not isinstance(driver, string_types): + if not isinstance(driver, str): raise TypeError("A driver name string is required.") try: width = int(width) @@ -2121,7 +2116,7 @@ def virtual_file_to_buffer(filename): cdef unsigned char *buff = NULL cdef const char *cfilename = NULL cdef vsi_l_offset buff_len = 0 - filename_b = filename if not isinstance(filename, string_types) else filename.encode('utf-8') + filename_b = filename if not isinstance(filename, str) else filename.encode('utf-8') cfilename = filename_b buff = VSIGetMemFileBuffer(cfilename, &buff_len, 0) n = buff_len diff --git a/rasterio/_warp.pyx b/rasterio/_warp.pyx index c6802e9a..00ae1e5b 100644 --- a/rasterio/_warp.pyx +++ b/rasterio/_warp.pyx @@ -3,6 +3,8 @@ include "gdal.pxi" +from collections import UserDict +from collections.abc import Mapping import logging import uuid import warnings @@ -17,7 +19,6 @@ from rasterio._err import ( CPLE_BaseError, CPLE_IllegalArgError, CPLE_NotSupportedError, CPLE_AppDefinedError, CPLE_OpenFailedError) from rasterio import dtypes -from rasterio.compat import DICT_TYPES from rasterio.control import GroundControlPoint from rasterio.enums import Resampling, MaskFlags, ColorInterp from rasterio.env import GDALVersion @@ -107,7 +108,7 @@ def _transform_geom( factory = new OGRGeometryFactory() try: - if isinstance(geom, DICT_TYPES) or hasattr(geom, "__geo_interface__"): + if isinstance(geom, (dict, Mapping, UserDict)) or hasattr(geom, "__geo_interface__"): out_geom = _transform_single_geom(geom, factory, transform, options, precision) else: out_geom = [ diff --git a/rasterio/compat.py b/rasterio/compat.py deleted file mode 100644 index 966c533d..00000000 --- a/rasterio/compat.py +++ /dev/null @@ -1,35 +0,0 @@ -"""Python 2-3 compatibility.""" - -import itertools -import sys -import warnings - - -if sys.version_info[0] >= 3: # pragma: no cover - string_types = str, - text_type = str - integer_types = int, - zip_longest = itertools.zip_longest - import configparser - from urllib.parse import urlparse - from collections import UserDict - from collections.abc import Iterable, Mapping - from inspect import getfullargspec as getargspec - import pathlib - -else: # pragma: no cover - warnings.warn("Python 2 compatibility will be removed after version 1.1", DeprecationWarning) - string_types = basestring, - text_type = unicode - integer_types = int, long - zip_longest = itertools.izip_longest - import ConfigParser as configparser - from urlparse import urlparse - from UserDict import UserDict - from inspect import getargspec - from collections import Iterable, Mapping - -# Users can pass in objects that subclass a few different objects -# More specifically, rasterio has a CRS() class that subclasses UserDict() -# In Python 2 UserDict() is in its own module and does not subclass Mapping() -DICT_TYPES = (dict, Mapping, UserDict) diff --git a/rasterio/crs.py b/rasterio/crs.py index b442435c..4c5850ed 100644 --- a/rasterio/crs.py +++ b/rasterio/crs.py @@ -10,11 +10,11 @@ used. """ +from collections.abc import Mapping import json import pickle from rasterio._crs import _CRS, all_proj_keys, _epsg_treats_as_latlong, _epsg_treats_as_northingeasting -from rasterio.compat import Mapping, string_types from rasterio.errors import CRSError @@ -492,7 +492,7 @@ class CRS(Mapping): return cls.from_epsg(value) elif isinstance(value, dict): return cls(**value) - elif isinstance(value, string_types): + elif isinstance(value, str): return cls.from_string(value, morph_from_esri_dialect=morph_from_esri_dialect) else: raise CRSError("CRS is invalid: {!r}".format(value)) diff --git a/rasterio/env.py b/rasterio/env.py index 9fdbcecb..60388995 100644 --- a/rasterio/env.py +++ b/rasterio/env.py @@ -2,6 +2,7 @@ import attr from functools import wraps, total_ordering +from inspect import getfullargspec as getargspec import logging import os import re @@ -11,7 +12,6 @@ import warnings from rasterio._env import ( GDALEnv, get_gdal_config, set_gdal_config, GDALDataFinder, PROJDataFinder, set_proj_data_search_path) -from rasterio.compat import string_types, getargspec from rasterio.errors import ( EnvError, GDALVersionError, RasterioDeprecationWarning) from rasterio.session import Session, DummySession @@ -477,7 +477,7 @@ class GDALVersion(object): return input if isinstance(input, tuple): return cls(*input) - elif isinstance(input, string_types): + elif isinstance(input, str): # Extract major and minor version components. # alpha, beta, rc suffixes ignored match = re.search(r'^\d+\.\d+', input) diff --git a/rasterio/merge.py b/rasterio/merge.py index 3df3de0a..705090eb 100644 --- a/rasterio/merge.py +++ b/rasterio/merge.py @@ -9,7 +9,6 @@ import warnings import numpy as np import rasterio -from rasterio.compat import string_types from rasterio.enums import Resampling from rasterio import windows from rasterio.transform import Affine @@ -125,7 +124,7 @@ def merge( .format(method, MERGE_METHODS)) # Create a dataset_opener object to use in several places in this function. - if isinstance(datasets[0], string_types) or isinstance(datasets[0], Path): + if isinstance(datasets[0], str) or isinstance(datasets[0], Path): dataset_opener = rasterio.open else: diff --git a/rasterio/path.py b/rasterio/path.py index 15247a97..fd7e9d1a 100644 --- a/rasterio/path.py +++ b/rasterio/path.py @@ -1,11 +1,12 @@ """Dataset paths, identifiers, and filenames""" +import pathlib import re import sys +from urllib.parse import urlparse import attr -from rasterio.compat import pathlib, string_types, urlparse from rasterio.errors import PathError # Supported URI schemes and their mapping to GDAL's VSI suffix. @@ -134,7 +135,7 @@ def parse_path(path): elif pathlib and isinstance(path, pathlib.PurePath): return ParsedPath(path.as_posix(), None, None) - elif isinstance(path, string_types): + elif isinstance(path, str): if sys.platform == "win32" and re.match(r"^[a-zA-Z]\:", path): if pathlib: diff --git a/rasterio/plot.py b/rasterio/plot.py index a3807161..78cf14fa 100644 --- a/rasterio/plot.py +++ b/rasterio/plot.py @@ -5,9 +5,8 @@ Most can handle a numpy array or `rasterio.Band()`. Primarily supports `$ rio insp`. """ -from __future__ import absolute_import - from collections import OrderedDict +from itertools import zip_longest import logging import warnings @@ -16,7 +15,6 @@ import numpy as np import rasterio from rasterio.io import DatasetReader from rasterio.transform import guard_transform -from rasterio.compat import zip_longest logger = logging.getLogger(__name__) diff --git a/rasterio/profiles.py b/rasterio/profiles.py index c55f6136..e491efe4 100644 --- a/rasterio/profiles.py +++ b/rasterio/profiles.py @@ -1,8 +1,8 @@ """Raster dataset profiles.""" +from collections import UserDict import warnings -from rasterio.compat import UserDict from rasterio.dtypes import uint8 diff --git a/rasterio/rio/stack.py b/rasterio/rio/stack.py index 5de35df7..0d65a385 100644 --- a/rasterio/rio/stack.py +++ b/rasterio/rio/stack.py @@ -1,12 +1,12 @@ """$ rio stack""" - +from collections.abc import Iterable +from itertools import zip_longest import logging import click import rasterio -from rasterio.compat import Iterable, zip_longest from rasterio.rio import options from rasterio.rio.helpers import resolve_inout diff --git a/rasterio/transform.py b/rasterio/transform.py index af26af96..9743713e 100644 --- a/rasterio/transform.py +++ b/rasterio/transform.py @@ -1,14 +1,11 @@ """Geospatial transforms""" -from __future__ import division - +from collections.abc import Iterable import math from affine import Affine from rasterio._transform import _transform_from_gcps -from rasterio.compat import Iterable - IDENTITY = Affine.identity() GDAL_IDENTITY = IDENTITY.to_gdal() diff --git a/rasterio/warp.py b/rasterio/warp.py index 87f56b1e..22c0de07 100644 --- a/rasterio/warp.py +++ b/rasterio/warp.py @@ -1,19 +1,17 @@ """Raster warping and reprojection.""" - -from __future__ import absolute_import, division - from math import ceil, floor +from affine import Affine import numpy as np import rasterio -from affine import Affine + from rasterio._base import _transform -from rasterio._warp import _calculate_default_transform, _reproject, _transform_geom from rasterio.enums import Resampling from rasterio.env import GDALVersion, ensure_env, require_gdal_version from rasterio.errors import GDALBehaviorChangeException, TransformError from rasterio.transform import array_bounds +from rasterio._warp import _calculate_default_transform, _reproject, _transform_geom # Gauss (7) is not supported for warp SUPPORTED_RESAMPLING = [r for r in Resampling if r.value < 7] diff --git a/rasterio/windows.py b/rasterio/windows.py index e74830c8..c64d7f01 100644 --- a/rasterio/windows.py +++ b/rasterio/windows.py @@ -17,8 +17,8 @@ The newer float precision read-write window capabilities of Rasterio require instances of Window to be used. """ -from __future__ import division import collections +from collections.abc import Iterable import functools import math import warnings @@ -27,7 +27,6 @@ import attr from affine import Affine import numpy as np -from rasterio.compat import Iterable from rasterio.errors import WindowError from rasterio.transform import rowcol, guard_transform diff --git a/tests/test_path.py b/tests/test_path.py index d5c45875..7602d540 100644 --- a/tests/test_path.py +++ b/tests/test_path.py @@ -5,7 +5,6 @@ import sys import pytest import rasterio -import rasterio.compat from rasterio.errors import PathError from rasterio.path import parse_path, vsi_path, ParsedPath, UnparsedPath @@ -39,7 +38,7 @@ def test_parsed_path_remote(scheme): @pytest.mark.parametrize("uri", ["/test.tif", "file:///test.tif"]) def test_parsed_path_not_remote(uri): """Check for paths that are not remote""" - assert False == ParsedPath.from_uri(uri).is_remote + assert not ParsedPath.from_uri(uri).is_remote @pytest.mark.parametrize('scheme', [None, '', 'zip', 'tar', 'file', 'zip+file']) @@ -53,7 +52,7 @@ def test_parsed_path_file_local(scheme): ) def test_parsed_path_not_local(uri): """Check for paths that are not local""" - assert False == ParsedPath.from_uri(uri).is_local + assert not ParsedPath.from_uri(uri).is_local def test_parse_path_zip(): diff --git a/tests/test_rio_blocks.py b/tests/test_rio_blocks.py index e6cb172a..565486c8 100644 --- a/tests/test_rio_blocks.py +++ b/tests/test_rio_blocks.py @@ -1,6 +1,6 @@ """Unittests for $ rio blocks""" - +from itertools import zip_longest import json import re @@ -8,7 +8,6 @@ import numpy as np import rasterio from rasterio.warp import transform_bounds -from rasterio.compat import zip_longest from rasterio.rio.main import main_group