Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Python 3.9 #1197

Merged
merged 33 commits into from Dec 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
7b360ab
Fix importlib error when using py3.9
shagunsodhani Dec 11, 2020
b0733d5
Fix lint errors
shagunsodhani Dec 11, 2020
c46ceef
Add a method to match lines based on regex
shagunsodhani Dec 11, 2020
d7ac56c
fix lint error
shagunsodhani Dec 11, 2020
fd7d851
bump hydra version in discovery test plugin
shagunsodhani Dec 11, 2020
d6a8353
Add python 3.9 in setup.py
shagunsodhani Dec 11, 2020
6a6919d
Skip python 3.9 tests on windows
shagunsodhani Dec 11, 2020
75564c3
use assert_text_same when lengths of actual and expected output do no…
shagunsodhani Dec 12, 2020
0cd2c91
Remove dependency on hydra version
shagunsodhani Dec 12, 2020
cb08a11
Check python version to decide if importlib_resources should be imported
shagunsodhani Dec 12, 2020
821b4d5
Update the install script for plugins to reflect support for python 3.9
shagunsodhani Dec 12, 2020
a21dca9
pin virtualenv to 20.0.33 for windows
shagunsodhani Dec 12, 2020
0a871a0
Fix lint error
shagunsodhani Dec 12, 2020
81b5164
Enable CI for 3.9 on windows
shagunsodhani Dec 12, 2020
3ac079b
Update circle ci config
shagunsodhani Dec 12, 2020
7c44f29
Update circle ci config
shagunsodhani Dec 12, 2020
a3bb8b9
Fix issues with windows
shagunsodhani Dec 12, 2020
d115c8f
Skip Ray test for Python 3.9
shagunsodhani Dec 12, 2020
8364afb
Incorporate feedback
shagunsodhani Dec 12, 2020
a267dd5
Fix circleci config
shagunsodhani Dec 12, 2020
18f1c3c
Fix lint errors
shagunsodhani Dec 12, 2020
e55b904
Fix circleci config
shagunsodhani Dec 12, 2020
f9f4555
Fix some ci errors
shagunsodhani Dec 12, 2020
f5fdf25
Fix lint error
shagunsodhani Dec 13, 2020
c6da725
Fix lint error
shagunsodhani Dec 13, 2020
c79f7f0
Update setup.py for some plugins
shagunsodhani Dec 13, 2020
fec551d
Disable windows 9 support
shagunsodhani Dec 13, 2020
720abcd
Ax plugin doesnt support 3.9 for now
shagunsodhani Dec 14, 2020
ab772c5
Nevergrad python 3.9 support depends on Scikit-learn
shagunsodhani Dec 14, 2020
7c7a850
Add news entries
shagunsodhani Dec 14, 2020
2ffac4b
Accidentally removed support for optuna on windows
shagunsodhani Dec 15, 2020
4c69b25
Incorporate feedback
shagunsodhani Dec 16, 2020
70e64d2
Disable windows test for optuna
shagunsodhani Dec 18, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 8 additions & 10 deletions .circleci/config.yml
Expand Up @@ -92,16 +92,16 @@ commands:
choco install -y --no-progress openssl javaruntime
- run:
name: Preparing environment - Hydra
# Using virtualenv==20.0.33 higher versions of virtualenv are not compatible with conda on windows. Relevant issue: https://github.com/ContinuumIO/anaconda-issues/issues/12094
command: |
conda create -n hydra python=<< parameters.py_version >> pywin32 -qy
conda create -n hydra python=<< parameters.py_version >> pywin32 virtualenv==20.0.33 -qy
omry marked this conversation as resolved.
Show resolved Hide resolved
conda activate hydra
pip install nox dataclasses --progress-bar off
- save_cache:
key: -<< pipeline.parameters.cache_key_version >>-win-sys-{{ .Branch }}-<< parameters.py_version >>
paths:
- C:\tools\miniconda3


jobs:
test_macos:
parameters:
Expand Down Expand Up @@ -240,16 +240,15 @@ workflows:
- test_macos:
matrix:
parameters:
py_version: ["3.6", "3.7", "3.8"]
py_version: ["3.6", "3.7", "3.8", "3.9"]
- test_linux:
matrix:
parameters:
py_version: ["3.6", "3.7", "3.8"]
py_version: ["3.6", "3.7", "3.8", "3.9"]
- test_win:
matrix:
parameters:
# py_version: ["3.6", "3.7", "3.8"]
py_version: ["3.6"]
py_version: ["3.6", "3.7", "3.8"]
shagunsodhani marked this conversation as resolved.
Show resolved Hide resolved


