From 72144c0ca6d88e097d2fb05c171964d4c44f528c Mon Sep 17 00:00:00 2001 From: Plamen Valentinov Kolev <41479552+pvk-developer@users.noreply.github.com> Date: Tue, 2 May 2023 19:00:48 +0200 Subject: [PATCH] Use cached version of faker rather than instance every time (#1406) * Use cached version of faker rather than instance every time * instance lru_cache --- sdv/metadata/anonymization.py | 9 ++++++++- tests/unit/metadata/test_anonymization.py | 21 +++++++++++++++++---- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/sdv/metadata/anonymization.py b/sdv/metadata/anonymization.py index 56d465885..7e599e8e1 100644 --- a/sdv/metadata/anonymization.py +++ b/sdv/metadata/anonymization.py @@ -2,6 +2,7 @@ import inspect import warnings +from functools import lru_cache from faker import Faker from faker.config import AVAILABLE_LOCALES @@ -47,6 +48,12 @@ } +@lru_cache() +def get_faker_instance(): + """Return a ``faker.Faker`` instance with all the locales.""" + return Faker(AVAILABLE_LOCALES) + + def is_faker_function(function_name): """Return whether or not the function name is a valid Faker function. @@ -60,7 +67,7 @@ def is_faker_function(function_name): try: with warnings.catch_warnings(): warnings.filterwarnings('ignore', module='faker') - getattr(Faker(AVAILABLE_LOCALES), function_name) + getattr(get_faker_instance(), function_name) except AttributeError: return False diff --git a/tests/unit/metadata/test_anonymization.py b/tests/unit/metadata/test_anonymization.py index a854da5a1..b2983cfde 100644 --- a/tests/unit/metadata/test_anonymization.py +++ b/tests/unit/metadata/test_anonymization.py @@ -1,7 +1,7 @@ from unittest.mock import Mock, patch from sdv.metadata.anonymization import ( - _detect_provider_name, get_anonymized_transformer, is_faker_function) + _detect_provider_name, get_anonymized_transformer, get_faker_instance, is_faker_function) class TestAnonimization: @@ -110,18 +110,31 @@ def test_is_faker_function(self, faker_mock): # Assert assert result is True - @patch('sdv.metadata.anonymization.Faker') - def test_is_faker_function_error(self, faker_mock): + @patch('sdv.metadata.anonymization.get_faker_instance') + def test_is_faker_function_error(self, mock_get_faker_instance): """Test that the method returns False if ``function_name`` is not a valid faker function. If the ``function_name`` is not an attribute of ``Faker()`` then we should return false. This test mocks ``Faker`` to not have the attribute that is passed as ``function_name``. """ # Setup - faker_mock.return_value = Mock(spec=[]) + mock_get_faker_instance.return_value = Mock(spec=[]) # Run result = is_faker_function('blah') # Assert assert result is False + mock_get_faker_instance.assert_called_once() + + @patch('sdv.metadata.anonymization.Faker') + def test_get_faker_instance(self, mock_faker): + """Test that ``get_faker_instance`` returns the same object.""" + # Setup + first_instance = get_faker_instance() + + # Run + second_instance = get_faker_instance() + + # Assert + assert id(first_instance) == id(second_instance)