how to modify a python library function

Question:

In the python module fitter there is a function called:

    def fit(self, progress=False, n_jobs=-1, max_workers=-1):
    
    import warnings

    warnings.filterwarnings("ignore", category=RuntimeWarning)

    N = len(self.distributions)
    with tqdm_joblib(desc=f"Fitting {N} distributions", total=N) as progress_bar:
        Parallel(n_jobs=max_workers, backend='threading')(delayed(self._fit_single_distribution)(dist) for dist in self.distributions)


    self.df_errors = pd.DataFrame(
        {
            "sumsquare_error": self._fitted_errors,
            "aic": self._aic,
            "bic": self._bic,
            "kl_div": self._kldiv,
            "ks_statistic": self._ks_stat,
            "ks_pvalue": self._ks_pval,
        }
    )

I want to change it and remove the progress bar. However, I cannot change this file, it is only for reading. How could I modify it?

Asked By: Jesus M.

||

Answers:

If you want to modify the fit function in the fitter module but cannot change the original file, you can subclass the Fitter class and override the fit function with your own implementation.

from fitter import Fitter

class MyFitter(Fitter):
    def fit(self, progress=False, n_jobs=-1, max_workers=-1):
        import warnings
        warnings.filterwarnings("ignore", category=RuntimeWarning)
        
        N = len(self.distributions)
        for dist in self.distributions:
            self._fit_single_distribution(dist)

        self.df_errors = pd.DataFrame(
            {
                "sumsquare_error": self._fitted_errors,
                "aic": self._aic,
                "bic": self._bic,
                "kl_div": self._kldiv,
                "ks_statistic": self._ks_stat,
                "ks_pvalue": self._ks_pval,
            }
        )

I defined a new class MyFitter that inherits from the Fitter class in the fitter module. I override the fit function with my own implementation that does not use the progress bar. You can then use this new class to perform fitting without the progress bar as follows:

my_fitter = MyFitter(data=my_data)
my_fitter.fit()
Answered By: Rohit Singh

Make sure the function is called in a context in which you patch tqdm_joblib to produce a contextlib.nullcontext instead.

import unitest.mock
import contextlib

null_context = contextlib.nullcontext()


with unittest.mock.patch('fitter.tqdm_joblib', return_value=null_context):
    # your code that invokes fit(...)

You can wrap this into a decorator that you can manually apply to fit make the patch automatically whenever it gets run.

from contextlib import contextmanager

@contextmanager
def disable_progress_bar(ContextDecorator):
     with unittest.mock.patch('fitter.tqdm_joblib', return_value=null_context):
         yield


fitter.fit = disable_progress_par(fitter.fit)
    
Answered By: chepner
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.