plugin_tests:
Expand All @@ -258,18 +257,17 @@ workflows:
- test_plugin_linux:
matrix:
parameters:
py_version: ["3.6", "3.7", "3.8"]
py_version: ["3.6", "3.7", "3.8", "3.9"]
test_plugin: [<< pipeline.parameters.test_plugins >>]
- test_plugin_macos:
matrix:
parameters:
py_version: ["3.6", "3.7", "3.8"]
py_version: ["3.6", "3.7", "3.8", "3.9"]
test_plugin: [<< pipeline.parameters.test_plugins >>]
- test_plugin_win:
matrix:
parameters:
# py_version: ["3.6", "3.7", "3.8"]
py_version: ["3.6"]
py_version: ["3.6", "3.7", "3.8",]
test_plugin: [<< pipeline.parameters.test_plugins >>]


Expand Down
22 changes: 16 additions & 6 deletions hydra/_internal/core_plugins/importlib_resources_config_source.py
@@ -1,13 +1,23 @@
# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
import os
import sys
from typing import List, Optional

import importlib_resources
from omegaconf import OmegaConf

from hydra.core.object_type import ObjectType
from hydra.plugins.config_source import ConfigLoadError, ConfigResult, ConfigSource

if sys.version_info.major >= 4 or (
sys.version_info.major >= 3 and sys.version_info.minor >= 9
):
from importlib import resources
else:
import importlib_resources as resources # type:ignore

# Relevant issue: https://github.com/python/mypy/issues/1153
# Use importlib backport for Python older than 3.9


class ImportlibResourcesConfigSource(ConfigSource):
def __init__(self, provider: str, path: str) -> None:
Expand All @@ -26,7 +36,7 @@ def load_config(
package_override: Optional[str] = None,
) -> ConfigResult:
normalized_config_path = self._normalize_file_name(config_path)
res = importlib_resources.files(self.path).joinpath(normalized_config_path)
res = resources.files(self.path).joinpath(normalized_config_path) # type:ignore
omry marked this conversation as resolved.
Show resolved Hide resolved
if not res.exists():
raise ConfigLoadError(f"Config not found : {normalized_config_path}")

