-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #65 from MODFLOW-USGS/v0.1.5
Release 0.1.5
- Loading branch information
Showing
14 changed files
with
249 additions
and
113 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
[flake8] | ||
exclude = | ||
.git | ||
__pycache__ | ||
build | ||
dist | ||
examples | ||
autotest | ||
ignore = | ||
# https://flake8.pycqa.org/en/latest/user/error-codes.html | ||
F401, | ||
# https://pycodestyle.readthedocs.io/en/latest/intro.html#error-codes | ||
# Indentation | ||
E121, E122, E126, E127, E128, | ||
# Whitespace | ||
E203, E221, E222, E226, E231, E241, | ||
# Import | ||
E402, | ||
# Line length | ||
E501, E502, | ||
# Statement | ||
E722, E741, | ||
# Whitespace warning | ||
W291, W292, W293, | ||
# Blank line warning | ||
W391, | ||
# Line break warning | ||
W503, W504 | ||
statistics = True |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
global-exclude .DS_Store *.pyc *.pyo *.pyd *.swp *.bak *~ .* *.sh *.yml *.md *.toml | ||
exclude autotest/* | ||
include pyproject.toml | ||
include version.txt | ||
include version.txt | ||
include README.md |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,34 @@ | ||
# `MFZipFile` | ||
|
||
Python's [`ZipFile`](https://docs.python.org/3/library/zipfile.html) doesn't [preserve file permissions at extraction time](https://bugs.python.org/issue15795). The `MFZipFile` subclass modifies `ZipFile.extract()` to do so, as per the recommendation [here](https://stackoverflow.com/questions/39296101/python-zipfile-removes-execute-permissions-from-binaries), and maintains identical behavior otherwise. | ||
Python's [`ZipFile`](https://docs.python.org/3/library/zipfile.html) doesn't [preserve file permissions at extraction time](https://bugs.python.org/issue15795). The `MFZipFile` subclass: | ||
|
||
- modifies `ZipFile.extract()` to preserve permissions per the [recommendation here](https://stackoverflow.com/questions/39296101/python-zipfile-removes-execute-permissions-from-binaries) | ||
- adds a static `ZipFile.compressall()` method to create a zip file from files and directories | ||
- maintains an otherwise identical API | ||
|
||
## `compressall` | ||
|
||
The `compressall` method is a static method that creates a zip file from lists of files and/or directories. It is a convenience method that wraps `ZipFile.write()`, `ZipFile.close()`, etc. | ||
|
||
```python | ||
from zipfile import ZipFile | ||
from modflow_devtools.zip import MFZipFile | ||
|
||
def test_compressall(function_tmpdir): | ||
zip_file = function_tmpdir / "output.zip" | ||
|
||
input_dir = function_tmpdir / "input" | ||
input_dir.mkdir() | ||
|
||
with open(input_dir / "data.txt", "w") as f: | ||
f.write("hello world") | ||
|
||
MFZipFile.compressall(str(zip_file), dir_pths=str(input_dir)) | ||
assert zip_file.exists() | ||
|
||
output_dir = function_tmpdir / "output" | ||
output_dir.mkdir() | ||
|
||
ZipFile(zip_file).extractall(path=str(output_dir)) | ||
assert (output_dir / "data.txt").is_file() | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
__author__ = "Joseph D. Hughes" | ||
__date__ = "Jan 18, 2023" | ||
__version__ = "0.1.4" | ||
__date__ = "Jan 19, 2023" | ||
__version__ = "0.1.5" | ||
__maintainer__ = "Joseph D. Hughes" | ||
__email__ = "[email protected]" | ||
__status__ = "Production" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import os | ||
import shutil | ||
import sys | ||
import zipfile | ||
from os import environ | ||
from pathlib import Path | ||
from pprint import pprint | ||
from zipfile import ZipFile | ||
|
||
import pytest | ||
from modflow_devtools.markers import excludes_platform | ||
from modflow_devtools.misc import get_suffixes, set_dir | ||
from modflow_devtools.zip import MFZipFile | ||
|
||
_bin_path = Path(environ.get("BIN_PATH")).expanduser().absolute() | ||
_ext, _ = get_suffixes(sys.platform) | ||
|
||
|
||
@pytest.fixture(scope="module") | ||
def empty_archive(module_tmpdir) -> Path: | ||
# https://stackoverflow.com/a/25195628/6514033 | ||
data = b"PK\x05\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" | ||
path = module_tmpdir / "empty.zip" | ||
|
||
with open(path, "wb") as zip: | ||
zip.write(data) | ||
|
||
return path | ||
|
||
|
||
@pytest.fixture(scope="module") | ||
def nonempty_archive(module_tmpdir) -> Path: | ||
if not _bin_path.is_dir(): | ||
pytest.skip(f"BIN_PATH ({_bin_path}) is not a directory") | ||
|
||
zip_path = module_tmpdir / "nonempty.zip" | ||
txt_path = module_tmpdir / "hw.txt" | ||
exe_path = _bin_path / f"mf6{_ext}" | ||
|
||
# create a zip file with a text file and an executable | ||
shutil.copy(exe_path, module_tmpdir) | ||
with open(txt_path, "w") as f: | ||
f.write("hello world") | ||
|
||
with set_dir(module_tmpdir): | ||
zip = MFZipFile(zip_path.name, "w") | ||
zip.write(txt_path.name, compress_type=zipfile.ZIP_DEFLATED) | ||
zip.write(exe_path.name, compress_type=zipfile.ZIP_DEFLATED) | ||
zip.close() | ||
|
||
return zip_path | ||
|
||
|
||
def test_compressall(function_tmpdir): | ||
zip_file = function_tmpdir / "output.zip" | ||
input_dir = function_tmpdir / "input" | ||
input_dir.mkdir() | ||
|
||
with open(input_dir / "data.txt", "w") as f: | ||
f.write("hello world") | ||
|
||
MFZipFile.compressall(str(zip_file), dir_pths=str(input_dir)) | ||
|
||
pprint(list(function_tmpdir.iterdir())) | ||
assert zip_file.exists() | ||
|
||
output_dir = function_tmpdir / "output" | ||
output_dir.mkdir() | ||
|
||
ZipFile(zip_file).extractall(path=str(output_dir)) | ||
|
||
pprint(list(output_dir.iterdir())) | ||
assert (output_dir / "data.txt").is_file() | ||
|
||
|
||
def test_extractall_empty(empty_archive, function_tmpdir): | ||
zf = MFZipFile(empty_archive, "r") | ||
zf.extractall(str(function_tmpdir)) | ||
|
||
assert not any(function_tmpdir.iterdir()) | ||
|
||
|
||
@pytest.mark.parametrize("mf", [True, False]) | ||
@excludes_platform("Windows") | ||
def test_preserves_execute_permission(function_tmpdir, nonempty_archive, mf): | ||
zip = MFZipFile(nonempty_archive) if mf else ZipFile(nonempty_archive) | ||
zip.extractall(path=str(function_tmpdir)) | ||
|
||
exe_path = function_tmpdir / f"mf6{_ext}" | ||
|
||
assert exe_path.is_file() | ||
assert os.access(exe_path, os.X_OK) == mf |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,80 @@ | ||
[build-system] | ||
# Minimum requirements for the build system to execute | ||
requires = [ | ||
"setuptools>=45", | ||
"wheel", | ||
"setuptools>=61", | ||
] | ||
build-backend = "setuptools.build_meta" | ||
|
||
[project] | ||
name = "modflow-devtools" | ||
description = "Python tools for MODFLOW development" | ||
authors = [ | ||
{name = "Joseph D. Hughes", email = "[email protected]"}, | ||
] | ||
maintainers = [ | ||
{name = "Joseph D. Hughes", email = "[email protected]"}, | ||
] | ||
keywords = [ | ||
"MODFLOW", | ||
"development", | ||
"utilities", | ||
"groundwater", | ||
"hydrogeology" | ||
] | ||
readme = "README.md" | ||
license = {text = "CC0"} | ||
classifiers = [ | ||
"Development Status :: 3 - Alpha", | ||
"Intended Audience :: Science/Research", | ||
"License :: CC0 1.0 Universal (CC0 1.0) Public Domain Dedication", | ||
"Programming Language :: Python :: 3 :: Only", | ||
"Programming Language :: Python :: 3", | ||
"Programming Language :: Python :: 3.8", | ||
"Programming Language :: Python :: 3.9", | ||
"Programming Language :: Python :: 3.10", | ||
"Programming Language :: Python :: 3.11", | ||
"Topic :: Scientific/Engineering :: Hydrology" | ||
] | ||
requires-python = ">=3.8" | ||
dependencies = [ | ||
"numpy", | ||
"pytest" | ||
] | ||
dynamic = ["version"] | ||
|
||
[project.optional-dependencies] | ||
lint = [ | ||
"black", | ||
"cffconvert", | ||
"flake8", | ||
"isort", | ||
"pylint" | ||
] | ||
test = [ | ||
"modflow-devtools[lint]", | ||
"coverage", | ||
"flaky", | ||
"filelock", | ||
"meson!=0.63.0", | ||
"ninja", | ||
"pytest-cases", | ||
"pytest-cov", | ||
"pytest-dotenv", | ||
"pytest-xdist", | ||
"PyYaml" | ||
] | ||
docs = [ | ||
"sphinx", | ||
"sphinx-rtd-theme", | ||
"myst-parser" | ||
] | ||
|
||
[project.urls] | ||
"Documentation" = "https://modflow-devtools.readthedocs.io/en/latest/" | ||
"Bug Tracker" = "https://github.com/MODFLOW-USGS/modflow-devtools/issues" | ||
"Source Code" = "https://github.com/MODFLOW-USGS/modflow-devtools" | ||
|
||
|
||
[tool.black] | ||
line-length = 79 | ||
target_version = ["py37"] | ||
|
@@ -19,6 +88,13 @@ profile = "black" | |
src_paths = ["src/modflow_devtools"] | ||
line_length = 79 | ||
|
||
[tool.setuptools] | ||
include-package-data = true | ||
zip-safe = false | ||
|
||
[tool.setuptools.dynamic] | ||
version = {file = "version.txt"} | ||
|
||
[tool.setuptools_scm] | ||
fallback_version = "999" | ||
|
||
|
Oops, something went wrong.