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

[MAINT] Drop 3.6 python support #258

Merged
merged 4 commits into from
Jun 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions .github/workflows/pytest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.6, 3.7, 3.8]
python-version: [3.7, 3.8]
include:
- python-version: 3.8
code-cov: true
Expand Down Expand Up @@ -52,4 +52,4 @@ jobs:
uses: codecov/codecov-action@v1
with:
fail_ci_if_error: true
verbose: true
verbose: true
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import numpy as np

import torch.tensor
import torch

from autoPyTorch.pipeline.components.preprocessing.image_preprocessing.normalise.base_normalizer import BaseNormalizer

Expand Down Expand Up @@ -30,16 +30,16 @@ def fit(self, X: Dict[str, Any], y: Optional[Any] = None) -> "ImageNormalizer":
self.std = X['dataset_properties']['std']
return self

def __call__(self, X: Union[np.ndarray, torch.tensor]) -> Union[np.ndarray, torch.tensor]:
def __call__(self, X: Union[np.ndarray, torch.Tensor]) -> Union[np.ndarray, torch.Tensor]:
"""
Makes the autoPyTorchPreprocessingComponent Callable. Calling the component
calls the transform function of the underlying early_preprocessor and
returns the transformed array.
Args:
X (Union[np.ndarray, torch.tensor]): input data tensor
X (Union[np.ndarray, torch.Tensor]): input data tensor

Returns:
Union[np.ndarray, torch.tensor]: Transformed data tensor
Union[np.ndarray, torch.Tensor]: Transformed data tensor
"""
X = (X - self.mean) / self.std
return X
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import numpy as np

import torch.tensor
import torch

from autoPyTorch.pipeline.components.preprocessing.image_preprocessing.normalise.base_normalizer import (
BaseNormalizer
Expand Down Expand Up @@ -34,16 +34,16 @@ def transform(self, X: Dict[str, Any]) -> Dict[str, Any]:
X.update({'normalise': self})
return X

def __call__(self, X: Union[np.ndarray, torch.tensor]) -> Union[np.ndarray, torch.tensor]:
def __call__(self, X: Union[np.ndarray, torch.Tensor]) -> Union[np.ndarray, torch.Tensor]:
"""
Makes the autoPyTorchPreprocessingComponent Callable. Calling the component
calls the transform function of the underlying early_preprocessor and
returns the transformed array.
Args:
X (Union[np.ndarray, torch.tensor]): input data tensor
X (Union[np.ndarray, torch.Tensor]): input data tensor

Returns:
Union[np.ndarray, torch.tensor]: Transformed data tensor
Union[np.ndarray, torch.Tensor]: Transformed data tensor
"""
return X

Expand Down
12 changes: 10 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import setuptools
import sys
if sys.version_info < (3, 7):
raise ValueError(
'Unsupported Python version %d.%d.%d found. Auto-PyTorch requires Python '
'3.7 or higher.' % (sys.version_info.major, sys.version_info.minor, sys.version_info.micro)
)

with open("README.md", "r") as f:
long_description = f.read()
Expand Down Expand Up @@ -27,10 +33,12 @@
"Topic :: Utilities",
"Topic :: Scientific/Engineering",
"Topic :: Scientific/Engineering :: Artificial Intelligence",
"Programming Language :: Python :: 3",
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
"License :: OSI Approved :: BSD License",
],
python_requires='>=3',
python_requires='>=3.7',
platforms=['Linux'],
install_requires=requirements,
include_package_data=True,
Expand Down
4 changes: 2 additions & 2 deletions test/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from autoPyTorch.utils.pipeline import get_dataset_requirements


N_SAMPLES = 200
N_SAMPLES = 300


@pytest.fixture(scope="session")
Expand Down Expand Up @@ -222,7 +222,7 @@ def get_tabular_data(task):
validator = TabularInputValidator(is_classification=True).fit(X.copy(), y.copy())

