Decorators for deprecation and named arguments validation (#30799)
* Fix do_reduce_labels for maskformer image processor * Deprecate reduce_labels in favor to do_reduce_labels * Deprecate reduce_labels in favor to do_reduce_labels (segformer) * Deprecate reduce_labels in favor to do_reduce_labels (oneformer) * Deprecate reduce_labels in favor to do_reduce_labels (maskformer) * Deprecate reduce_labels in favor to do_reduce_labels (mask2former) * Fix typo * Update mask2former test * fixup * Update segmentation examples * Update docs * Fixup * Imports fixup * Add deprecation decorator draft * Add deprecation decorator * Fixup * Add deprecate_kwarg decorator * Validate kwargs decorator * Kwargs validation (beit) * fixup * Kwargs validation (mask2former) * Kwargs validation (maskformer) * Kwargs validation (oneformer) * Kwargs validation (segformer) * Better message * Fix oneformer processor save-load test * Update src/transformers/utils/deprecation.py Co-authored-by: amyeroberts <22614925+amyeroberts@users.noreply.github.com> * Update src/transformers/utils/deprecation.py Co-authored-by: amyeroberts <22614925+amyeroberts@users.noreply.github.com> * Update src/transformers/utils/deprecation.py Co-authored-by: Pablo Montalvo <39954772+molbap@users.noreply.github.com> * Update src/transformers/utils/deprecation.py Co-authored-by: Pablo Montalvo <39954772+molbap@users.noreply.github.com> * Better handle classmethod warning * Fix typo, remove warn * Add header * Docs and `additional_message` * Move to filter decorator ot generic * Proper deprecation for semantic segm scripts * Add to __init__ and update import * Basic tests for filter decorator * Fix doc * Override `to_dict()` to pop depracated `_max_size` * Pop unused parameters * Fix trailing whitespace * Add test for deprecation * Add deprecation warning control parameter * Update generic test * Fixup deprecation tests * Introduce init service kwargs * Revert popping unused params * Revert oneformer test * Allow "metadata" to pass * Better docs * Fix test * Add notion in docstring * Fix notification for both names * Add func name to warning message * Fixup --------- Co-authored-by: amyeroberts <22614925+amyeroberts@users.noreply.github.com> Co-authored-by: Pablo Montalvo <39954772+molbap@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
4fa4dcb2be
commit
517df566f5
@@ -136,6 +136,7 @@ class BeitImageProcessingTest(ImageProcessingTestMixin, unittest.TestCase):
|
||||
self.assertTrue(hasattr(image_processing, "do_normalize"))
|
||||
self.assertTrue(hasattr(image_processing, "image_mean"))
|
||||
self.assertTrue(hasattr(image_processing, "image_std"))
|
||||
self.assertTrue(hasattr(image_processing, "do_reduce_labels"))
|
||||
|
||||
def test_image_processor_from_dict_with_kwargs(self):
|
||||
image_processor = self.image_processing_class.from_dict(self.image_processor_dict)
|
||||
@@ -144,7 +145,7 @@ class BeitImageProcessingTest(ImageProcessingTestMixin, unittest.TestCase):
|
||||
self.assertEqual(image_processor.do_reduce_labels, False)
|
||||
|
||||
image_processor = self.image_processing_class.from_dict(
|
||||
self.image_processor_dict, size=42, crop_size=84, reduce_labels=True
|
||||
self.image_processor_dict, size=42, crop_size=84, do_reduce_labels=True
|
||||
)
|
||||
self.assertEqual(image_processor.size, {"height": 42, "width": 42})
|
||||
self.assertEqual(image_processor.crop_size, {"height": 84, "width": 84})
|
||||
@@ -270,3 +271,16 @@ class BeitImageProcessingTest(ImageProcessingTestMixin, unittest.TestCase):
|
||||
encoding = image_processing(image, map, return_tensors="pt")
|
||||
self.assertTrue(encoding["labels"].min().item() >= 0)
|
||||
self.assertTrue(encoding["labels"].max().item() <= 255)
|
||||
|
||||
def test_removed_deprecated_kwargs(self):
|
||||
image_processor_dict = dict(self.image_processor_dict)
|
||||
image_processor_dict.pop("do_reduce_labels", None)
|
||||
image_processor_dict["reduce_labels"] = True
|
||||
|
||||
# test we are able to create the image processor with the deprecated kwargs
|
||||
image_processor = self.image_processing_class(**image_processor_dict)
|
||||
self.assertEqual(image_processor.do_reduce_labels, True)
|
||||
|
||||
# test we still support reduce_labels with config
|
||||
image_processor = self.image_processing_class.from_dict(image_processor_dict)
|
||||
self.assertEqual(image_processor.do_reduce_labels, True)
|
||||
|
||||
@@ -274,7 +274,7 @@ class Mask2FormerImageProcessingTest(ImageProcessingTestMixin, unittest.TestCase
|
||||
instance_seg2, inst2class2 = get_instance_segmentation_and_mapping(annotation2)
|
||||
|
||||
# create a image processor
|
||||
image_processing = Mask2FormerImageProcessor(reduce_labels=True, ignore_index=255, size=(512, 512))
|
||||
image_processing = Mask2FormerImageProcessor(do_reduce_labels=True, ignore_index=255, size=(512, 512))
|
||||
|
||||
# prepare the images and annotations
|
||||
inputs = image_processing(
|
||||
@@ -317,7 +317,7 @@ class Mask2FormerImageProcessingTest(ImageProcessingTestMixin, unittest.TestCase
|
||||
)
|
||||
|
||||
# create a image processor
|
||||
image_processing = Mask2FormerImageProcessor(reduce_labels=True, ignore_index=255, size=(512, 512))
|
||||
image_processing = Mask2FormerImageProcessor(do_reduce_labels=True, ignore_index=255, size=(512, 512))
|
||||
|
||||
# prepare the images and annotations
|
||||
inputs = image_processing(
|
||||
@@ -490,3 +490,16 @@ class Mask2FormerImageProcessingTest(ImageProcessingTestMixin, unittest.TestCase
|
||||
expected_num_segments = max([el["id"] for el in el_unfused]) - num_to_fuse
|
||||
num_segments_fused = max([el["id"] for el in el_fused])
|
||||
self.assertEqual(num_segments_fused, expected_num_segments)
|
||||
|
||||
def test_removed_deprecated_kwargs(self):
|
||||
image_processor_dict = dict(self.image_processor_dict)
|
||||
image_processor_dict.pop("do_reduce_labels", None)
|
||||
image_processor_dict["reduce_labels"] = True
|
||||
|
||||
# test we are able to create the image processor with the deprecated kwargs
|
||||
image_processor = self.image_processing_class(**image_processor_dict)
|
||||
self.assertEqual(image_processor.do_reduce_labels, True)
|
||||
|
||||
# test we still support reduce_labels with config
|
||||
image_processor = self.image_processing_class.from_dict(image_processor_dict)
|
||||
self.assertEqual(image_processor.do_reduce_labels, True)
|
||||
|
||||
@@ -274,7 +274,7 @@ class MaskFormerImageProcessingTest(ImageProcessingTestMixin, unittest.TestCase)
|
||||
instance_seg2, inst2class2 = get_instance_segmentation_and_mapping(annotation2)
|
||||
|
||||
# create a image processor
|
||||
image_processing = MaskFormerImageProcessor(reduce_labels=True, ignore_index=255, size=(512, 512))
|
||||
image_processing = MaskFormerImageProcessor(do_reduce_labels=True, ignore_index=255, size=(512, 512))
|
||||
|
||||
# prepare the images and annotations
|
||||
inputs = image_processing(
|
||||
@@ -317,7 +317,7 @@ class MaskFormerImageProcessingTest(ImageProcessingTestMixin, unittest.TestCase)
|
||||
)
|
||||
|
||||
# create a image processor
|
||||
image_processing = MaskFormerImageProcessor(reduce_labels=True, ignore_index=255, size=(512, 512))
|
||||
image_processing = MaskFormerImageProcessor(do_reduce_labels=True, ignore_index=255, size=(512, 512))
|
||||
|
||||
# prepare the images and annotations
|
||||
inputs = image_processing(
|
||||
@@ -525,3 +525,16 @@ class MaskFormerImageProcessingTest(ImageProcessingTestMixin, unittest.TestCase)
|
||||
expected_num_segments = max([el["id"] for el in el_unfused]) - num_to_fuse
|
||||
num_segments_fused = max([el["id"] for el in el_fused])
|
||||
self.assertEqual(num_segments_fused, expected_num_segments)
|
||||
|
||||
def test_removed_deprecated_kwargs(self):
|
||||
image_processor_dict = dict(self.image_processor_dict)
|
||||
image_processor_dict.pop("do_reduce_labels", None)
|
||||
image_processor_dict["reduce_labels"] = True
|
||||
|
||||
# test we are able to create the image processor with the deprecated kwargs
|
||||
image_processor = self.image_processing_class(**image_processor_dict)
|
||||
self.assertEqual(image_processor.do_reduce_labels, True)
|
||||
|
||||
# test we still support reduce_labels with config
|
||||
image_processor = self.image_processing_class.from_dict(image_processor_dict)
|
||||
self.assertEqual(image_processor.do_reduce_labels, True)
|
||||
|
||||
@@ -349,3 +349,16 @@ class OneFormerImageProcessingTest(ImageProcessingTestMixin, unittest.TestCase):
|
||||
image_processor = self.image_processing_class(**config_dict)
|
||||
|
||||
self.assertEqual(image_processor.metadata, metadata)
|
||||
|
||||
def test_removed_deprecated_kwargs(self):
|
||||
image_processor_dict = dict(self.image_processor_dict)
|
||||
image_processor_dict.pop("do_reduce_labels", None)
|
||||
image_processor_dict["reduce_labels"] = True
|
||||
|
||||
# test we are able to create the image processor with the deprecated kwargs
|
||||
image_processor = self.image_processing_class(**image_processor_dict)
|
||||
self.assertEqual(image_processor.do_reduce_labels, True)
|
||||
|
||||
# test we still support reduce_labels with config
|
||||
image_processor = self.image_processing_class.from_dict(image_processor_dict)
|
||||
self.assertEqual(image_processor.do_reduce_labels, True)
|
||||
|
||||
@@ -73,7 +73,7 @@ class OneFormerProcessorTester(unittest.TestCase):
|
||||
image_mean=[0.5, 0.5, 0.5],
|
||||
image_std=[0.5, 0.5, 0.5],
|
||||
num_labels=10,
|
||||
reduce_labels=False,
|
||||
do_reduce_labels=False,
|
||||
ignore_index=255,
|
||||
max_seq_length=77,
|
||||
task_seq_length=77,
|
||||
@@ -105,7 +105,7 @@ class OneFormerProcessorTester(unittest.TestCase):
|
||||
self.height = 3
|
||||
self.width = 4
|
||||
self.num_labels = num_labels
|
||||
self.reduce_labels = reduce_labels
|
||||
self.do_reduce_labels = do_reduce_labels
|
||||
self.ignore_index = ignore_index
|
||||
|
||||
def prepare_processor_dict(self):
|
||||
@@ -116,7 +116,7 @@ class OneFormerProcessorTester(unittest.TestCase):
|
||||
"image_mean": self.image_mean,
|
||||
"image_std": self.image_std,
|
||||
"num_labels": self.num_labels,
|
||||
"reduce_labels": self.reduce_labels,
|
||||
"do_reduce_labels": self.do_reduce_labels,
|
||||
"ignore_index": self.ignore_index,
|
||||
"class_info_file": self.class_info_file,
|
||||
"metadata": self.metadata,
|
||||
@@ -465,7 +465,7 @@ class OneFormerProcessingTest(unittest.TestCase):
|
||||
panoptic_map2, inst2class2 = create_panoptic_map(annotation2, segments_info2)
|
||||
|
||||
image_processor = OneFormerImageProcessor(
|
||||
reduce_labels=True,
|
||||
do_reduce_labels=True,
|
||||
ignore_index=0,
|
||||
size=(512, 512),
|
||||
class_info_file="ade20k_panoptic.json",
|
||||
@@ -553,7 +553,7 @@ class OneFormerProcessingTest(unittest.TestCase):
|
||||
panoptic_map2, inst2class2 = create_panoptic_map(annotation2, segments_info2)
|
||||
|
||||
image_processor = OneFormerImageProcessor(
|
||||
reduce_labels=True,
|
||||
do_reduce_labels=True,
|
||||
ignore_index=0,
|
||||
size=(512, 512),
|
||||
class_info_file="ade20k_panoptic.json",
|
||||
@@ -641,7 +641,7 @@ class OneFormerProcessingTest(unittest.TestCase):
|
||||
panoptic_map2, inst2class2 = create_panoptic_map(annotation2, segments_info2)
|
||||
|
||||
image_processor = OneFormerImageProcessor(
|
||||
reduce_labels=True,
|
||||
do_reduce_labels=True,
|
||||
ignore_index=0,
|
||||
size=(512, 512),
|
||||
class_info_file="ade20k_panoptic.json",
|
||||
@@ -710,7 +710,7 @@ class OneFormerProcessingTest(unittest.TestCase):
|
||||
|
||||
def test_post_process_semantic_segmentation(self):
|
||||
image_processor = OneFormerImageProcessor(
|
||||
reduce_labels=True,
|
||||
do_reduce_labels=True,
|
||||
ignore_index=0,
|
||||
size=(512, 512),
|
||||
class_info_file="ade20k_panoptic.json",
|
||||
@@ -744,7 +744,7 @@ class OneFormerProcessingTest(unittest.TestCase):
|
||||
|
||||
def test_post_process_instance_segmentation(self):
|
||||
image_processor = OneFormerImageProcessor(
|
||||
reduce_labels=True,
|
||||
do_reduce_labels=True,
|
||||
ignore_index=0,
|
||||
size=(512, 512),
|
||||
class_info_file="ade20k_panoptic.json",
|
||||
@@ -770,7 +770,7 @@ class OneFormerProcessingTest(unittest.TestCase):
|
||||
|
||||
def test_post_process_panoptic_segmentation(self):
|
||||
image_processor = OneFormerImageProcessor(
|
||||
reduce_labels=True,
|
||||
do_reduce_labels=True,
|
||||
ignore_index=0,
|
||||
size=(512, 512),
|
||||
class_info_file="ade20k_panoptic.json",
|
||||
|
||||
@@ -132,7 +132,9 @@ class SegformerImageProcessingTest(ImageProcessingTestMixin, unittest.TestCase):
|
||||
self.assertEqual(image_processor.size, {"height": 30, "width": 30})
|
||||
self.assertEqual(image_processor.do_reduce_labels, False)
|
||||
|
||||
image_processor = self.image_processing_class.from_dict(self.image_processor_dict, size=42, reduce_labels=True)
|
||||
image_processor = self.image_processing_class.from_dict(
|
||||
self.image_processor_dict, size=42, do_reduce_labels=True
|
||||
)
|
||||
self.assertEqual(image_processor.size, {"height": 42, "width": 42})
|
||||
self.assertEqual(image_processor.do_reduce_labels, True)
|
||||
|
||||
@@ -256,3 +258,16 @@ class SegformerImageProcessingTest(ImageProcessingTestMixin, unittest.TestCase):
|
||||
encoding = image_processing(image, map, return_tensors="pt")
|
||||
self.assertTrue(encoding["labels"].min().item() >= 0)
|
||||
self.assertTrue(encoding["labels"].max().item() <= 255)
|
||||
|
||||
def test_removed_deprecated_kwargs(self):
|
||||
image_processor_dict = dict(self.image_processor_dict)
|
||||
image_processor_dict.pop("do_reduce_labels", None)
|
||||
image_processor_dict["reduce_labels"] = True
|
||||
|
||||
# test we are able to create the image processor with the deprecated kwargs
|
||||
image_processor = self.image_processing_class(**image_processor_dict)
|
||||
self.assertEqual(image_processor.do_reduce_labels, True)
|
||||
|
||||
# test we still support reduce_labels with config
|
||||
image_processor = self.image_processing_class.from_dict(image_processor_dict)
|
||||
self.assertEqual(image_processor.do_reduce_labels, True)
|
||||
|
||||
170
tests/utils/test_deprecation.py
Normal file
170
tests/utils/test_deprecation.py
Normal file
@@ -0,0 +1,170 @@
|
||||
# Copyright 2024 The HuggingFace Team. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import unittest
|
||||
import warnings
|
||||
|
||||
from parameterized import parameterized
|
||||
|
||||
from transformers import __version__
|
||||
from transformers.utils.deprecation import deprecate_kwarg
|
||||
|
||||
|
||||
INFINITE_VERSION = "9999.0.0"
|
||||
|
||||
|
||||
class DeprecationDecoratorTester(unittest.TestCase):
|
||||
def test_rename_kwarg(self):
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter("ignore")
|
||||
|
||||
@deprecate_kwarg("deprecated_name", new_name="new_name", version=INFINITE_VERSION)
|
||||
def dummy_function(new_name=None, other_name=None):
|
||||
return new_name, other_name
|
||||
|
||||
# Test keyword argument is renamed
|
||||
value, other_value = dummy_function(deprecated_name="old_value")
|
||||
self.assertEqual(value, "old_value")
|
||||
self.assertIsNone(other_value)
|
||||
|
||||
# Test deprecated keyword argument not passed
|
||||
value, other_value = dummy_function(new_name="new_value")
|
||||
self.assertEqual(value, "new_value")
|
||||
self.assertIsNone(other_value)
|
||||
|
||||
# Test other keyword argument
|
||||
value, other_value = dummy_function(other_name="other_value")
|
||||
self.assertIsNone(value)
|
||||
self.assertEqual(other_value, "other_value")
|
||||
|
||||
# Test deprecated and new args are passed, the new one should be returned
|
||||
value, other_value = dummy_function(deprecated_name="old_value", new_name="new_value")
|
||||
self.assertEqual(value, "new_value")
|
||||
self.assertIsNone(other_value)
|
||||
|
||||
def test_rename_multiple_kwargs(self):
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter("ignore")
|
||||
|
||||
@deprecate_kwarg("deprecated_name1", new_name="new_name1", version=INFINITE_VERSION)
|
||||
@deprecate_kwarg("deprecated_name2", new_name="new_name2", version=INFINITE_VERSION)
|
||||
def dummy_function(new_name1=None, new_name2=None, other_name=None):
|
||||
return new_name1, new_name2, other_name
|
||||
|
||||
# Test keyword argument is renamed
|
||||
value1, value2, other_value = dummy_function(deprecated_name1="old_value1", deprecated_name2="old_value2")
|
||||
self.assertEqual(value1, "old_value1")
|
||||
self.assertEqual(value2, "old_value2")
|
||||
self.assertIsNone(other_value)
|
||||
|
||||
# Test deprecated keyword argument is not passed
|
||||
value1, value2, other_value = dummy_function(new_name1="new_value1", new_name2="new_value2")
|
||||
self.assertEqual(value1, "new_value1")
|
||||
self.assertEqual(value2, "new_value2")
|
||||
self.assertIsNone(other_value)
|
||||
|
||||
# Test other keyword argument is passed and correctly returned
|
||||
value1, value2, other_value = dummy_function(other_name="other_value")
|
||||
self.assertIsNone(value1)
|
||||
self.assertIsNone(value2)
|
||||
self.assertEqual(other_value, "other_value")
|
||||
|
||||
def test_warnings(self):
|
||||
# Test warning is raised for future version
|
||||
@deprecate_kwarg("deprecated_name", new_name="new_name", version=INFINITE_VERSION)
|
||||
def dummy_function(new_name=None, other_name=None):
|
||||
return new_name, other_name
|
||||
|
||||
with self.assertWarns(FutureWarning):
|
||||
dummy_function(deprecated_name="old_value")
|
||||
|
||||
# Test warning is not raised for past version, but arg is still renamed
|
||||
@deprecate_kwarg("deprecated_name", new_name="new_name", version="0.0.0")
|
||||
def dummy_function(new_name=None, other_name=None):
|
||||
return new_name, other_name
|
||||
|
||||
with warnings.catch_warnings(record=True) as raised_warnings:
|
||||
warnings.simplefilter("always")
|
||||
|
||||
value, other_value = dummy_function(deprecated_name="old_value")
|
||||
|
||||
self.assertEqual(value, "old_value")
|
||||
self.assertIsNone(other_value)
|
||||
self.assertEqual(len(raised_warnings), 0, f"Warning raised: {[w.message for w in raised_warnings]}")
|
||||
|
||||
# Test warning is raised for future version if warn_if_greater_or_equal_version is set
|
||||
@deprecate_kwarg("deprecated_name", version="0.0.0", warn_if_greater_or_equal_version=True)
|
||||
def dummy_function(deprecated_name=None):
|
||||
return deprecated_name
|
||||
|
||||
with self.assertWarns(FutureWarning):
|
||||
value = dummy_function(deprecated_name="deprecated_value")
|
||||
self.assertEqual(value, "deprecated_value")
|
||||
|
||||
# Test arg is not renamed if new_name is not specified, but warning is raised
|
||||
@deprecate_kwarg("deprecated_name", version=INFINITE_VERSION)
|
||||
def dummy_function(deprecated_name=None):
|
||||
return deprecated_name
|
||||
|
||||
with self.assertWarns(FutureWarning):
|
||||
value = dummy_function(deprecated_name="deprecated_value")
|
||||
self.assertEqual(value, "deprecated_value")
|
||||
|
||||
def test_raises(self):
|
||||
# Test if deprecated name and new name are both passed and raise_if_both_names is set -> raise error
|
||||
@deprecate_kwarg("deprecated_name", new_name="new_name", version=INFINITE_VERSION, raise_if_both_names=True)
|
||||
def dummy_function(new_name=None, other_name=None):
|
||||
return new_name, other_name
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
dummy_function(deprecated_name="old_value", new_name="new_value")
|
||||
|
||||
# Test for current version == deprecation version
|
||||
@deprecate_kwarg("deprecated_name", version=__version__, raise_if_greater_or_equal_version=True)
|
||||
def dummy_function(deprecated_name=None):
|
||||
return deprecated_name
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
dummy_function(deprecated_name="old_value")
|
||||
|
||||
# Test for current version > deprecation version
|
||||
@deprecate_kwarg("deprecated_name", version="0.0.0", raise_if_greater_or_equal_version=True)
|
||||
def dummy_function(deprecated_name=None):
|
||||
return deprecated_name
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
dummy_function(deprecated_name="old_value")
|
||||
|
||||
def test_additional_message(self):
|
||||
# Test additional message is added to the warning
|
||||
@deprecate_kwarg("deprecated_name", version=INFINITE_VERSION, additional_message="Additional message")
|
||||
def dummy_function(deprecated_name=None):
|
||||
return deprecated_name
|
||||
|
||||
with warnings.catch_warnings(record=True) as raised_warnings:
|
||||
warnings.simplefilter("always")
|
||||
dummy_function(deprecated_name="old_value")
|
||||
|
||||
self.assertTrue("Additional message" in str(raised_warnings[0].message))
|
||||
|
||||
@parameterized.expand(["0.0.0", __version__, INFINITE_VERSION])
|
||||
def test_warning_for_both_names(self, version):
|
||||
# We should raise warning if both names are passed for any specified version
|
||||
@deprecate_kwarg("deprecated_name", new_name="new_name", version=version)
|
||||
def dummy_function(new_name=None, **kwargs):
|
||||
return new_name
|
||||
|
||||
with self.assertWarns(FutureWarning):
|
||||
result = dummy_function(deprecated_name="old_value", new_name="new_value")
|
||||
self.assertEqual(result, "new_value")
|
||||
@@ -14,12 +14,14 @@
|
||||
# limitations under the License.
|
||||
|
||||
import unittest
|
||||
import warnings
|
||||
|
||||
import numpy as np
|
||||
|
||||
from transformers.testing_utils import require_flax, require_tf, require_torch
|
||||
from transformers.utils import (
|
||||
expand_dims,
|
||||
filter_out_non_signature_kwargs,
|
||||
flatten_dict,
|
||||
is_flax_available,
|
||||
is_tf_available,
|
||||
@@ -198,3 +200,74 @@ class GenericTester(unittest.TestCase):
|
||||
x = np.random.randn(3, 4)
|
||||
t = jnp.array(x)
|
||||
self.assertTrue(np.allclose(expand_dims(x, axis=1), np.asarray(expand_dims(t, axis=1))))
|
||||
|
||||
|
||||
class ValidationDecoratorTester(unittest.TestCase):
|
||||
def test_cases_no_warning(self):
|
||||
with warnings.catch_warnings(record=True) as raised_warnings:
|
||||
warnings.simplefilter("always")
|
||||
|
||||
# basic test
|
||||
@filter_out_non_signature_kwargs()
|
||||
def func1(a):
|
||||
return a
|
||||
|
||||
result = func1(1)
|
||||
self.assertEqual(result, 1)
|
||||
|
||||
# include extra kwarg
|
||||
@filter_out_non_signature_kwargs(extra=["extra_arg"])
|
||||
def func2(a, **kwargs):
|
||||
return a, kwargs
|
||||
|
||||
a, kwargs = func2(1)
|
||||
self.assertEqual(a, 1)
|
||||
self.assertEqual(kwargs, {})
|
||||
|
||||
a, kwargs = func2(1, extra_arg=2)
|
||||
self.assertEqual(a, 1)
|
||||
self.assertEqual(kwargs, {"extra_arg": 2})
|
||||
|
||||
# multiple extra kwargs
|
||||
@filter_out_non_signature_kwargs(extra=["extra_arg", "extra_arg2"])
|
||||
def func3(a, **kwargs):
|
||||
return a, kwargs
|
||||
|
||||
a, kwargs = func3(2)
|
||||
self.assertEqual(a, 2)
|
||||
self.assertEqual(kwargs, {})
|
||||
|
||||
a, kwargs = func3(3, extra_arg2=3)
|
||||
self.assertEqual(a, 3)
|
||||
self.assertEqual(kwargs, {"extra_arg2": 3})
|
||||
|
||||
a, kwargs = func3(1, extra_arg=2, extra_arg2=3)
|
||||
self.assertEqual(a, 1)
|
||||
self.assertEqual(kwargs, {"extra_arg": 2, "extra_arg2": 3})
|
||||
|
||||
# Check that no warnings were raised
|
||||
self.assertEqual(len(raised_warnings), 0, f"Warning raised: {[w.message for w in raised_warnings]}")
|
||||
|
||||
def test_cases_with_warnings(self):
|
||||
@filter_out_non_signature_kwargs()
|
||||
def func1(a):
|
||||
return a
|
||||
|
||||
with self.assertWarns(UserWarning):
|
||||
func1(1, extra_arg=2)
|
||||
|
||||
@filter_out_non_signature_kwargs(extra=["extra_arg"])
|
||||
def func2(a, **kwargs):
|
||||
return kwargs
|
||||
|
||||
with self.assertWarns(UserWarning):
|
||||
kwargs = func2(1, extra_arg=2, extra_arg2=3)
|
||||
self.assertEqual(kwargs, {"extra_arg": 2})
|
||||
|
||||
@filter_out_non_signature_kwargs(extra=["extra_arg", "extra_arg2"])
|
||||
def func3(a, **kwargs):
|
||||
return kwargs
|
||||
|
||||
with self.assertWarns(UserWarning):
|
||||
kwargs = func3(1, extra_arg=2, extra_arg2=3, extra_arg3=4)
|
||||
self.assertEqual(kwargs, {"extra_arg": 2, "extra_arg2": 3})
|
||||
|
||||
Reference in New Issue
Block a user