Expand Down Expand Up @@ -54,7 +64,7 @@ def load_config(

def available(self) -> bool:
try:
ret = importlib_resources.is_resource(self.path, "__init__.py")
ret = resources.is_resource(self.path, "__init__.py") # type:ignore
assert isinstance(ret, bool)
return ret
except ValueError:
Expand All @@ -64,7 +74,7 @@ def available(self) -> bool:

def is_group(self, config_path: str) -> bool:
try:
files = importlib_resources.files(self.path)
files = resources.files(self.path) # type:ignore
except Exception:
return False

Expand All @@ -76,7 +86,7 @@ def is_group(self, config_path: str) -> bool:
def is_config(self, config_path: str) -> bool:
config_path = self._normalize_file_name(config_path)
try:
files = importlib_resources.files(self.path)
files = resources.files(self.path) # type:ignore
except Exception:
return False
res = files.joinpath(config_path)
Expand All @@ -87,7 +97,7 @@ def is_config(self, config_path: str) -> bool:
def list(self, config_path: str, results_filter: Optional[ObjectType]) -> List[str]:
files: List[str] = []
for file in (
importlib_resources.files(self.path).joinpath(config_path).iterdir()
resources.files(self.path).joinpath(config_path).iterdir() # type:ignore
):
fname = file.name
fpath = os.path.join(config_path, fname)
Expand Down
28 changes: 28 additions & 0 deletions hydra/test_utils/test_utils.py
Expand Up @@ -5,6 +5,7 @@
import copy
import logging
import os
import re
import shutil
import string
import subprocess
Expand Down Expand Up @@ -423,3 +424,30 @@ def assert_text_same(
print(diff)
print("-------------------------------")
assert False, "Mismatch between expected and actual text"


def assert_regex_match(
shagunsodhani marked this conversation as resolved.
Show resolved Hide resolved
from_line: str, to_line: str, from_name: str = "Expected", to_name: str = "Actual"
) -> None:
"""Check that the lines of `from_line` (which can be a regex expression)
matches the corresponding lines of `to_line` string.

In case the regex match fails, we display the diff as if `from_line` was a regular string.
"""
normalized_from_line = [x for x in normalize_newlines(from_line).split("\n") if x]
normalized_to_line = [x for x in normalize_newlines(to_line).split("\n") if x]
if len(normalized_from_line) != len(normalized_to_line):
assert_text_same(
from_line=from_line,
to_line=to_line,
from_name=from_name,
to_name=to_name,
)
for line1, line2 in zip(normalized_from_line, normalized_to_line):
if line1 != line2 and re.match(line1, line2) is None:
assert_text_same(
from_line=from_line,
to_line=to_line,
from_name=from_name,
to_name=to_name,
)
1 change: 1 addition & 0 deletions news/1062.feature
@@ -0,0 +1 @@
Support Python 3.9 .
2 changes: 1 addition & 1 deletion noxfile.py
Expand Up @@ -12,7 +12,7 @@

BASE = os.path.abspath(os.path.dirname(__file__))

DEFAULT_PYTHON_VERSIONS = ["3.6", "3.7", "3.8"]
DEFAULT_PYTHON_VERSIONS = ["3.6", "3.7", "3.8", "3.9"]
DEFAULT_OS_NAMES = ["Linux", "MacOS", "Windows"]

PYTHON_VERSIONS = os.environ.get(
Expand Down
1 change: 1 addition & 0 deletions plugins/hydra_ax_sweeper/setup.py
Expand Up @@ -18,6 +18,7 @@
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
# "Programming Language :: Python :: 3.9",
"Operating System :: POSIX :: Linux",
"Operating System :: MacOS",
"Development Status :: 4 - Beta",
Expand Down
1 change: 1 addition & 0 deletions plugins/hydra_colorlog/news/1062.feature
@@ -0,0 +1 @@
Support Python 3.9 .
1 change: 1 addition & 0 deletions plugins/hydra_colorlog/setup.py
Expand Up @@ -19,6 +19,7 @@
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Operating System :: OS Independent",
],
install_requires=["colorlog", "hydra-core>=1.0.0"],
Expand Down
1 change: 1 addition & 0 deletions plugins/hydra_joblib_launcher/news/1062.feature
@@ -0,0 +1 @@
Support Python 3.9 .
1 change: 1 addition & 0 deletions plugins/hydra_joblib_launcher/setup.py
Expand Up @@ -18,6 +18,7 @@
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Operating System :: MacOS",
"Operating System :: Microsoft :: Windows",
"Operating System :: POSIX :: Linux",
Expand Down
1 change: 1 addition & 0 deletions plugins/hydra_nevergrad_sweeper/setup.py
Expand Up @@ -19,6 +19,7 @@
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
# "Programming Language :: Python :: 3.9",
"Operating System :: OS Independent",
"Development Status :: 4 - Beta",
],
Expand Down
4 changes: 3 additions & 1 deletion plugins/hydra_optuna_sweeper/setup.py
Expand Up @@ -26,7 +26,9 @@ def get_long_description() -> str:
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3.9",
"Operating System :: POSIX :: Linux",
"Operating System :: MacOS",
omry marked this conversation as resolved.
Show resolved Hide resolved
"Development Status :: 4 - Beta",
],
install_requires=["hydra-core", "optuna"],
Expand Down
10 changes: 10 additions & 0 deletions plugins/hydra_optuna_sweeper/tests/test_optuna_sweeper_plugin.py
Expand Up @@ -24,6 +24,8 @@
chdir_plugin_root()


