Skip to content

Commit

Permalink
Drop Python 2 compat code and bump support to >=3.7 (holoviz#1033)
Browse files Browse the repository at this point in the history
* require python >= 3.7
* add classifiers for pypi
* remove references to Python 2 in the docs
* remove python 2 compat
* remove py27 env from tox
* cleanup and drop 3.6
* Run the CI on py3.9
* add badge of supported versions in the README
  • Loading branch information
maximlt authored Apr 25, 2022
1 parent e7189cc commit 1fd7b6b
Show file tree
Hide file tree
Showing 22 changed files with 62 additions and 140 deletions.
1 change: 0 additions & 1 deletion .coveragerc
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
[run]
omit =
*/test_*.py
datashader/compatibility.py
source =
datashader
11 changes: 3 additions & 8 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ on:
pull_request:
branches:
- '*'
workflow_dispatch:

jobs:
test_suite:
Expand Down Expand Up @@ -54,12 +55,6 @@ jobs:
eval "$(conda shell.bash hook)"
conda activate test-environment
doit develop_install -o tests -o examples --conda-mode=mamba
- name: Python 3.6 installs
if: matrix.python-version == '3.6'
run: |
eval "$(conda shell.bash hook)"
conda activate test-environment
mamba install "panel=0.12" dataclasses
- name: patch for fiona on windows / 3.7
if: matrix.os == 'windows-latest' && matrix.python-version == '3.7'
run: |
Expand All @@ -76,11 +71,11 @@ jobs:
eval "$(conda shell.bash hook)"
conda activate test-environment
doit test_lint
- name: doit test_unit_deploy
- name: doit test_unit
run: |
eval "$(conda shell.bash hook)"
conda activate test-environment
doit test_unit_deploy
doit test_unit
- name: doit test_unit_nojit
run: |
eval "$(conda shell.bash hook)"
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
| Coverage | [![codecov](https://codecov.io/gh/holoviz/datashader/branch/master/graph/badge.svg)](https://codecov.io/gh/holoviz/datashader) |
| Latest dev release | [![Github tag](https://img.shields.io/github/tag/holoviz/datashader.svg?label=tag&colorB=11ccbb)](https://github.com/holoviz/datashader/tags) [![dev-site](https://img.shields.io/website-up-down-green-red/https/pyviz-dev.github.io/datashader.svg?label=dev%20website)](https://pyviz-dev.github.io/datashader/) |
| Latest release | [![Github release](https://img.shields.io/github/release/holoviz/datashader.svg?label=tag&colorB=11ccbb)](https://github.com/holoviz/datashader/releases) [![PyPI version](https://img.shields.io/pypi/v/datashader.svg?colorB=cc77dd)](https://pypi.python.org/pypi/datashader) [![datashader version](https://img.shields.io/conda/v/pyviz/datashader.svg?colorB=4488ff&style=flat)](https://anaconda.org/pyviz/datashader) [![conda-forge version](https://img.shields.io/conda/v/conda-forge/datashader.svg?label=conda%7Cconda-forge&colorB=4488ff)](https://anaconda.org/conda-forge/datashader) [![defaults version](https://img.shields.io/conda/v/anaconda/datashader.svg?label=conda%7Cdefaults&style=flat&colorB=4488ff)](https://anaconda.org/anaconda/datashader) |
| Python | [![Python support](https://img.shields.io/pypi/pyversions/datashader.svg)](https://pypi.org/project/datashader/)
| Docs | [![gh-pages](https://img.shields.io/github/last-commit/holoviz/datashader/gh-pages.svg)](https://github.com/holoviz/datashader/tree/gh-pages) [![site](https://img.shields.io/website-up-down-green-red/http/datashader.org.svg)](http://datashader.org) |
| Support | [![Discourse](https://img.shields.io/discourse/status?server=https%3A%2F%2Fdiscourse.holoviz.org)](https://discourse.holoviz.org/) |

Expand Down Expand Up @@ -48,7 +49,7 @@ to work with much larger datasets than it would otherwise.

## Installation

Datashader supports Python 2.7, 3.6 and 3.7 on Linux, Windows, or
Datashader supports Python 3.7, 3.8, 3.9 and 3.10 on Linux, Windows, or
Mac and can be installed with conda:

conda install datashader
Expand Down
8 changes: 1 addition & 7 deletions datashader/colors.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
from __future__ import absolute_import, division, print_function

# Declare Python2/3 unicode-safe string type
try:
basestring
except NameError:
basestring = str


# Lookup of web color names to their hex codes.
color_lookup = {'aliceblue': '#F0F8FF', 'antiquewhite': '#FAEBD7',
Expand Down Expand Up @@ -117,7 +111,7 @@ def rgb(x):
>>> rgb((255, 255, 255))
(255, 255, 255)
"""
if isinstance(x, basestring):
if isinstance(x, str):
if x.startswith('#'):
return hex_to_rgb(x)
elif x in color_lookup:
Expand Down
21 changes: 0 additions & 21 deletions datashader/compatibility.py

This file was deleted.

3 changes: 1 addition & 2 deletions datashader/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import numpy as np
import xarray as xr

from .compatibility import _exec
from .reductions import by, category_codes, summary
from .utils import ngjit

Expand Down Expand Up @@ -148,7 +147,7 @@ def make_append(bases, cols, calls, glyph, categorical):
code = ('def append({0}, x, y, {1}):\n'
' {2}'
).format(subscript, ', '.join(signature), '\n '.join(body))
_exec(code, namespace)
exec(code, namespace)
return ngjit(namespace['append'])


Expand Down
31 changes: 15 additions & 16 deletions datashader/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import pandas as pd
import dask.dataframe as dd
import dask.array as da
from six import string_types
from xarray import DataArray, Dataset
from collections import OrderedDict

Expand Down Expand Up @@ -376,8 +375,8 @@ def line(self, source, x=None, y=None, agg=None, axis=0, geometry=None,
x, y = _broadcast_column_specifications(x, y)

if axis == 0:
if (isinstance(x, (Number, string_types)) and
isinstance(y, (Number, string_types))):
if (isinstance(x, (Number, str)) and
isinstance(y, (Number, str))):
glyph = LineAxis0(x, y)
elif (isinstance(x, (list, tuple)) and
isinstance(y, (list, tuple))):
Expand All @@ -400,8 +399,8 @@ def line(self, source, x=None, y=None, agg=None, axis=0, geometry=None,
elif (isinstance(x, (list, tuple)) and
isinstance(y, np.ndarray)):
glyph = LinesAxis1YConstant(tuple(x), y)
elif (isinstance(x, (Number, string_types)) and
isinstance(y, (Number, string_types))):
elif (isinstance(x, (Number, str)) and
isinstance(y, (Number, str))):
glyph = LinesAxis1Ragged(x, y)
else:
raise ValueError("""
Expand Down Expand Up @@ -591,8 +590,8 @@ def area(self, source, x, y, agg=None, axis=0, y_stack=None):

if axis == 0:
if y_stack is None:
if (isinstance(x, (Number, string_types)) and
isinstance(y, (Number, string_types))):
if (isinstance(x, (Number, str)) and
isinstance(y, (Number, str))):
glyph = AreaToZeroAxis0(x, y)
elif (isinstance(x, (list, tuple)) and
isinstance(y, (list, tuple))):
Expand All @@ -607,9 +606,9 @@ def area(self, source, x, y, agg=None, axis=0, y_stack=None):
x=repr(x), y=repr(y)))
else:
# y_stack is not None
if (isinstance(x, (Number, string_types)) and
isinstance(y, (Number, string_types)) and
isinstance(y_stack, (Number, string_types))):
if (isinstance(x, (Number, str)) and
isinstance(y, (Number, str)) and
isinstance(y_stack, (Number, str))):

glyph = AreaToLineAxis0(x, y, y_stack)
elif (isinstance(x, (list, tuple)) and
Expand Down Expand Up @@ -640,8 +639,8 @@ def area(self, source, x, y, agg=None, axis=0, y_stack=None):
elif (isinstance(x, (list, tuple)) and
isinstance(y, np.ndarray)):
glyph = AreaToZeroAxis1YConstant(tuple(x), y)
elif (isinstance(x, (Number, string_types)) and
isinstance(y, (Number, string_types))):
elif (isinstance(x, (Number, str)) and
isinstance(y, (Number, str))):
glyph = AreaToZeroAxis1Ragged(x, y)
else:
raise ValueError("""
Expand All @@ -666,9 +665,9 @@ def area(self, source, x, y, agg=None, axis=0, y_stack=None):
isinstance(y, np.ndarray) and
isinstance(y_stack, np.ndarray)):
glyph = AreaToLineAxis1YConstant(tuple(x), y, y_stack)
elif (isinstance(x, (Number, string_types)) and
isinstance(y, (Number, string_types)) and
isinstance(y_stack, (Number, string_types))):
elif (isinstance(x, (Number, str)) and
isinstance(y, (Number, str)) and
isinstance(y_stack, (Number, str))):
glyph = AreaToLineAxis1Ragged(x, y, y_stack)
else:
raise ValueError("""
Expand Down Expand Up @@ -1310,7 +1309,7 @@ def _broadcast_column_specifications(*args):
else:
n = lengths.pop()
return tuple(
(arg,) * n if isinstance(arg, (Number, string_types)) else arg
(arg,) * n if isinstance(arg, (Number, str)) else arg
for arg in args
)

Expand Down
2 changes: 1 addition & 1 deletion datashader/data_libraries/dask.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from dask.base import tokenize, compute

from datashader.core import bypixel
from datashader.compatibility import apply
from datashader.utils import apply
from datashader.compiler import compile_components
from datashader.glyphs import Glyph, LineAxis0
from datashader.utils import Dispatcher
Expand Down
2 changes: 1 addition & 1 deletion datashader/data_libraries/dask_xarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from datashader.glyphs.quadmesh import (
QuadMeshRaster, QuadMeshRectilinear, QuadMeshCurvilinear, build_scale_translate
)
from datashader.compatibility import apply
from datashader.utils import apply
import dask
import numpy as np
import xarray as xr
Expand Down
26 changes: 2 additions & 24 deletions datashader/macros.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,18 +86,6 @@ def visit_Starred(self, node):
return node


class ExpandVarargTransformerCallArg(ExpandVarargTransformer):
# Python 2
def visit_Call(self, node):
if getattr(node, 'starargs', None) and node.starargs.id == self.starred_name:
node.starargs = None
node.args.extend([ast.Name(id=name, ctx=ast.Load())
for name in self.expand_names])
return node
else:
return node


def function_to_ast(fn):
"""
Get the AST representation of a function
Expand Down Expand Up @@ -161,12 +149,7 @@ def function_ast_to_function(fn_ast, stacklevel=1):


def _build_arg(name):
try:
# Python 3
return ast.arg(arg=name)
except AttributeError:
# Python 2
return ast.Name(id=name, ctx=ast.Param())
return ast.arg(arg=name)


def expand_function_ast_varargs(fn_ast, expand_number):
Expand Down Expand Up @@ -238,12 +221,7 @@ def my_fn1(a, b, _0, _1, _2):
expand_names = before_name_visitor.get_new_names(expand_number)

# Replace use of *args in function body
if hasattr(ast, "Starred"):
# Python 3
expand_transformer = ExpandVarargTransformerStarred
else:
# Python 2
expand_transformer = ExpandVarargTransformerCallArg
expand_transformer = ExpandVarargTransformerStarred

new_fn_ast = expand_transformer(
vararg_name, expand_names
Expand Down
5 changes: 0 additions & 5 deletions datashader/resampling.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@

from __future__ import absolute_import, division, print_function

import sys
import datetime as dt
from itertools import groupby
from math import floor, ceil

Expand Down Expand Up @@ -967,9 +965,6 @@ def infer_interval_breaks(coord, axis=0):
pass
else:
coord = np.asarray(coord)
if sys.version_info.major == 2 and len(coord) and isinstance(coord[0], (dt.datetime, dt.date)):
# np.diff does not work on datetimes in python 2
coord = coord.astype('datetime64')
if len(coord) == 0:
return np.array([], dtype=coord.dtype)
deltas = 0.5 * np.diff(coord, axis=axis)
Expand Down
8 changes: 0 additions & 8 deletions datashader/tests/benchmarks/test_draw_line.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
from __future__ import division

import sys

import pytest

import numpy as np
Expand All @@ -11,9 +9,6 @@
_build_map_onto_pixel_for_line, AntialiasCombination
from datashader.utils import ngjit

py2_skip = pytest.mark.skipif(sys.version_info.major < 3, reason="py2 not supported")


mapper = ngjit(lambda x: x)
map_onto_pixel = _build_map_onto_pixel_for_line(mapper, mapper)
sx, tx, sy, ty = 1, 0, 1, 0
Expand All @@ -31,7 +26,6 @@ def append(i, x, y, agg):
False, AntialiasCombination.NONE)


@py2_skip
@pytest.mark.benchmark(group="draw_line")
def test_draw_line_left_border(benchmark, draw_line):
n = 10**4
Expand All @@ -43,7 +37,6 @@ def test_draw_line_left_border(benchmark, draw_line):
x0, x1, y0, y1, 0.0, 0.0, agg)


@py2_skip
@pytest.mark.benchmark(group="draw_line")
def test_draw_line_diagonal(benchmark, draw_line):
n = 10**4
Expand All @@ -55,7 +48,6 @@ def test_draw_line_diagonal(benchmark, draw_line):
x0, x1, y0, y1, 0.0, 0.0, agg)


@py2_skip
@pytest.mark.benchmark(group="draw_line")
def test_draw_line_offset(benchmark, draw_line):
n = 10**4
Expand Down
6 changes: 0 additions & 6 deletions datashader/tests/benchmarks/test_extend_line.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import sys

import numpy as np
import pytest

Expand All @@ -10,8 +8,6 @@
)
from datashader.utils import ngjit

py2_skip = pytest.mark.skipif(sys.version_info.major < 3, reason="py2 not supported")


@pytest.fixture
def extend_line():
Expand All @@ -27,7 +23,6 @@ def append(i, x, y, agg):
return _build_extend_line_axis0(draw_line, expand_aggs_and_cols, AntialiasCombination.NONE)[0]


@py2_skip
@pytest.mark.parametrize('high', [0, 10**5])
@pytest.mark.parametrize('low', [0, -10**5])
@pytest.mark.benchmark(group="extend_line")
Expand All @@ -45,7 +40,6 @@ def test_extend_line_uniform(benchmark, extend_line, low, high):
)


@py2_skip
@pytest.mark.benchmark(group="extend_line")
def test_extend_line_normal(benchmark, extend_line):
n = 10**6
Expand Down
3 changes: 0 additions & 3 deletions datashader/tests/test_antialias.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,16 +121,13 @@


import os
import sys

import xarray as xr
import datashader as ds
import pandas as pd
import numpy as np
import pytest

if sys.version_info.major < 3:
pytestmark = pytest.mark.skip('Anti-aliasing not supported in python 2.')

cm = pytest.importorskip('matplotlib.cm')
binary = cm.binary
Expand Down
Loading

0 comments on commit 1fd7b6b

Please sign in to comment.