diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index b3065e1..7233479 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -12,4 +12,3 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 - uses: pre-commit/action@v2.0.0 - \ No newline at end of file diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 611280d..5445db7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,6 +5,7 @@ repos: hooks: - id: check-ast - id: end-of-file-fixer + exclude: github_deploy_key.enc - id: check-docstring-first - id: check-added-large-files - id: requirements-txt-fixer @@ -14,18 +15,18 @@ repos: - id: debug-statements - repo: https://gitlab.com/pycqa/flake8 - rev: 3.8.4 + rev: 3.9.0 hooks: - id: flake8 exclude: docs/source/conf.py - args: [--max-line-length=105] + args: [--max-line-length=105, "--ignore=E203,W503"] -- repo: https://github.com/pre-commit/mirrors-isort - rev: v5.7.0 +- repo: https://github.com/pycqa/isort + rev: 5.7.0 hooks: - - id: isort - additional_dependencies: [toml] - args: [--project=oceans, --multi-line=3, --lines-after-imports=2, --lines-between-types=1, --trailing-comma, --force-grid-wrap=0, --use-parentheses, --line-width=88] + - id: isort + additional_dependencies: [toml] + args: ["--profile", "black", "--filter-files"] - repo: https://github.com/psf/black rev: 20.8b1 @@ -43,4 +44,4 @@ repos: - repo: https://github.com/asottile/add-trailing-comma rev: v2.1.0 hooks: - - id: add-trailing-comma \ No newline at end of file + - id: add-trailing-comma diff --git a/.travis.yml b/.travis.yml index 62d526d..d4b1506 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,8 +20,6 @@ matrix: env: PY=3.8 - name: "doctests" env: PY=3 - - name: "coding_standards" - env: PY=3 - name: "tarball" env: PY=3 - name: "docs" @@ -60,10 +58,6 @@ script: - if [[ $TRAVIS_JOB_NAME == doctests ]]; then pytest -vv oceans --doctest-modules ; fi - - - if [[ $TRAVIS_JOB_NAME == 'coding_standards' ]]; then - pytest --flake8 -m flake8 ; - fi - | if [[ $TRAVIS_JOB_NAME == 'docs' ]]; then diff --git a/CHANGES.txt b/CHANGES.txt index 67720d2..9a7f6b2 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -80,4 +80,4 @@ Version 0.1.0 Version 0.0.1 -* Initial release. \ No newline at end of file +* Initial release. diff --git a/docs/Makefile b/docs/Makefile index 69fe55e..ba501f6 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -16,4 +16,4 @@ help: # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/source/RPSstuff.rst b/docs/source/RPSstuff.rst index b0caccc..049f34e 100644 --- a/docs/source/RPSstuff.rst +++ b/docs/source/RPSstuff.rst @@ -4,4 +4,4 @@ .. automodule:: oceans.RPSstuff :members: :undoc-members: - :show-inheritance: \ No newline at end of file + :show-inheritance: diff --git a/docs/source/colormaps.rst b/docs/source/colormaps.rst index 2cd332b..5d08ece 100644 --- a/docs/source/colormaps.rst +++ b/docs/source/colormaps.rst @@ -4,4 +4,4 @@ .. automodule:: oceans.colormaps :members: :undoc-members: - :show-inheritance: \ No newline at end of file + :show-inheritance: diff --git a/docs/source/conf.py b/docs/source/conf.py index cd0fa06..28720b6 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # # Configuration file for the Sphinx documentation builder. # @@ -25,7 +24,6 @@ from oceans._version import get_versions - version = release = get_versions()["version"] del get_versions @@ -116,7 +114,7 @@ "relations.html", # needs 'show_related': True theme option to display "searchbox.html", "donate.html", - ] + ], } diff --git a/docs/source/datasets.rst b/docs/source/datasets.rst index 728a07a..5b2c520 100644 --- a/docs/source/datasets.rst +++ b/docs/source/datasets.rst @@ -4,4 +4,4 @@ .. automodule:: oceans.datasets :members: :undoc-members: - :show-inheritance: \ No newline at end of file + :show-inheritance: diff --git a/docs/source/filters.rst b/docs/source/filters.rst index 52dc4c8..706a848 100644 --- a/docs/source/filters.rst +++ b/docs/source/filters.rst @@ -4,4 +4,4 @@ .. automodule:: oceans.filters :members: :undoc-members: - :show-inheritance: \ No newline at end of file + :show-inheritance: diff --git a/docs/source/ocfis.rst b/docs/source/ocfis.rst index 4d3853a..bdb9eb4 100644 --- a/docs/source/ocfis.rst +++ b/docs/source/ocfis.rst @@ -4,4 +4,4 @@ .. automodule:: oceans.ocfis :members: :undoc-members: - :show-inheritance: \ No newline at end of file + :show-inheritance: diff --git a/docs/source/plotting.rst b/docs/source/plotting.rst index 343a103..965e2be 100644 --- a/docs/source/plotting.rst +++ b/docs/source/plotting.rst @@ -4,4 +4,4 @@ .. automodule:: oceans.plotting :members: :undoc-members: - :show-inheritance: \ No newline at end of file + :show-inheritance: diff --git a/oceans/RPSstuff.py b/oceans/RPSstuff.py index 6ed82cf..34c60f7 100644 --- a/oceans/RPSstuff.py +++ b/oceans/RPSstuff.py @@ -3,7 +3,6 @@ import numpy as np import numpy.ma as ma - earth_radius = 6371.0e3 diff --git a/oceans/__init__.py b/oceans/__init__.py index 4dac47b..0377b35 100644 --- a/oceans/__init__.py +++ b/oceans/__init__.py @@ -1,5 +1,4 @@ from ._version import get_versions # noqa - __version__ = get_versions()["version"] del get_versions diff --git a/oceans/_version.py b/oceans/_version.py index 23c50b5..c8e487c 100644 --- a/oceans/_version.py +++ b/oceans/_version.py @@ -68,9 +68,7 @@ def decorate(f): return decorate -def run_command( - commands, args, cwd=None, verbose=False, hide_stderr=False, env=None -): +def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, env=None): """Call the given command(s).""" assert isinstance(commands, list) p = None @@ -86,7 +84,7 @@ def run_command( stderr=(subprocess.PIPE if hide_stderr else None), ) break - except EnvironmentError: + except OSError: e = sys.exc_info()[1] if e.errno == errno.ENOENT: continue @@ -96,7 +94,7 @@ def run_command( return None, None else: if verbose: - print("unable to find command, tried %s" % (commands,)) + print(f"unable to find command, tried {commands}") return None, None stdout = p.communicate()[0].strip() if sys.version_info[0] >= 3: @@ -135,7 +133,7 @@ def versions_from_parentdir(parentdir_prefix, root, verbose): if verbose: print( "Tried directories %s but none started with prefix %s" - % (str(rootdirs), parentdir_prefix) + % (str(rootdirs), parentdir_prefix), ) raise NotThisMethod("rootdir doesn't start with parentdir_prefix") @@ -149,7 +147,7 @@ def git_get_keywords(versionfile_abs): # _version.py. keywords = {} try: - f = open(versionfile_abs, "r") + f = open(versionfile_abs) for line in f.readlines(): if line.strip().startswith("git_refnames ="): mo = re.search(r'=\s*"(.*)"', line) @@ -164,7 +162,7 @@ def git_get_keywords(versionfile_abs): if mo: keywords["date"] = mo.group(1) f.close() - except EnvironmentError: + except OSError: pass return keywords @@ -243,9 +241,7 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): if sys.platform == "win32": GITS = ["git.cmd", "git.exe"] - out, rc = run_command( - GITS, ["rev-parse", "--git-dir"], cwd=root, hide_stderr=True - ) + out, rc = run_command(GITS, ["rev-parse", "--git-dir"], cwd=root, hide_stderr=True) if rc != 0: if verbose: print("Directory %s not under git control" % root) @@ -297,9 +293,7 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): mo = re.search(r"^(.+)-(\d+)-g([0-9a-f]+)$", git_describe) if not mo: # unparseable. Maybe git-describe is misbehaving? - pieces["error"] = ( - "unable to parse git-describe output: '%s'" % describe_out - ) + pieces["error"] = "unable to parse git-describe output: '%s'" % describe_out return pieces # tag @@ -308,7 +302,7 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): if verbose: fmt = "tag '%s' doesn't start with prefix '%s'" print(fmt % (full_tag, tag_prefix)) - pieces["error"] = "tag '%s' doesn't start with prefix '%s'" % ( + pieces["error"] = "tag '{}' doesn't start with prefix '{}'".format( full_tag, tag_prefix, ) @@ -324,9 +318,7 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): else: # HEX: no tags pieces["closest-tag"] = None - count_out, rc = run_command( - GITS, ["rev-list", "HEAD", "--count"], cwd=root - ) + count_out, rc = run_command(GITS, ["rev-list", "HEAD", "--count"], cwd=root) pieces["distance"] = int(count_out) # total number of commits # commit date: see ISO-8601 comment in git_versions_from_keywords() @@ -523,9 +515,7 @@ def get_versions(): verbose = cfg.verbose try: - return git_versions_from_keywords( - get_keywords(), cfg.tag_prefix, verbose - ) + return git_versions_from_keywords(get_keywords(), cfg.tag_prefix, verbose) except NotThisMethod: pass diff --git a/oceans/colormaps.py b/oceans/colormaps.py index 73be55d..7267501 100644 --- a/oceans/colormaps.py +++ b/oceans/colormaps.py @@ -1,14 +1,11 @@ import os - from colorsys import hsv_to_rgb from glob import glob import matplotlib.pyplot as plt import numpy as np - from matplotlib import colors - cmap_path = os.path.join(os.path.dirname(__file__), "cmap_data") @@ -26,7 +23,7 @@ def get_color(color): for hue in range(color): hue = 1.0 * hue / color col = [int(x) for x in hsv_to_rgb(hue, 1.0, 230)] - yield "#{0:02x}{1:02x}{2:02x}".format(*col) + yield "#{:02x}{:02x}{:02x}".format(*col) def cmat2cmpl(rgb, reverse=False): @@ -160,7 +157,7 @@ def demo(): data = np.outer(np.arange(0, 1, 0.01), np.ones(10)) fig = plt.figure(figsize=(10, 5)) fig.subplots_adjust(top=0.8, bottom=0.05, left=0.01, right=0.99) - cmaps = sorted((m for m in cm.keys() if not m.endswith("_r"))) + cmaps = sorted(m for m in cm.keys() if not m.endswith("_r")) length = len(cmaps) for k, cmap in enumerate(cmaps): plt.subplot(1, length + 1, k + 1) diff --git a/oceans/datasets.py b/oceans/datasets.py index 834bc84..1a8c84f 100644 --- a/oceans/datasets.py +++ b/oceans/datasets.py @@ -1,7 +1,6 @@ import warnings import numpy as np - from netCDF4 import Dataset from oceans.ocfis import get_profile, wrap_lon180 @@ -21,7 +20,7 @@ def _woa_variable(variable): v = _VAR.get(variable) if not v: raise ValueError( - f'Unrecognizable variable. Expected one of {list(_VAR.keys())}, got "{variable}".' + f'Unrecognizable variable. Expected one of {list(_VAR.keys())}, got "{variable}".', ) return v @@ -35,7 +34,7 @@ def _woa_url(variable, time_period, resolution): pref = "woa09" warnings.warn( f'The variable "{variable}" is only available at 1 degree resolution, ' - f'annual time period, and "{pref}".' + f'annual time period, and "{pref}".', ) return f"{base}/" f"{pref}/" f"{variable}_annual_1deg.nc" else: @@ -50,7 +49,7 @@ def _woa_url(variable, time_period, resolution): grid = grids.get(resolution) if not grid: raise ValueError( - f'Unrecognizable resolution. Expected one of {list(grids.keys())}, got "{resolution}".' + f'Unrecognizable resolution. Expected one of {list(grids.keys())}, got "{resolution}".', ) res = grid[0] gg = grid[1] @@ -90,7 +89,7 @@ def _woa_url(variable, time_period, resolution): if not tt: raise ValueError( f"Unrecognizable time_period. " - f'Expected one of {list(time_periods.keys())}, got "{time_period}".' + f'Expected one of {list(time_periods.keys())}, got "{time_period}".', ) url = ( @@ -102,9 +101,7 @@ def _woa_url(variable, time_period, resolution): return url -def woa_profile( - lon, lat, variable="temperature", time_period="annual", resolution="1" -): +def woa_profile(lon, lat, variable="temperature", time_period="annual", resolution="1"): """ Return an iris.cube instance from a World Ocean Atlas variable at a given lon, lat point. @@ -143,9 +140,7 @@ def woa_profile( """ import iris - url = _woa_url( - variable=variable, time_period=time_period, resolution=resolution - ) + url = _woa_url(variable=variable, time_period=time_period, resolution=resolution) with warnings.catch_warnings(): warnings.simplefilter("ignore") @@ -222,9 +217,7 @@ def woa_subset( url = _woa_url(variable, time_period, resolution) cubes = iris.load_raw(url) cubes = [ - cube.intersection( - longitude=(bbox[0], bbox[1]), latitude=(bbox[2], bbox[3]) - ) + cube.intersection(longitude=(bbox[0], bbox[1]), latitude=(bbox[2], bbox[3])) for cube in cubes ] diff --git a/oceans/filters.py b/oceans/filters.py index 19209bc..5e59156 100644 --- a/oceans/filters.py +++ b/oceans/filters.py @@ -434,7 +434,7 @@ def medfilt1(x, L=3): return None if L > N: - msg = "Input filter window length must be shorter than series: L = {0:d}, len(x) = {1:d}".format # noqa + msg = "Input filter window length must be shorter than series: L = {:d}, len(x) = {:d}".format # noqa raise ValueError(msg(L, N)) return None @@ -540,7 +540,7 @@ def md_trenberth(x): 0.09030, 0.05856, 0.02700, - ] + ], ) sz = len(x) @@ -655,7 +655,7 @@ def pl33tn(x, dt=1.0, T=33.0, mode="valid"): -0.00211, -0.00114, -0.00027, - ] + ], ) _dt = np.linspace(-33, 33, 67) diff --git a/oceans/ocfis.py b/oceans/ocfis.py index 329073e..5d1631f 100644 --- a/oceans/ocfis.py +++ b/oceans/ocfis.py @@ -190,7 +190,7 @@ def mld(SA, CT, p, criterion="pdvar"): sig_diff = Sig0 + 0.125 idx_mld = sigma <= sig_diff else: - raise NameError("Unknown criteria {}".format(criterion)) + raise NameError(f"Unknown criteria {criterion}") MLD = ma.masked_all_like(p) MLD[idx_mld] = p[idx_mld] @@ -421,7 +421,7 @@ def complex_demodulation(series, f, fc, axis=-1): # phase = np.arctan2(np.imag(cc), np.real(cc)) filtered_series = amplitude * np.exp( - -2 * np.pi * 1j * (1 / T) * series.time_in_seconds + -2 * np.pi * 1j * (1 / T) * series.time_in_seconds, ) new_series = filtered_series.real, series.time # Return cc, amplitude, phase, dfs, filtered_series @@ -535,9 +535,7 @@ def bin_dates(self, freq, tz=None): """ from pandas import date_range - new_index = date_range( - start=self.index[0], end=self.index[-1], freq=freq, tz=tz - ) + new_index = date_range(start=self.index[0], end=self.index[-1], freq=freq, tz=tz) new_series = self.groupby(new_index.asof).mean() # Averages at the center. secs = new_index.freq.delta.total_seconds() @@ -581,7 +579,7 @@ def despike(self, n=3, recursive=False): result = self.values.copy() outliers = np.abs(self.values - np.nanmean(self.values)) >= n * np.nanstd( - self.values + self.values, ) removed = np.count_nonzero(outliers) @@ -711,7 +709,7 @@ def get_profile(x, y, f, xi, yi, mode="nearest", order=3): xi.max() > x.max(), yi.min() < y.min(), yi.max() > y.max(), - ] + ], ) if conditions.any(): diff --git a/oceans/plotting.py b/oceans/plotting.py index 1e28c31..7fe6825 100644 --- a/oceans/plotting.py +++ b/oceans/plotting.py @@ -2,7 +2,6 @@ import matplotlib.pyplot as plt import numpy as np import numpy.ma as ma - from matplotlib.artist import Artist from matplotlib.dates import date2num from matplotlib.lines import Line2D @@ -56,7 +55,7 @@ def stick_plot(time, u, v, **kw): raise AssertionError( "Stickplot angles must be `uv` so that" "if *U*==*V* the angle of the arrow on" - "the plot is 45 degrees CCW from the *x*-axis." + "the plot is 45 degrees CCW from the *x*-axis.", ) if isinstance(time, DatetimeIndex): @@ -76,7 +75,7 @@ def stick_plot(time, u, v, **kw): headwidth=headwidth, headlength=headlength, headaxislength=headaxislength, - **kw + **kw, ) ax.axes.get_yaxis().set_visible(False) @@ -131,7 +130,9 @@ def level_colormap(levels, cmap=None): cdict = {"red": tuple(R), "green": tuple(G), "blue": tuple(B)} return matplotlib.colors.LinearSegmentedColormap( - "%s_levels" % cmap.name, cdict, 256 + "%s_levels" % cmap.name, + cdict, + 256, ) @@ -198,7 +199,7 @@ def plot_spectrum(data, fs): plt.show() -class EditPoints(object): +class EditPoints: """ Edit points on a graph with the mouse. Handles only one set of points. @@ -252,9 +253,7 @@ def __init__(self, fig, ax, points, verbose=False): canvas.mpl_connect("draw_event", self.draw_callback) canvas.mpl_connect("button_press_event", self.button_press_callback) canvas.mpl_connect("key_press_event", self.key_press_callback) - canvas.mpl_connect( - "button_release_event", self.button_release_callback - ) + canvas.mpl_connect("button_release_event", self.button_release_callback) canvas.mpl_connect("motion_notify_event", self.motion_notify_callback) self.canvas = canvas @@ -297,9 +296,7 @@ def get_ind_under_point(self, event): ind = None if self.verbose: - print( - "\nClicked at ({}, {})".format(event.xdata, event.ydata) - ) # noqa + print(f"\nClicked at ({event.xdata}, {event.ydata})") # noqa return ind def button_press_callback(self, event): @@ -320,9 +317,7 @@ def button_press_callback(self, event): self.pick_pos = (x[self._ind], y[self._ind]) if self.verbose: - print( - "\nGot point: ({}), ind: {}".format(self.pick_pos, self._ind) - ) # noqa + print(f"\nGot point: ({self.pick_pos}), ind: {self._ind}") # noqa def button_release_callback(self, event): """ @@ -351,7 +346,7 @@ def key_press_callback(self, event): self._ind = None if self.verbose: - print("\nToggle {:d}".format(self.showpoint)) # noqa + print(f"\nToggle {self.showpoint:d}") # noqa return get_pointsxy(self.points) elif event.key == "d": x, y = get_pointsxy(self.points) @@ -359,9 +354,7 @@ def key_press_callback(self, event): if ind is not None: if self.verbose: print( - "\nDeleted ({}, {}) ind: {}".format( - x[ind], y[ind], ind - ) + "\nDeleted ({}, {}) ind: {}".format(x[ind], y[ind], ind), ) # noqa x = np.delete(x, ind) y = np.delete(y, ind) @@ -378,7 +371,7 @@ def key_press_callback(self, event): self.points.set_ydata(np.r_[self.points.get_ydata(), ey]) self.line.set_data(self.points.get_data()) if self.verbose: - print("\nInserting: ({}, {})".format(ex, ey)) # noqa + print(f"\nInserting: ({ex}, {ey})") # noqa break self.canvas.draw() @@ -402,8 +395,8 @@ def motion_notify_callback(self, event): x[self._ind] = self.pick_pos[0] + dx y[self._ind] = self.pick_pos[1] + dy if self.verbose: - print("\nevent.xdata {}".format(event.xdata)) # noqa - print("\nevent.ydata {}".format(event.ydata)) # noqa + print(f"\nevent.xdata {event.xdata}") # noqa + print(f"\nevent.ydata {event.ydata}") # noqa self.points.set_xdata(x) self.points.set_ydata(y) self.line.set_data(list(zip(self.points.get_data()))) diff --git a/oceans/sandbox/lines.py b/oceans/sandbox/lines.py index 2b0b596..cb84e5d 100644 --- a/oceans/sandbox/lines.py +++ b/oceans/sandbox/lines.py @@ -2,7 +2,6 @@ import numpy as np - _default_path = os.path.join(os.path.dirname(__file__), "data") @@ -123,7 +122,7 @@ def LineCurvature2D(Vertices, Lines=None): np.arange(2, Vertices.shape[0] + 1), ] else: - raise ValueError("Cannot recognized {!r}.".format(Lines)) + raise ValueError(f"Cannot recognized {Lines!r}.") # Get left and right neighbor of each points. Na = np.zeros(Vertices.shape[0], dtype=np.int) @@ -176,39 +175,27 @@ def LineCurvature2D(Vertices, Lines=None): a = np.zeros_like(x) b = np.zeros_like(a) a[:, 0] = ( - invM[:, 0, 0] * x[:, 0] - + invM[:, 1, 0] * x[:, 1] - + invM[:, 2, 0] * x[:, 2] + invM[:, 0, 0] * x[:, 0] + invM[:, 1, 0] * x[:, 1] + invM[:, 2, 0] * x[:, 2] ) a[:, 1] = ( - invM[:, 0, 1] * x[:, 0] - + invM[:, 1, 1] * x[:, 1] - + invM[:, 2, 1] * x[:, 2] + invM[:, 0, 1] * x[:, 0] + invM[:, 1, 1] * x[:, 1] + invM[:, 2, 1] * x[:, 2] ) a[:, 2] = ( - invM[:, 0, 2] * x[:, 0] - + invM[:, 1, 2] * x[:, 1] - + invM[:, 2, 2] * x[:, 2] + invM[:, 0, 2] * x[:, 0] + invM[:, 1, 2] * x[:, 1] + invM[:, 2, 2] * x[:, 2] ) b[:, 0] = ( - invM[:, 0, 0] * y[:, 0] - + invM[:, 1, 0] * y[:, 1] - + invM[:, 2, 0] * y[:, 2] + invM[:, 0, 0] * y[:, 0] + invM[:, 1, 0] * y[:, 1] + invM[:, 2, 0] * y[:, 2] ) b[:, 1] = ( - invM[:, 0, 1] * y[:, 0] - + invM[:, 1, 1] * y[:, 1] - + invM[:, 2, 1] * y[:, 2] + invM[:, 0, 1] * y[:, 0] + invM[:, 1, 1] * y[:, 1] + invM[:, 2, 1] * y[:, 2] ) b[:, 2] = ( - invM[:, 0, 2] * y[:, 0] - + invM[:, 1, 2] * y[:, 1] - + invM[:, 2, 2] * y[:, 2] + invM[:, 0, 2] * y[:, 0] + invM[:, 1, 2] * y[:, 1] + invM[:, 2, 2] * y[:, 2] ) # Calculate the curvature from the fitted polygon. diff --git a/oceans/sw_extras/__init__.py b/oceans/sw_extras/__init__.py index 31ed2a3..a2764c0 100644 --- a/oceans/sw_extras/__init__.py +++ b/oceans/sw_extras/__init__.py @@ -23,7 +23,6 @@ ) from oceans.sw_extras.waves import Waves - __all__ = [ N, cor_beta, diff --git a/oceans/sw_extras/gamma_GP_from_SP_pt.py b/oceans/sw_extras/gamma_GP_from_SP_pt.py index ce970c3..8d59edd 100644 --- a/oceans/sw_extras/gamma_GP_from_SP_pt.py +++ b/oceans/sw_extras/gamma_GP_from_SP_pt.py @@ -59,7 +59,7 @@ def gamma_G_north_atlantic(SP, pt): [2.0, 4.0, -8.16468531808416], [1.0, 5.0, 5.58313794099231], [0.0, 6.0, -0.156149127884621], - ] + ], ) gamma_NAtl = Fit[0, 2] * np.ones_like(SP) @@ -106,7 +106,7 @@ def gamma_G_south_atlantic(SP, pt): [2.0, 4.0, 28.7899447141466], [1.0, 5.0, -8.73093192235768], [0.0, 6.0, 1.25587481738340], - ] + ], ) gamma_SAtl = Fit[0, 2] * np.ones_like(SP) @@ -154,7 +154,7 @@ def gamma_G_pacific(SP, pt): [2.0, 4.0, 25.1352444814321], [1.0, 5.0, -5.58077135773059], [0.0, 6.0, 0.0505878919989799], - ] + ], ) gamma_Pac = Fit[0, 2] * np.ones_like(SP) @@ -202,7 +202,7 @@ def gamma_G_indian(SP, pt): [2.0, 4.0, 13.2992863063285], [1.0, 5.0, -6.93690276392252], [0.0, 6.0, 1.42081034484842], - ] + ], ) gamma_Ind = Fit[0, 2] * np.ones_like(SP) @@ -250,7 +250,7 @@ def gamma_G_southern_ocean(SP, pt, p): [2.0, 4.0, 1.95823443401631], [1.0, 5.0, -10.8585153444218], [0.0, 6.0, 1.44257249650877], - ] + ], ) gamma_SOce_N = Fit_N[0, 2] * np.ones_like(SP) @@ -277,7 +277,7 @@ def gamma_G_southern_ocean(SP, pt, p): [2.0, 2.0, 3.68258441217306], [1.0, 3.0, 264.211505260770], [0.0, 4.0, 20.1983279379898], - ] + ], ) p_ref, pt_ref, c_pt = 700.0, 2.5, 0.65 @@ -399,7 +399,7 @@ def gamma_GP_from_SP_pt(SP, pt, p, lon, lat): 102.57, 98.79, 100, - ] + ], ) io_lat = np.array( @@ -422,7 +422,7 @@ def gamma_GP_from_SP_pt(SP, pt, p, lon, lat): 2.9, 10, 20, - ] + ], ) # Definition of the Pacific part. @@ -454,7 +454,7 @@ def gamma_GP_from_SP_pt(SP, pt, p, lon, lat): 102.57, 98.79, 100.0, - ] + ], ) po_lat = np.array( @@ -485,43 +485,37 @@ def gamma_GP_from_SP_pt(SP, pt, p, lon, lat): 2.9, 10, 20, - ] + ], ) # Definition of the polygon filters. io_polygon = Path(list(zip(io_lon, io_lat))) po_polygon = Path(list(zip(po_lon, po_lat))) i_inter_indian_pacific = in_polygon(lon, lat, io_polygon) * in_polygon( - lon, lat, po_polygon + lon, + lat, + po_polygon, ) - i_indian = np.logical_xor( - in_polygon(lon, lat, io_polygon), i_inter_indian_pacific - ) + i_indian = np.logical_xor(in_polygon(lon, lat, io_polygon), i_inter_indian_pacific) i_pacific = in_polygon(lon, lat, po_polygon) i_atlantic = (1 - i_pacific) * (1 - i_indian) # Definition of the Atlantic weighting function. charac1_sa = lat < -10.0 charac2_sa = np.logical_and(lat <= 10.0, lat >= -10.0) - w_sa = charac1_sa + charac2_sa * ( - 0.5 + 0.5 * np.cos(np.pi * (lat + 10.0) / 20.0) - ) + w_sa = charac1_sa + charac2_sa * (0.5 + 0.5 * np.cos(np.pi * (lat + 10.0) / 20.0)) # Definition of the Southern Ocean weighting function. charac1_so = lat < -40.0 charac2_so = np.logical_and(lat <= -20.0, lat >= -40.0) - w_so = charac1_so + charac2_so * ( - 0.5 + 0.5 * np.cos(np.pi * (lat + 40.0) / 20.0) - ) + w_so = charac1_so + charac2_so * (0.5 + 0.5 * np.cos(np.pi * (lat + 40.0) / 20.0)) # Combination of the North and South Atlantic. gamma_Atl = (1.0 - w_sa) * gamma_NAtl + w_sa * gamma_SAtl # Combination of the middle parts. - gamma_middle = ( - i_pacific * gamma_Pac + i_atlantic * gamma_Atl + i_indian * gamma_Ind - ) + gamma_middle = i_pacific * gamma_Pac + i_atlantic * gamma_Atl + i_indian * gamma_Ind # Combination of the Northern and Southern parts. gamma_GP = w_so * gamma_SOce + (1.0 - w_so) * gamma_middle diff --git a/oceans/sw_extras/sw_extras.py b/oceans/sw_extras/sw_extras.py index 9573369..4d6978f 100644 --- a/oceans/sw_extras/sw_extras.py +++ b/oceans/sw_extras/sw_extras.py @@ -2,7 +2,6 @@ import numpy as np import seawater as sw - from seawater.constants import OMEGA, earth_radius @@ -674,13 +673,9 @@ def soundspeed(S, T, D, equation="mackenzie"): P = D / GR # This is from VSOUND.f. C000 = 1402.392 - DCT = ( - 0.501109398873e1 - (0.550946843172e-1 - 0.221535969240e-3 * T) * T - ) * T + DCT = (0.501109398873e1 - (0.550946843172e-1 - 0.221535969240e-3 * T) * T) * T DCS = (0.132952290781e1 + 0.128955756844e-3 * S) * S - DCP = ( - 0.156059257041e0 + (0.244998688441e-4 - 0.883392332513e-8 * P) * P - ) * P + DCP = (0.156059257041e0 + (0.244998688441e-4 - 0.883392332513e-8 * P) * P) * P DCSTP = ( ( -0.127562783426e-1 * T * S @@ -715,9 +710,7 @@ def soundspeed(S, T, D, equation="mackenzie"): A1 = ( ((-2.0122e-10 * T + 1.0507e-8) * T - 6.4885e-8) * T - 1.2580e-5 ) * T + 9.4742e-5 - A0 = ( - ((-3.21e-8 * T + 2.006e-6) * T + 7.164e-5) * T - 1.262e-2 - ) * T + 1.389 + A0 = (((-3.21e-8 * T + 2.006e-6) * T + 7.164e-5) * T - 1.262e-2) * T + 1.389 A = ((A3 * P + A2) * P + A1) * P + A0 # S**0 TERM. C3 = (-2.3643e-12 * T + 3.8504e-10) * T - 9.7729e-9 @@ -728,17 +721,14 @@ def soundspeed(S, T, D, equation="mackenzie"): ((-6.1185e-10 * T + 1.3621e-7) * T - 8.1788e-6) * T + 6.8982e-4 ) * T + 0.153563 C0 = ( - (((3.1464e-9 * T - 1.47800e-6) * T + 3.3420e-4) * T - 5.80852e-2) - * T + (((3.1464e-9 * T - 1.47800e-6) * T + 3.3420e-4) * T - 5.80852e-2) * T + 5.03711 ) * T + 1402.388 C = ((C3 * P + C2) * P + C1) * P + C0 # SOUND SPEED RETURN. ssp = C + (A + B * SR + D * S) * S else: - raise TypeError( - "Unrecognizable equation specified: {}".format(equation) - ) + raise TypeError(f"Unrecognizable equation specified: {equation}") return ssp @@ -917,9 +907,7 @@ def zmld_boyer(s, t, p): return mldepthdens_mldindex, mldepthptemp_mldindex else: # starti = min(find((pres-10).^2==min((pres-10).^2))); - starti = np.min( - np.where(((p - 10.0) ** 2 == np.min((p - 10.0) ** 2)))[0] - ) + starti = np.min(np.where((p - 10.0) ** 2 == np.min((p - 10.0) ** 2))[0]) starti = 0 pres = p[starti:m] sal = s[starti:m] diff --git a/oceans/sw_extras/waves.py b/oceans/sw_extras/waves.py index 3eb3c57..653d3f7 100644 --- a/oceans/sw_extras/waves.py +++ b/oceans/sw_extras/waves.py @@ -2,7 +2,7 @@ import numpy as np -class Waves(object): +class Waves: r""" Solves the wave dispersion relationship via Newton-Raphson. @@ -148,11 +148,10 @@ def __init__(self, h, T=None, L=None, thetao=None, Ho=None, lat=None): self.Kr = np.NaN if thetao is not None: self.theta = np.rad2deg( - np.asin(self.C / self.Co * np.sin(np.deg2rad(self.thetao))) + np.asin(self.C / self.Co * np.sin(np.deg2rad(self.thetao))), ) self.Kr = np.sqrt( - np.cos(np.deg2rad(self.thetao)) - / np.cos(np.deg2rad(self.theta)) + np.cos(np.deg2rad(self.thetao)) / np.cos(np.deg2rad(self.theta)), ) if Ho is None: diff --git a/oceans/synop.py b/oceans/synop.py index 17e92dd..dfbfaed 100644 --- a/oceans/synop.py +++ b/oceans/synop.py @@ -71,9 +71,7 @@ def scaloa(xc, yc, x, y, t=None, corrlen=None, err=None, zc=None): t = np.reshape(t, (n, 1)) tp = np.dot(C, np.linalg.solve(A, t)) if 0: # NOTE: `scaloa2.m` - mD = np.sum(np.linalg.solve(A, t)) / np.sum( - np.sum(np.linalg.inv(A)) - ) + mD = np.sum(np.linalg.solve(A, t)) / np.sum(np.sum(np.linalg.inv(A))) t = t - mD tp = C * (np.linalg.solve(A, t)) tp = tp + mD * np.ones(tp.shape) diff --git a/oceans/utilities.py b/oceans/utilities.py index 977419e..e03b138 100644 --- a/oceans/utilities.py +++ b/oceans/utilities.py @@ -7,7 +7,7 @@ def basename(fname): return os.path.splitext(os.path.basename(fname)) -class match_args_return(object): +class match_args_return: """ Function decorator to homogenize input arguments and to make the output match the original input with respect to scalar versus array, and masked diff --git a/setup.cfg b/setup.cfg index 92ea954..744e698 100644 --- a/setup.cfg +++ b/setup.cfg @@ -14,28 +14,11 @@ parentdir_prefix = [tool:pytest] markers = web: marks tests require connection (deselect with '-m "not web"') -flake8-max-line-length = 105 -flake8-ignore = - E203 W503 - docs/* ALL - versioneer.py ALL - oceans/_version.py ALL [metadata] description-file = README.rst license_file = LICENSE.txt -[isort] -atomic=true -force_grid_wrap=0 -include_trailing_comma=true -lines_after_imports=2 -lines_between_types=1 -multi_line_output=3 -not_skip=__init__.py -use_parentheses=true -known_first_party=attr - [check-manifest] ignore = .travis.yml diff --git a/setup.py b/setup.py index fc563a6..c8bce78 100644 --- a/setup.py +++ b/setup.py @@ -4,17 +4,16 @@ import versioneer - rootpath = os.path.abspath(os.path.dirname(__file__)) def read(*parts): - return open(os.path.join(rootpath, *parts), "r").read() + return open(os.path.join(rootpath, *parts)).read() email = "ocefpaf@gmail.com" maintainer = "Filipe Fernandes" -authors = [u"André Palóczy", "Arnaldo Russo", "Filipe Fernandes"] +authors = ["André Palóczy", "Arnaldo Russo", "Filipe Fernandes"] # Dependencies. hard = ["gsw", "matplotlib", "numpy", "seawater"] @@ -55,6 +54,6 @@ def read(*parts): keywords=["oceanography", "data analysis"], extras_require=soft, install_requires=hard, - python_requires='>=3.6', + python_requires=">=3.6", tests_require=["pytest"], ) diff --git a/tests/test_sw_extras.py b/tests/test_sw_extras.py index 0117ae8..7264e30 100644 --- a/tests/test_sw_extras.py +++ b/tests/test_sw_extras.py @@ -87,7 +87,7 @@ def test_kdpar(): 1.1003, 1.0465, 0.9971, - ] + ], ) press = np.array( @@ -167,7 +167,7 @@ def test_kdpar(): 77.0, 78.0, 79.0, - ] + ], ) kd, par_surface = swe.kdpar(press, PAR, boundary=25) diff --git a/versioneer.py b/versioneer.py index bf6048c..ffc686b 100644 --- a/versioneer.py +++ b/versioneer.py @@ -275,7 +275,6 @@ """ -from __future__ import print_function import errno import json @@ -284,7 +283,6 @@ import subprocess import sys - try: import configparser except ImportError: @@ -331,7 +329,7 @@ def get_root(): if me_dir != vsr_dir: print( "Warning: build in %s is using versioneer.py from %s" - % (os.path.dirname(me), versioneer_py) + % (os.path.dirname(me), versioneer_py), ) except NameError: pass @@ -346,7 +344,7 @@ def get_config_from_root(root): # the top of versioneer.py for instructions on writing your setup.cfg . setup_cfg = os.path.join(root, "setup.cfg") parser = configparser.SafeConfigParser() - with open(setup_cfg, "r") as f: + with open(setup_cfg) as f: parser.readfp(f) VCS = parser.get("versioneer", "VCS") # mandatory @@ -390,9 +388,7 @@ def decorate(f): return decorate -def run_command( - commands, args, cwd=None, verbose=False, hide_stderr=False, env=None -): +def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, env=None): """Call the given command(s).""" assert isinstance(commands, list) p = None @@ -408,7 +404,7 @@ def run_command( stderr=(subprocess.PIPE if hide_stderr else None), ) break - except EnvironmentError: + except OSError: e = sys.exc_info()[1] if e.errno == errno.ENOENT: continue @@ -418,7 +414,7 @@ def run_command( return None, None else: if verbose: - print("unable to find command, tried %s" % (commands,)) + print(f"unable to find command, tried {commands}") return None, None stdout = p.communicate()[0].strip() if sys.version_info[0] >= 3: @@ -433,7 +429,7 @@ def run_command( LONG_VERSION_PY[ "git" -] = ''' +] = r''' # This file helps to compute a version number in source trees obtained from # git-archive tarball (such as those provided by githubs download-from-tag # feature). Distribution tarballs (built by setup.py sdist) and build @@ -965,7 +961,7 @@ def git_get_keywords(versionfile_abs): # _version.py. keywords = {} try: - f = open(versionfile_abs, "r") + f = open(versionfile_abs) for line in f.readlines(): if line.strip().startswith("git_refnames ="): mo = re.search(r'=\s*"(.*)"', line) @@ -980,7 +976,7 @@ def git_get_keywords(versionfile_abs): if mo: keywords["date"] = mo.group(1) f.close() - except EnvironmentError: + except OSError: pass return keywords @@ -1004,11 +1000,11 @@ def git_versions_from_keywords(keywords, tag_prefix, verbose): if verbose: print("keywords are unexpanded, not using") raise NotThisMethod("unexpanded keywords, not a git-archive tarball") - refs = set([r.strip() for r in refnames.strip("()").split(",")]) + refs = {r.strip() for r in refnames.strip("()").split(",")} # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of # just "foo-1.0". If we see a "tag: " prefix, prefer those. TAG = "tag: " - tags = set([r[len(TAG) :] for r in refs if r.startswith(TAG)]) + tags = {r[len(TAG) :] for r in refs if r.startswith(TAG)} if not tags: # Either we're using git < 1.8.3, or there really are no tags. We use # a heuristic: assume all version tags have a digit. The old git %d @@ -1017,7 +1013,7 @@ def git_versions_from_keywords(keywords, tag_prefix, verbose): # between branches and tags. By ignoring refnames without digits, we # filter out many common branch names like "release" and # "stabilization", as well as "HEAD" and "master". - tags = set([r for r in refs if re.search(r"\d", r)]) + tags = {r for r in refs if re.search(r"\d", r)} if verbose: print("discarding '%s', no digits" % ",".join(refs - tags)) if verbose: @@ -1059,9 +1055,7 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): if sys.platform == "win32": GITS = ["git.cmd", "git.exe"] - out, rc = run_command( - GITS, ["rev-parse", "--git-dir"], cwd=root, hide_stderr=True - ) + out, rc = run_command(GITS, ["rev-parse", "--git-dir"], cwd=root, hide_stderr=True) if rc != 0: if verbose: print("Directory %s not under git control" % root) @@ -1113,9 +1107,7 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): mo = re.search(r"^(.+)-(\d+)-g([0-9a-f]+)$", git_describe) if not mo: # unparseable. Maybe git-describe is misbehaving? - pieces["error"] = ( - "unable to parse git-describe output: '%s'" % describe_out - ) + pieces["error"] = "unable to parse git-describe output: '%s'" % describe_out return pieces # tag @@ -1124,7 +1116,7 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): if verbose: fmt = "tag '%s' doesn't start with prefix '%s'" print(fmt % (full_tag, tag_prefix)) - pieces["error"] = "tag '%s' doesn't start with prefix '%s'" % ( + pieces["error"] = "tag '{}' doesn't start with prefix '{}'".format( full_tag, tag_prefix, ) @@ -1140,9 +1132,7 @@ def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): else: # HEX: no tags pieces["closest-tag"] = None - count_out, rc = run_command( - GITS, ["rev-list", "HEAD", "--count"], cwd=root - ) + count_out, rc = run_command(GITS, ["rev-list", "HEAD", "--count"], cwd=root) pieces["distance"] = int(count_out) # total number of commits # commit date: see ISO-8601 comment in git_versions_from_keywords() @@ -1176,13 +1166,13 @@ def do_vcs_install(manifest_in, versionfile_source, ipy): files.append(versioneer_file) present = False try: - f = open(".gitattributes", "r") + f = open(".gitattributes") for line in f.readlines(): if line.strip().startswith(versionfile_source): if "export-subst" in line.strip().split()[1:]: present = True f.close() - except EnvironmentError: + except OSError: pass if not present: f = open(".gitattributes", "a+") @@ -1218,7 +1208,7 @@ def versions_from_parentdir(parentdir_prefix, root, verbose): if verbose: print( "Tried directories %s but none started with prefix %s" - % (str(rootdirs), parentdir_prefix) + % (str(rootdirs), parentdir_prefix), ) raise NotThisMethod("rootdir doesn't start with parentdir_prefix") @@ -1246,7 +1236,7 @@ def versions_from_file(filename): try: with open(filename) as f: contents = f.read() - except EnvironmentError: + except OSError: raise NotThisMethod("unable to read _version.py") mo = re.search( r"version_json = '''\n(.*)''' # END VERSION_JSON", @@ -1267,13 +1257,11 @@ def versions_from_file(filename): def write_to_version_file(filename, versions): """Write the given version number to the given _version.py file.""" os.unlink(filename) - contents = json.dumps( - versions, sort_keys=True, indent=1, separators=(",", ": ") - ) + contents = json.dumps(versions, sort_keys=True, indent=1, separators=(",", ": ")) with open(filename, "w") as f: f.write(SHORT_VERSION_PY % contents) - print("set %s to '%s'" % (filename, versions["version"])) + print("set {} to '{}'".format(filename, versions["version"])) def plus_or_dot(pieces): @@ -1498,7 +1486,7 @@ def get_versions(verbose=False): try: ver = versions_from_file(versionfile_abs) if verbose: - print("got version from file %s %s" % (versionfile_abs, ver)) + print(f"got version from file {versionfile_abs} {ver}") return ver except NotThisMethod: pass @@ -1614,9 +1602,7 @@ def run(self): # now locate _version.py in the new build/ directory and replace # it with an updated value if cfg.versionfile_build: - target_versionfile = os.path.join( - self.build_lib, cfg.versionfile_build - ) + target_versionfile = os.path.join(self.build_lib, cfg.versionfile_build) print("UPDATING %s" % target_versionfile) write_to_version_file(target_versionfile, versions) @@ -1653,7 +1639,7 @@ def run(self): "TAG_PREFIX": cfg.tag_prefix, "PARENTDIR_PREFIX": cfg.parentdir_prefix, "VERSIONFILE_SOURCE": cfg.versionfile_source, - } + }, ) cmds["build_exe"] = cmd_build_exe @@ -1686,7 +1672,7 @@ def run(self): "TAG_PREFIX": cfg.tag_prefix, "PARENTDIR_PREFIX": cfg.parentdir_prefix, "VERSIONFILE_SOURCE": cfg.versionfile_source, - } + }, ) cmds["py2exe"] = cmd_py2exe @@ -1716,7 +1702,8 @@ def make_release_tree(self, base_dir, files): target_versionfile = os.path.join(base_dir, cfg.versionfile_source) print("UPDATING %s" % target_versionfile) write_to_version_file( - target_versionfile, self._versioneer_generated_versions + target_versionfile, + self._versioneer_generated_versions, ) cmds["sdist"] = cmd_sdist @@ -1773,15 +1760,9 @@ def do_setup(): root = get_root() try: cfg = get_config_from_root(root) - except ( - EnvironmentError, - configparser.NoSectionError, - configparser.NoOptionError, - ) as e: + except (OSError, configparser.NoSectionError, configparser.NoOptionError) as e: if isinstance(e, (EnvironmentError, configparser.NoSectionError)): - print( - "Adding sample versioneer config to setup.cfg", file=sys.stderr - ) + print("Adding sample versioneer config to setup.cfg", file=sys.stderr) with open(os.path.join(root, "setup.cfg"), "a") as f: f.write(SAMPLE_CONFIG) print(CONFIG_ERROR, file=sys.stderr) @@ -1798,15 +1779,15 @@ def do_setup(): "TAG_PREFIX": cfg.tag_prefix, "PARENTDIR_PREFIX": cfg.parentdir_prefix, "VERSIONFILE_SOURCE": cfg.versionfile_source, - } + }, ) ipy = os.path.join(os.path.dirname(cfg.versionfile_source), "__init__.py") if os.path.exists(ipy): try: - with open(ipy, "r") as f: + with open(ipy) as f: old = f.read() - except EnvironmentError: + except OSError: old = "" if INIT_PY_SNIPPET not in old: print(" appending to %s" % ipy) @@ -1825,12 +1806,12 @@ def do_setup(): manifest_in = os.path.join(root, "MANIFEST.in") simple_includes = set() try: - with open(manifest_in, "r") as f: + with open(manifest_in) as f: for line in f: if line.startswith("include "): for include in line.split()[1:]: simple_includes.add(include) - except EnvironmentError: + except OSError: pass # That doesn't cover everything MANIFEST.in can do # (http://docs.python.org/2/distutils/sourcedist.html#commands), so @@ -1845,7 +1826,7 @@ def do_setup(): if cfg.versionfile_source not in simple_includes: print( " appending versionfile_source ('%s') to MANIFEST.in" - % cfg.versionfile_source + % cfg.versionfile_source, ) with open(manifest_in, "a") as f: f.write("include %s\n" % cfg.versionfile_source) @@ -1864,7 +1845,7 @@ def scan_setup_py(): found = set() setters = False errors = 0 - with open("setup.py", "r") as f: + with open("setup.py") as f: for line in f.readlines(): if "import versioneer" in line: found.add("import")