# https://github.com/pyreadline/pyreadline/issues/65
@pytest.mark.filterwarnings("ignore::DeprecationWarning") # type: ignore
def test_discovery() -> None:
assert OptunaSweeper.__name__ in [
x.__name__ for x in Plugins.instance().discover(Sweeper)
Expand All @@ -40,6 +42,8 @@ def check_distribution(expected: BaseDistribution, actual: BaseDistribution) ->
assert set(expected.choices) == set(actual.choices)


# https://github.com/pyreadline/pyreadline/issues/65
@pytest.mark.filterwarnings("ignore::DeprecationWarning") # type: ignore
@pytest.mark.parametrize( # type: ignore
"input, expected",
[
Expand Down Expand Up @@ -73,6 +77,8 @@ def test_create_optuna_distribution_from_config(input: Any, expected: Any) -> No
check_distribution(expected, actual)


# https://github.com/pyreadline/pyreadline/issues/65
@pytest.mark.filterwarnings("ignore::DeprecationWarning") # type: ignore
@pytest.mark.parametrize( # type: ignore
"input, expected",
[
Expand All @@ -94,6 +100,8 @@ def test_create_optuna_distribution_from_override(input: Any, expected: Any) ->
check_distribution(expected, actual)


# https://github.com/pyreadline/pyreadline/issues/65
@pytest.mark.filterwarnings("ignore::DeprecationWarning") # type: ignore
def test_launch_jobs(hydra_sweep_runner: TSweepRunner) -> None:
sweep = hydra_sweep_runner(
calling_file=None,
Expand All @@ -112,6 +120,8 @@ def test_launch_jobs(hydra_sweep_runner: TSweepRunner) -> None:
assert sweep.returns is None


# https://github.com/pyreadline/pyreadline/issues/65
@pytest.mark.filterwarnings("ignore::DeprecationWarning") # type: ignore
@pytest.mark.parametrize("with_commandline", (True, False)) # type: ignore
def test_optuna_example(with_commandline: bool, tmpdir: Path) -> None:
cmd = [
Expand Down
1 change: 1 addition & 0 deletions plugins/hydra_ray_launcher/setup.py
Expand Up @@ -17,6 +17,7 @@
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
# "Programming Language :: Python :: 3.9",
"Operating System :: MacOS",
"Operating System :: POSIX :: Linux",
],
Expand Down
1 change: 1 addition & 0 deletions plugins/hydra_rq_launcher/news/1062.feature
@@ -0,0 +1 @@
Support Python 3.9 .
1 change: 1 addition & 0 deletions plugins/hydra_rq_launcher/setup.py
Expand Up @@ -19,6 +19,7 @@
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Operating System :: MacOS",
"Operating System :: POSIX :: Linux",
],
Expand Down
1 change: 1 addition & 0 deletions plugins/hydra_submitit_launcher/news/1062.feature
@@ -0,0 +1 @@
Support Python 3.9 .
1 change: 1 addition & 0 deletions plugins/hydra_submitit_launcher/setup.py
Expand Up @@ -18,6 +18,7 @@
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Operating System :: MacOS",
"Operating System :: POSIX :: Linux",
"Development Status :: 4 - Beta",
Expand Down
1 change: 1 addition & 0 deletions setup.py
Expand Up @@ -48,6 +48,7 @@
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Operating System :: POSIX :: Linux",
"Operating System :: MacOS",
"Operating System :: Microsoft :: Windows",
Expand Down
2 changes: 1 addition & 1 deletion tests/standalone_apps/discovery_test_plugin/setup.py
Expand Up @@ -8,5 +8,5 @@
author_email="omry@fb.com",
url="https://github.com/facebookresearch/hydra/",
packages=find_namespace_packages(include=["hydra_plugins.*"]),
install_requires=["hydra-core==1.0.*"],
install_requires=["hydra-core"],
)
24 changes: 16 additions & 8 deletions tests/test_hydra.py
Expand Up @@ -15,7 +15,7 @@
from hydra.test_utils.test_utils import (
TSweepRunner,
TTaskRunner,
assert_text_same,
assert_regex_match,
chdir_hydra_root,
get_run_output,
integration_test,
Expand Down Expand Up @@ -1055,9 +1055,9 @@ def test_app_with_error_exception_sanitized(tmpdir: Any, monkeypatch: Any) -> No
"hydra.sweep.dir=" + str(tmpdir),
]
expected = """Traceback (most recent call last):
File "my_app.py", line 13, in my_app
File ".*my_app.py", line 13, in my_app
foo(cfg)
File "my_app.py", line 8, in foo
File ".*my_app.py", line 8, in foo
cfg.foo = "bar" # does not exist in the config
omegaconf.errors.ConfigAttributeError: Key 'foo' is not in struct
\tfull_key: foo
Expand All @@ -1067,7 +1067,12 @@ def test_app_with_error_exception_sanitized(tmpdir: Any, monkeypatch: Any) -> No
Set the environment variable HYDRA_FULL_ERROR=1 for a complete stack trace."""

ret = run_with_error(cmd)
assert normalize_newlines(expected) == normalize_newlines(ret)
assert_regex_match(
from_line=expected,
to_line=ret,
from_name="Expected output",
to_name="Actual output",
)
omry marked this conversation as resolved.
Show resolved Hide resolved


def test_hydra_to_job_config_interpolation(tmpdir: Any) -> Any:
Expand Down Expand Up @@ -1155,7 +1160,7 @@ def test_2(self) -> None:
dedent(
"""\
Traceback (most recent call last):
File "my_app.py", line 9, in my_app
File ".*my_app.py", line 9, in my_app
1 / 0
ZeroDivisionError: division by zero

Expand All @@ -1165,11 +1170,14 @@ def test_2(self) -> None:
),
],
)
def test_hydra_exception(monkeypatch: Any, tmpdir: Any, expected: str) -> None:
def test_hydra_exception(
monkeypatch: Any,
tmpdir: Any,
expected: str,
) -> None:
monkeypatch.chdir("tests/test_apps/app_exception")
ret = run_with_error(["my_app.py", f"hydra.run.dir={tmpdir}"])

assert_text_same(
assert_regex_match(
from_line=expected,
to_line=ret,
from_name="Expected output",
Expand Down