diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index dfe5405f..128b72a8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,7 +1,7 @@ fail_fast: true repos: - repo: https://github.com/psf/black - rev: stable + rev: 21.4b0 hooks: - id: black language_version: python3 diff --git a/README.rst b/README.rst index 4454bb88..0f446804 100644 --- a/README.rst +++ b/README.rst @@ -101,6 +101,16 @@ can automatically run the tests for various python versions like this: tox +Update pyptest version +++++++++++++++++++++++ + +If you update or change the pytest version, the following files need to be changed: + +- ``dev-requirements.txt`` +- ``tox.ini`` +- ``test/test_utils.py`` +- ``setup.py`` + Contributing ------------ If you find a bug, have a feature request or want to discuss something general you are welcome to open an @@ -229,8 +239,8 @@ This project is released under the terms of the `MIT license `_. diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 9071b8d2..a37be28b 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -3,85 +3,97 @@ jobs: - job: test strategy: matrix: - Windows py35: - IMAGE_NAME: 'vs2017-win2016' - PYTHON_VERSION: '3.5' - TOX_CMD: 'py35' - Windows py36: - IMAGE_NAME: 'vs2017-win2016' - PYTHON_VERSION: '3.6' - TOX_CMD: 'py36' Windows py37: - IMAGE_NAME: 'vs2017-win2016' + IMAGE_NAME: 'windows-latest' PYTHON_VERSION: '3.7' TOX_CMD: 'py37' - OSX py35: - IMAGE_NAME: 'macos-10.15' - PYTHON_VERSION: '3.5' - TOX_CMD: 'py35' - OSX py36: - IMAGE_NAME: 'macos-10.15' - PYTHON_VERSION: '3.6' - TOX_CMD: 'py36' + Windows py38: + IMAGE_NAME: 'windows-latest' + PYTHON_VERSION: '3.8' + TOX_CMD: 'py38' + Windows py39: + IMAGE_NAME: 'windows-latest' + PYTHON_VERSION: '3.9' + TOX_CMD: 'py39' OSX py37: - IMAGE_NAME: 'macos-10.15' + IMAGE_NAME: 'macOS-latest' PYTHON_VERSION: '3.7' TOX_CMD: 'py37' - Linux py35: - IMAGE_NAME: 'ubuntu-16.04' - PYTHON_VERSION: '3.5' - TOX_CMD: 'py35' - Linux py36: - IMAGE_NAME: 'ubuntu-16.04' - PYTHON_VERSION: '3.6' - TOX_CMD: 'py36' + OSX py38: + IMAGE_NAME: 'macOS-latest' + PYTHON_VERSION: '3.8' + TOX_CMD: 'py38' + OSX py39: + IMAGE_NAME: 'macOS-latest' + PYTHON_VERSION: '3.9' + TOX_CMD: 'py39' Linux py37: - IMAGE_NAME: 'ubuntu-16.04' + IMAGE_NAME: 'ubuntu-latest' PYTHON_VERSION: '3.7' TOX_CMD: 'py37' + Linux py38: + IMAGE_NAME: 'ubuntu-latest' + PYTHON_VERSION: '3.8' + TOX_CMD: 'py38' + Linux py39: + IMAGE_NAME: 'ubuntu-latest' + PYTHON_VERSION: '3.9' + TOX_CMD: 'py39' Linux numpy_117: - IMAGE_NAME: 'ubuntu-16.04' + IMAGE_NAME: 'ubuntu-latest' PYTHON_VERSION: '3.7' TOX_CMD: 'numpy-117' Linux numpy_118: - IMAGE_NAME: 'ubuntu-16.04' - PYTHON_VERSION: '3.7' + IMAGE_NAME: 'ubuntu-latest' + PYTHON_VERSION: '3.8' TOX_CMD: 'numpy-118' Linux numpy_119: - IMAGE_NAME: 'ubuntu-16.04' - PYTHON_VERSION: '3.7' + IMAGE_NAME: 'ubuntu-latest' + PYTHON_VERSION: '3.9' TOX_CMD: 'numpy-119' - Linux tensorflow_112: - IMAGE_NAME: 'ubuntu-16.04' - PYTHON_VERSION: '3.6' - TOX_CMD: 'tensorflow-112' - Linux tensorflow_113: - IMAGE_NAME: 'ubuntu-16.04' - PYTHON_VERSION: '3.6' - TOX_CMD: 'tensorflow-113' - Linux tensorflow-114: - IMAGE_NAME: 'ubuntu-16.04' + Linux numpy_120: + IMAGE_NAME: 'ubuntu-latest' + PYTHON_VERSION: '3.9' + TOX_CMD: 'numpy-120' + Linux tensorflow_115: + IMAGE_NAME: 'ubuntu-latest' PYTHON_VERSION: '3.7' - TOX_CMD: 'tensorflow-114' - Linux tensorflow_2: - IMAGE_NAME: 'ubuntu-16.04' + TOX_CMD: 'tensorflow-115' + Linux tensorflow_20: + IMAGE_NAME: 'ubuntu-latest' PYTHON_VERSION: '3.7' - TOX_CMD: 'tensorflow-2' - Linux setup: - IMAGE_NAME: 'ubuntu-16.04' + TOX_CMD: 'tensorflow-20' + Linux tensorflow-21: + IMAGE_NAME: 'ubuntu-latest' PYTHON_VERSION: '3.7' + TOX_CMD: 'tensorflow-21' + Linux tensorflow_22: + IMAGE_NAME: 'ubuntu-latest' + PYTHON_VERSION: '3.8' + TOX_CMD: 'tensorflow-22' + Linux tensorflow_23: + IMAGE_NAME: 'ubuntu-latest' + PYTHON_VERSION: '3.8' + TOX_CMD: 'tensorflow-23' + Linux tensorflow_24: + IMAGE_NAME: 'ubuntu-latest' + PYTHON_VERSION: '3.8' + TOX_CMD: 'tensorflow-24' + Linux setup: + IMAGE_NAME: 'ubuntu-latest' + PYTHON_VERSION: '3.9' TOX_CMD: 'setup' Linux flake8: - IMAGE_NAME: 'ubuntu-16.04' - PYTHON_VERSION: '3.7' + IMAGE_NAME: 'ubuntu-latest' + PYTHON_VERSION: '3.9' TOX_CMD: 'flake8' Linux black: - IMAGE_NAME: 'ubuntu-16.04' - PYTHON_VERSION: '3.6' + IMAGE_NAME: 'ubuntu-latest' + PYTHON_VERSION: '3.9' TOX_CMD: 'black' Linux coverage: - IMAGE_NAME: 'ubuntu-16.04' - PYTHON_VERSION: '3.7' + IMAGE_NAME: 'ubuntu-latest' + PYTHON_VERSION: '3.9' TOX_CMD: 'coverage' pool: vmImage: $(IMAGE_NAME) @@ -93,9 +105,9 @@ jobs: - bash: tox -e $TOX_CMD - job: test_pre_commit pool: - vmImage: 'ubuntu-16.04' + vmImage: 'ubuntu-latest' steps: - task: UsePythonVersion@0 inputs: - versionSpec: '3.6' + versionSpec: '3.9' - bash: bash ./tests/check_pre_commit.sh diff --git a/dev-requirements.txt b/dev-requirements.txt index ffa0b171..82ac3faa 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,34 +1,33 @@ -colorama==0.4.1 -docopt==0.6.2 -gitdb2==2.0.0 -GitPython==2.1.1 -hashfs==0.7.0 -jsonpickle==1.2 -Mako==1.0.6 -MarkupSafe==0.23 -mock==2.0.0 -mongomock==3.18.0 -munch==2.0.4 -packaging>=18.0 -pandas==0.24.2 -pbr==2.0.0 -# tests/test_utils.py depends on that pytest version is exactly 4.3.0 -pytest==4.3.0 -python-dateutil==2.6.0 -pytz==2016.10 -PyYAML>=4.2b1 -scandir==1.4 -sentinels==1.0.0 -smmap2==2.0.1 -SQLAlchemy>=1.3.0 -tinydb>=3.6 -tinydb-serialization>=2.0.0 -wrapt==1.10.8 -scikit-learn==0.20.3 -pymongo==3.9.0 -py-cpuinfo==4.0 -boto3>=1.9.0 -moto==1.3.13 -google-compute-engine>=2.8.0 -google-cloud-storage==1.20.0 -pre-commit==1.18.0 +pytest==6.2.3 # tests/test_utils.py depends on that pytest version is exactly 6.2.3 +colorama +docopt +gitdb2 +GitPython +hashfs +jsonpickle +Mako +MarkupSafe +mock +mongomock +munch +packaging +pandas +pbr +python-dateutil +pytz +PyYAML +scandir +sentinels +smmap2 +SQLAlchemy +tinydb +tinydb-serialization +wrapt +scikit-learn +pymongo +py-cpuinfo +boto3 +moto +google-compute-engine> +google-cloud-storage +pre-commit diff --git a/pyproject.toml b/pyproject.toml index b54bec17..5700fd51 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [tool.black] -target-version = ['py35'] +target-version = ['py37', 'py38', 'py39'] include = '\.pyi?$' exclude = ''' ( @@ -16,4 +16,4 @@ exclude = ''' | dist )/ ) -''' \ No newline at end of file +''' diff --git a/sacred/observers/mongo.py b/sacred/observers/mongo.py index 5d548c21..c7dca76a 100644 --- a/sacred/observers/mongo.py +++ b/sacred/observers/mongo.py @@ -86,7 +86,7 @@ def __init__( priority: int = DEFAULT_MONGO_PRIORITY, client: Optional["pymongo.MongoClient"] = None, failure_dir: Optional[PathType] = None, - **kwargs + **kwargs, ): """Initializer for MongoObserver. @@ -623,14 +623,15 @@ def __init__( overwrite: Optional[Union[int, str]] = None, priority: int = DEFAULT_MONGO_PRIORITY, client: Optional["pymongo.MongoClient"] = None, - **kwargs + **kwargs, ): """Initializer for MongoObserver. Parameters ---------- interval - The interval in seconds at which the background thread is woken up to process new events. + The interval in seconds at which the background thread is woken up to + process new events. retry_interval The interval in seconds to wait if an event failed to be processed. url diff --git a/sacred/observers/telegram_obs.py b/sacred/observers/telegram_obs.py index c216e1fc..e48b9420 100644 --- a/sacred/observers/telegram_obs.py +++ b/sacred/observers/telegram_obs.py @@ -80,7 +80,7 @@ def __init__( chat_id, silent_completion=False, priority=DEFAULT_TELEGRAM_PRIORITY, - **kwargs + **kwargs, ): self.silent_completion = silent_completion self.chat_id = chat_id diff --git a/sacred/stdout_capturing.py b/sacred/stdout_capturing.py index 2364b8a2..ae6941e2 100644 --- a/sacred/stdout_capturing.py +++ b/sacred/stdout_capturing.py @@ -117,12 +117,7 @@ def tee_output_python(): @contextmanager def tee_output_fd(): """Duplicate stdout and stderr to a file on the file descriptor level.""" - get_temp_file = ( - lambda: NamedTemporaryFile(mode="w+", newline="") - if sys.version_info >= (3,) - else NamedTemporaryFile(mode="w+") - ) - with get_temp_file() as target: + with NamedTemporaryFile(mode="w+", newline="") as target: original_stdout_fd = 1 original_stderr_fd = 2 target_fd = target.fileno() diff --git a/sacred/utils.py b/sacred/utils.py index 50960089..57abccb5 100755 --- a/sacred/utils.py +++ b/sacred/utils.py @@ -18,6 +18,7 @@ import wrapt + __all__ = [ "NO_LOGGER", "PYTHON_IDENTIFIER", @@ -315,6 +316,62 @@ def __init__( super().__init__(message, print_traceback, filter_traceback, print_usage) +class FilteredTracebackException(tb.TracebackException): + """Filter out sacred internal tracebacks from an exception traceback.""" + + def __init__( + self, + exc_type, + exc_value, + exc_traceback, + *, + limit=None, + lookup_lines=True, + capture_locals=False, + _seen=None, + ): + exc_traceback = self._filter_tb(exc_traceback) + self._walk_value(exc_value) + super().__init__( + exc_type, + exc_value, + exc_traceback, + limit=limit, + lookup_lines=lookup_lines, + capture_locals=capture_locals, + _seen=_seen, + ) + + def _walk_value(self, obj): + if obj.__cause__: + obj.__cause__.__traceback__ = self._filter_tb(obj.__cause__.__traceback__) + self._walk_value(obj.__cause__) + if obj.__context__: + obj.__context__.__traceback__ = self._filter_tb( + obj.__context__.__traceback__ + ) + self._walk_value(obj.__context__) + + def _filter_tb(self, tb): + filtered_tb = [] + while tb is not None: + if not _is_sacred_frame(tb.tb_frame): + filtered_tb.append(tb) + tb = tb.tb_next + if len(filtered_tb) >= 2: + for i in range(1, len(filtered_tb)): + filtered_tb[i - 1].tb_next = filtered_tb[i] + filtered_tb[-1].tb_next = None + return filtered_tb[0] + + def format(self, *, chain=True): + for line in super().format(chain=chain): + if line == "Traceback (most recent call last):\n": + yield "Traceback (most recent calls WITHOUT Sacred internals):\n" + else: + yield line + + def create_basic_stream_logger(): """Sets up a basic stream logger. @@ -342,7 +399,7 @@ def recursive_update(d, u): => {'a': {'b': 1, 'd': 3}, 'c': 2} """ for k, v in u.items(): - if isinstance(v, collections.Mapping): + if isinstance(v, collections.abc.Mapping): r = recursive_update(d.get(k, {}), v) d[k] = r else: @@ -521,20 +578,10 @@ def format_filtered_stacktrace(filter_traceback="default"): return "".join(header + texts[1:]).strip() elif filter_traceback in ("default", "always"): # print filtered stacktrace - if sys.version_info >= (3, 5): - tb_exception = tb.TracebackException( - exc_type, exc_value, exc_traceback, limit=None - ) - return "".join(filtered_traceback_format(tb_exception)) - else: - s = "Traceback (most recent calls WITHOUT Sacred internals):" - current_tb = exc_traceback - while current_tb is not None: - if not _is_sacred_frame(current_tb.tb_frame): - tb.print_tb(current_tb, 1) - current_tb = current_tb.tb_next - s += "\n".join(tb.format_exception_only(exc_type, exc_value)).strip() - return s + tb_exception = FilteredTracebackException( + exc_type, exc_value, exc_traceback, limit=None + ) + return "".join(tb_exception.format()) elif filter_traceback == "never": # print full stacktrace return "\n".join(tb.format_exception(exc_type, exc_value, exc_traceback)) @@ -553,29 +600,6 @@ def format_sacred_error(e, short_usage): return "\n".join(lines) -def filtered_traceback_format(tb_exception, chain=True): - if chain: - if tb_exception.__cause__ is not None: - yield from filtered_traceback_format(tb_exception.__cause__, chain=chain) - yield tb._cause_message - elif ( - tb_exception.__context__ is not None - and not tb_exception.__suppress_context__ - ): - yield from filtered_traceback_format(tb_exception.__context__, chain=chain) - yield tb._context_message - yield "Traceback (most recent calls WITHOUT Sacred internals):\n" - current_tb = tb_exception.exc_traceback - while current_tb is not None: - if not _is_sacred_frame(current_tb.tb_frame): - stack = tb.StackSummary.extract( - tb.walk_tb(current_tb), limit=1, lookup_lines=True, capture_locals=False - ) - yield from stack.format() - current_tb = current_tb.tb_next - yield from tb_exception.format_exception_only() - - # noinspection PyUnusedLocal @wrapt.decorator def optional_kwargs_decorator(wrapped, instance=None, args=None, kwargs=None): diff --git a/setup.py b/setup.py index 2ff1be0d..cc21cac4 100755 --- a/setup.py +++ b/setup.py @@ -8,9 +8,9 @@ Intended Audience :: Science/Research Natural Language :: English Operating System :: OS Independent -Programming Language :: Python :: 3.5 -Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 +Programming Language :: Python :: 3.8 +Programming Language :: Python :: 3.9 Topic :: Utilities Topic :: Scientific/Engineering Topic :: Scientific/Engineering :: Artificial Intelligence @@ -39,7 +39,7 @@ package_data={"sacred": [os.path.join("data", "*")]}, scripts=[], install_requires=Path("requirements.txt").read_text().splitlines(), - tests_require=["mock>=0.8, <3.0", "pytest==4.3.0"], + tests_require=["mock>=3.0, <5.0", "pytest==6.2.3"], classifiers=list(filter(None, classifiers.split("\n"))), description="Facilitates automated and reproducible experimental research", long_description=Path("README.rst").read_text(encoding="utf-8"), diff --git a/tests/conftest.py b/tests/conftest.py index 54ede588..b8a46afc 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -8,7 +8,7 @@ import shlex import sys import warnings -from imp import reload +from importlib import reload from sacred.settings import SETTINGS diff --git a/tests/test_commands.py b/tests/test_commands.py index 63161808..31dc5d73 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -271,7 +271,7 @@ def main(): ex.run("save_config", {"config_filename": "config.yaml"}) with open(os.path.join(dirname, "config.yaml")) as f: - saved_config = opt.yaml.load(f) + saved_config = opt.yaml.load(f, Loader=opt.yaml.FullLoader) assert config == saved_config finally: os.chdir(cwd) diff --git a/tests/test_exceptions.py b/tests/test_exceptions.py index 491b0107..5365b2d3 100644 --- a/tests/test_exceptions.py +++ b/tests/test_exceptions.py @@ -70,14 +70,14 @@ def f(): try: f() - except: + except Exception: st = format_filtered_stacktrace(filter_traceback="default") assert "captured_function" not in st assert "WITHOUT Sacred internals" in st try: f() - except: + except Exception: st = format_filtered_stacktrace(filter_traceback="always") assert "captured_function" not in st assert "WITHOUT Sacred internals" in st @@ -140,3 +140,25 @@ def test_format_sacred_error(print_traceback, filter_traceback, print_usage, exp except SacredError as e: st = format_sacred_error(e, "usage") assert re.match(expected, st, re.MULTILINE) + + +def test_chained_error(): + try: + try: + print(1 / 0) + except Exception as e: + raise SacredError("Something bad happened") from e + except SacredError as e: + st = format_sacred_error(e, "usage") + assert re.match( + r"Traceback \(most recent calls WITHOUT Sacred internals\):\n File " + + r"\"[^\"]+?test_exceptions.py\", line \d+, in test_chained_error\n " + + r"print\(1 / 0\)\nZeroDivisionError: division by zero\n\nThe above " + + r"exception was the direct cause of the following exception:\n\nTraceback " + + r"\(most recent calls WITHOUT Sacred internals\):\n File \"[^\"]+?" + + r"test_exceptions.py\", line \d+, in test_chained_error\n raise " + + r"SacredError\(\"Something bad happened\"\) from e\nsacred.utils." + + r"SacredError: Something bad happened\n", + st, + re.MULTILINE, + ) diff --git a/tests/test_observers/failing_mongo_mock.py b/tests/test_observers/failing_mongo_mock.py index 28365798..0987c597 100644 --- a/tests/test_observers/failing_mongo_mock.py +++ b/tests/test_observers/failing_mongo_mock.py @@ -1,7 +1,6 @@ import mongomock import pymongo import pymongo.errors -from mongomock.store import DatabaseStore class FailingMongoClient(mongomock.MongoClient): @@ -9,7 +8,7 @@ def __init__( self, max_calls_before_failure=2, exception_to_raise=pymongo.errors.AutoReconnect, - **kwargs + **kwargs, ): super().__init__(**kwargs) self._max_calls_before_failure = max_calls_before_failure diff --git a/tests/test_observers/test_file_storage_observer.py b/tests/test_observers/test_file_storage_observer.py index fb74c7b0..ac3c57c2 100644 --- a/tests/test_observers/test_file_storage_observer.py +++ b/tests/test_observers/test_file_storage_observer.py @@ -100,7 +100,7 @@ def test_fs_observer_started_event_creates_rundir(dir_obs, sample_run): def test_fs_observer_started_event_creates_rundir_with_filesystem_delay( dir_obs, sample_run, monkeypatch ): - """ Assumes listdir doesn't show existing file (e.g. due to caching or delay of network storage) """ + """Assumes listdir doesn't show existing file (e.g. due to caching or delay of network storage)""" basedir, obs = dir_obs sample_run["_id"] = None _id = obs.started_event(**sample_run) diff --git a/tests/test_observers/test_s3_observer.py b/tests/test_observers/test_s3_observer.py index 1028ccce..c4e2111d 100644 --- a/tests/test_observers/test_s3_observer.py +++ b/tests/test_observers/test_s3_observer.py @@ -4,6 +4,7 @@ import datetime import pytest import json +import os from sacred.observers import S3Observer @@ -18,6 +19,9 @@ BASEDIR = "some-tests" REGION = "us-west-2" +os.environ["AWS_ACCESS_KEY_ID"] = "test" +os.environ["AWS_SECRET_ACCESS_KEY"] = "test" + def s3_join(*args): return "/".join(args) @@ -26,7 +30,7 @@ def s3_join(*args): @pytest.fixture() def sample_run(): exp = {"name": "test_exp", "sources": [], "doc": "", "base_dir": "/tmp"} - host = {"hostname": "test_host", "cpu_count": 1, "python_version": "3.4"} + host = {"hostname": "test_host", "cpu_count": 1, "python_version": "3.9"} config = {"config": "True", "foo": "bar", "answer": 42} command = "run" meta_info = {"comment": "test run"} diff --git a/tests/test_stflow/test_method_interception.py b/tests/test_stflow/test_method_interception.py index 547efaf7..d56ec7db 100644 --- a/tests/test_stflow/test_method_interception.py +++ b/tests/test_stflow/test_method_interception.py @@ -55,8 +55,8 @@ def test_log_file_writer(ex, tf): """ Tests whether logdir is stored into the info dictionary when creating a new FileWriter object. """ - TEST_LOG_DIR = "/dev/null" - TEST_LOG_DIR2 = "/tmp/sacred_test" + TEST_LOG_DIR = "/tmp/sacred_test1" + TEST_LOG_DIR2 = "/tmp/sacred_test2" @ex.main @LogFileWriter(ex) @@ -77,8 +77,8 @@ def test_log_summary_writer_as_context_manager(ex, tf): """ Check that Tensorflow log directory is captured by LogFileWriter context manager. """ - TEST_LOG_DIR = "/dev/null" - TEST_LOG_DIR2 = "/tmp/sacred_test" + TEST_LOG_DIR = "/tmp/sacred_test1" + TEST_LOG_DIR2 = "/tmp/sacred_test2" @ex.main def run_experiment(_run): @@ -138,8 +138,8 @@ def test_log_summary_writer_class(ex, tf): Tests whether logdir is stored into the info dictionary when creating a new FileWriter object, but this time on a method of a class. """ - TEST_LOG_DIR = "/dev/null" - TEST_LOG_DIR2 = "/tmp/sacred_test" + TEST_LOG_DIR = "/tmp/sacred_test1" + TEST_LOG_DIR2 = "/tmp/sacred_test2" class FooClass: def __init__(self): diff --git a/tests/test_utils.py b/tests/test_utils.py index bee2060e..b819ba72 100755 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -190,19 +190,19 @@ def test_module_is_in_cache(): def test_get_package_version(): package_version = get_package_version("pytest") - assert str(package_version) == "4.3.0" + assert str(package_version) == "6.2.3" def test_parse_version(): - parsed_version = parse_version("4.3.0") - assert str(parsed_version) == "4.3.0" + parsed_version = parse_version("6.2.3") + assert str(parsed_version) == "6.2.3" def test_get_package_version_comparison(): package_version = get_package_version("pytest") - current_version = parse_version("4.3.0") - old_version = parse_version("4.2.1") - new_version = parse_version("4.4.1") + current_version = parse_version("6.2.3") + old_version = parse_version("6.2.0") + new_version = parse_version("6.2.4") assert package_version == current_version assert not package_version < current_version assert not package_version > current_version diff --git a/tox.ini b/tox.ini index eb15e7e7..5bc96745 100644 --- a/tox.ini +++ b/tox.ini @@ -4,7 +4,7 @@ # and then run "tox" from this directory. [tox] -envlist = py35, py36, py37, setup, flake8, numpy-117, numpy-118, numpy-119, tensorflow-112, tensorflow-113, tensorflow-114, tensorflow-2, tensorflow-2-gpu +envlist = py37, py38, py39, setup, flake8, numpy-117, numpy-118, numpy-119, numpy-120, tensorflow-115, tensorflow-20, tensorflow-21, tensorflow-22, tensorflow-23, tensorflow-24 [testenv] deps = @@ -17,7 +17,7 @@ commands = basepython = python deps = -rdev-requirements.txt - numpy==1.17.5 + numpy~=1.17.0 commands = pytest tests/test_config {posargs} @@ -25,7 +25,7 @@ commands = basepython = python deps = -rdev-requirements.txt - numpy==1.18.5 + numpy~=1.18.0 commands = pytest tests/test_config {posargs} @@ -33,51 +33,68 @@ commands = basepython = python deps = -rdev-requirements.txt - numpy==1.19.5 + numpy~=1.19.0 commands = pytest tests/test_config {posargs} -[testenv:tensorflow-112] +[testenv:numpy-120] basepython = python deps = -rdev-requirements.txt - tensorflow==1.12.3 + numpy~=1.20.0 +commands = + pytest tests/test_config {posargs} + +[testenv:tensorflow-115] +basepython = python +deps = + -rdev-requirements.txt + tensorflow~=1.15.0 +commands = + pytest tests/test_stflow tests/test_optional.py \ + {posargs} + +[testenv:tensorflow-20] +basepython = python +deps = + -rdev-requirements.txt + tensorflow~=2.0.0 commands = pytest tests/test_stflow tests/test_optional.py \ {posargs} -[testenv:tensorflow-113] +[testenv:tensorflow-21] basepython = python deps = -rdev-requirements.txt - tensorflow==1.13.2 + tensorflow~=2.1.0 commands = pytest tests/test_stflow tests/test_optional.py \ {posargs} -[testenv:tensorflow-114] +[testenv:tensorflow-22] basepython = python deps = -rdev-requirements.txt - tensorflow==1.14.0 + tensorflow~=2.2.0 commands = pytest tests/test_stflow tests/test_optional.py \ {posargs} -[testenv:tensorflow-2] +[testenv:tensorflow-23] basepython = python deps = -rdev-requirements.txt - tensorflow==2.0.0 + tensorflow~=2.3.0 commands = pytest tests/test_stflow tests/test_optional.py \ {posargs} -[testenv:tensorflow-2-gpu] +[testenv:tensorflow-24] basepython = python deps = -rdev-requirements.txt - tensorflow-gpu==2.0.0 + tensorflow~=2.4.0 commands = pytest tests/test_stflow tests/test_optional.py \ {posargs} @@ -85,8 +102,8 @@ commands = [testenv:setup] basepython = python deps = - pytest==4.3.0 - mock==2.0.0 + pytest==6.2.3 + mock commands = pytest {posargs} @@ -104,7 +121,7 @@ commands = [testenv:black] basepython = python deps = - black==19.10b0 + black commands = black --check sacred/ tests/