elif task == "regression_numerical_only":
X, y = make_regression(n_samples=N_SAMPLES,
X, y = make_regression(n_samples=3 * N_SAMPLES,
n_features=4,
n_informative=3,
n_targets=1,
Expand Down
76 changes: 21 additions & 55 deletions test/test_api/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import os
import pathlib
import pickle
import sys
import unittest
from test.test_api.utils import dummy_do_dummy_prediction, dummy_eval_function, dummy_traditional_classification

Expand Down Expand Up @@ -63,17 +62,11 @@ def test_tabular_classification(openml_id, resampling_strategy, backend, resampl
X_train, X_test, y_train, y_test = sklearn.model_selection.train_test_split(
X, y, random_state=42)

include = None
# for python less than 3.7, learned entity embedding
# is not able to be stored on disk (only on CI)
if sys.version_info < (3, 7):
include = {'network_embedding': ['NoEmbedding']}
# Search for a good configuration
estimator = TabularClassificationTask(
backend=backend,
resampling_strategy=resampling_strategy,
resampling_strategy_args=resampling_strategy_args,
include_components=include,
seed=42,
)

Expand Down Expand Up @@ -210,18 +203,14 @@ def test_tabular_classification(openml_id, resampling_strategy, backend, resampl
assert 'train_loss' in incumbent_results

# Check that we can pickle
# Test pickle
# This can happen on python greater than 3.6
# as older python do not control the state of the logger
if sys.version_info >= (3, 7):
dump_file = os.path.join(estimator._backend.temporary_directory, 'dump.pkl')
dump_file = os.path.join(estimator._backend.temporary_directory, 'dump.pkl')

with open(dump_file, 'wb') as f:
pickle.dump(estimator, f)
with open(dump_file, 'wb') as f:
pickle.dump(estimator, f)

with open(dump_file, 'rb') as f:
restored_estimator = pickle.load(f)
restored_estimator.predict(X_test)
with open(dump_file, 'rb') as f:
restored_estimator = pickle.load(f)
restored_estimator.predict(X_test)

# Test refit on dummy data
estimator.refit(dataset=backend.load_datamanager())
Expand Down Expand Up @@ -264,17 +253,11 @@ def test_tabular_regression(openml_name, resampling_strategy, backend, resamplin
X_train, X_test, y_train, y_test = sklearn.model_selection.train_test_split(
X, y, random_state=1)

include = None
# for python less than 3.7, learned entity embedding
# is not able to be stored on disk (only on CI)
if sys.version_info < (3, 7):
include = {'network_embedding': ['NoEmbedding']}
# Search for a good configuration
estimator = TabularRegressionTask(
backend=backend,
resampling_strategy=resampling_strategy,
resampling_strategy_args=resampling_strategy_args,
include_components=include,
seed=42,
)

Expand Down Expand Up @@ -403,30 +386,26 @@ def test_tabular_regression(openml_name, resampling_strategy, backend, resamplin
assert 'train_loss' in incumbent_results, estimator.run_history.data

# Check that we can pickle
# Test pickle
# This can happen on python greater than 3.6
# as older python do not control the state of the logger
if sys.version_info >= (3, 7):
dump_file = os.path.join(estimator._backend.temporary_directory, 'dump.pkl')
dump_file = os.path.join(estimator._backend.temporary_directory, 'dump.pkl')

with open(dump_file, 'wb') as f:
pickle.dump(estimator, f)
with open(dump_file, 'wb') as f:
pickle.dump(estimator, f)

with open(dump_file, 'rb') as f:
restored_estimator = pickle.load(f)
restored_estimator.predict(X_test)
with open(dump_file, 'rb') as f:
restored_estimator = pickle.load(f)
restored_estimator.predict(X_test)

# Test refit on dummy data
estimator.refit(dataset=backend.load_datamanager())
# Test refit on dummy data
estimator.refit(dataset=backend.load_datamanager())

# Make sure that a configuration space is stored in the estimator
assert isinstance(estimator.get_search_space(), CS.ConfigurationSpace)
# Make sure that a configuration space is stored in the estimator
assert isinstance(estimator.get_search_space(), CS.ConfigurationSpace)

representation = estimator.show_models()
assert isinstance(representation, str)
assert 'Weight' in representation
assert 'Preprocessing' in representation
assert 'Estimator' in representation
representation = estimator.show_models()
assert isinstance(representation, str)
assert 'Weight' in representation
assert 'Preprocessing' in representation
assert 'Estimator' in representation


@pytest.mark.parametrize('openml_id', (
Expand Down Expand Up @@ -536,16 +515,10 @@ def test_portfolio_selection(openml_id, backend, n_samples):
X_train, X_test, y_train, y_test = sklearn.model_selection.train_test_split(
X, y, random_state=1)

include = None
# for python less than 3.7, learned entity embedding
# is not able to be stored on disk (only on CI)
if sys.version_info < (3, 7):
include = {'network_embedding': ['NoEmbedding']}
# Search for a good configuration
estimator = TabularClassificationTask(
backend=backend,
resampling_strategy=HoldoutValTypes.holdout_validation,
include_components=include
)

with unittest.mock.patch.object(estimator, '_do_dummy_prediction', new=dummy_do_dummy_prediction):
Expand Down Expand Up @@ -584,16 +557,9 @@ def test_portfolio_selection_failure(openml_id, backend, n_samples):
X_train, X_test, y_train, y_test = sklearn.model_selection.train_test_split(
X, y, random_state=1)

include = None
# for python less than 3.7, learned entity embedding
# is not able to be stored on disk (only on CI)
if sys.version_info < (3, 7):
include = {'network_embedding': ['NoEmbedding']}
# Search for a good configuration
estimator = TabularClassificationTask(
backend=backend,
resampling_strategy=HoldoutValTypes.holdout_validation,
include_components=include
)
with pytest.raises(FileNotFoundError, match=r"The path: .+? provided for 'portfolio_selection' "
r"for the file containing the portfolio configurations "
Expand Down
2 changes: 0 additions & 2 deletions test/test_ensemble/test_ensemble.py
Original file line number Diff line number Diff line change
Expand Up @@ -690,8 +690,6 @@ def test_ensemble_builder_process_realrun(dask_client, ensemble_backend):

@flaky(max_runs=3)
@unittest.mock.patch('autoPyTorch.ensemble.ensemble_builder.EnsembleBuilder.fit_ensemble')
@pytest.mark.skipif(sys.version_info >= (3, 7),
reason="Causes out-of-memory Errors in CI")
def test_ensemble_builder_nbest_remembered(fit_ensemble, ensemble_backend, dask_client):
"""
Makes sure ensemble builder returns the size of the ensemble that pynisher allowed
Expand Down
1 change: 0 additions & 1 deletion test/test_evaluation/test_evaluation.py
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,6 @@ def test_exception_in_target_function(self, eval_holdout_mock):
self.assertIn('traceback', info[1].additional_info)
self.assertNotIn('exitcode', info[1].additional_info)

@unittest.skipIf(sys.version_info < (3, 7), reason="requires python3.7 or higher")
def test_silent_exception_in_target_function(self):
config = unittest.mock.Mock(spec=int)
config.config_id = 198
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,12 +126,11 @@ def test_model_fit_predict_score(traditional_learner, fit_dictionary_tabular):
fit_dictionary_tabular['y_train'][fit_dictionary_tabular['val_indices']])
assert np.allclose(score, model.fit_output['val_score'], atol=1e-6)

if sys.version_info >= (3, 7):
dump_file = os.path.join(fit_dictionary_tabular['backend'].temporary_directory, 'dump.pkl')
dump_file = os.path.join(fit_dictionary_tabular['backend'].temporary_directory, 'dump.pkl')

with open(dump_file, 'wb') as f:
pickle.dump(model, f)
with open(dump_file, 'wb') as f:
pickle.dump(model, f)

with open(dump_file, 'rb') as f:
restored_estimator = pickle.load(f)
restored_estimator.predict(fit_dictionary_tabular['X_train'])
with open(dump_file, 'rb') as f:
restored_estimator = pickle.load(f)
restored_estimator.predict(fit_dictionary_tabular['X_train'])