From 18ef31bdf5fc3de38b283ce13908e87e9ef7bbd4 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Fri, 16 Sep 2022 19:36:06 +0200 Subject: [PATCH 01/68] permutation importance --- examples/plot_model_card.py | 4 ++++ skops/card/_model_card.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/examples/plot_model_card.py b/examples/plot_model_card.py index 4acdfd1b..ce3fe6da 100644 --- a/examples/plot_model_card.py +++ b/examples/plot_model_card.py @@ -20,6 +20,7 @@ from sklearn.datasets import load_breast_cancer from sklearn.ensemble import HistGradientBoostingClassifier from sklearn.experimental import enable_halving_search_cv # noqa +from sklearn.inspection import permutation_importance from sklearn.metrics import ( ConfusionMatrixDisplay, accuracy_score, @@ -148,6 +149,9 @@ disp.figure_.savefig(Path(local_repo) / "confusion_matrix.png") model_card.add_plot(**{"Confusion matrix": "confusion_matrix.png"}) +result = permutation_importance(model, X_test, y_test, n_repeats=10) +model_card.add_feature_importances(result) + cv_results = model.cv_results_ clf_report = classification_report( y_test, y_pred, output_dict=True, target_names=["malignant", "benign"] diff --git a/skops/card/_model_card.py b/skops/card/_model_card.py index 5b97c4ef..e11aaf36 100644 --- a/skops/card/_model_card.py +++ b/skops/card/_model_card.py @@ -10,6 +10,8 @@ from reprlib import Repr from typing import Any, Optional, Union +import matplotlib.pyplot as plt +import pandas as pd from modelcards import CardData, ModelCard from sklearn.utils import estimator_html_repr from tabulate import tabulate # type: ignore @@ -366,6 +368,33 @@ def add_metrics(self, **kwargs: str) -> "Card": self._eval_results[metric] = value return self + def add_feature_importances(self, feature_importances) -> "Card": + """Visualize permutation importance. + + Parameters + ---------- + self : object + Card object. + feature_importances : sklearn.utils.Bunch + Output of sklearn.inspection.permutation_importance() + + Returns + ------- + self : object + Card object. + """ + + importances = pd.DataFrame( + feature_importances.importances.T, + columns=self.model.feature_names_in_, + ) + ax = importances.plot.box(vert=False, whis=10) + ax.set_title("Permutation Importances") + ax.set_xlabel("Decrease in accuracy score") + plt.savefig("feature_importances.png") + self.add_plot(**{"Feature Importances": "feature_importances.png"}) + return self + def _generate_card(self) -> ModelCard: """Generate the ModelCard object From 2ff7a5c0326e2b966e15b31c970b961b22edc6ac Mon Sep 17 00:00:00 2001 From: Merve Noyan Date: Thu, 29 Sep 2022 14:22:33 +0200 Subject: [PATCH 02/68] Update examples/plot_model_card.py Co-authored-by: Adrin Jalali --- examples/plot_model_card.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/plot_model_card.py b/examples/plot_model_card.py index ce3fe6da..07719fba 100644 --- a/examples/plot_model_card.py +++ b/examples/plot_model_card.py @@ -149,8 +149,8 @@ disp.figure_.savefig(Path(local_repo) / "confusion_matrix.png") model_card.add_plot(**{"Confusion matrix": "confusion_matrix.png"}) -result = permutation_importance(model, X_test, y_test, n_repeats=10) -model_card.add_feature_importances(result) +inportances = permutation_importance(model, X_test, y_test, n_repeats=10) +model_card.add_feature_importances(importances) cv_results = model.cv_results_ clf_report = classification_report( From 5b8d4c99f91aedafa81c2424f451ad4207923323 Mon Sep 17 00:00:00 2001 From: Merve Noyan Date: Mon, 7 Nov 2022 12:03:44 +0100 Subject: [PATCH 03/68] Update examples/plot_model_card.py Co-authored-by: Benjamin Bossan --- examples/plot_model_card.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/plot_model_card.py b/examples/plot_model_card.py index 07719fba..bc0f0465 100644 --- a/examples/plot_model_card.py +++ b/examples/plot_model_card.py @@ -149,7 +149,7 @@ disp.figure_.savefig(Path(local_repo) / "confusion_matrix.png") model_card.add_plot(**{"Confusion matrix": "confusion_matrix.png"}) -inportances = permutation_importance(model, X_test, y_test, n_repeats=10) +importances = permutation_importance(model, X_test, y_test, n_repeats=10) model_card.add_feature_importances(importances) cv_results = model.cv_results_ From e80359dd9afa7c5412c3490cc77a2392f9638662 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Mon, 7 Nov 2022 14:55:40 +0100 Subject: [PATCH 04/68] added test and got rid of pandas --- skops/card/_model_card.py | 20 ++++++++++---------- skops/card/tests/test_card.py | 10 ++++++++++ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/skops/card/_model_card.py b/skops/card/_model_card.py index c78825f2..c6cb247b 100644 --- a/skops/card/_model_card.py +++ b/skops/card/_model_card.py @@ -11,7 +11,6 @@ from typing import Any, Optional, Union import matplotlib.pyplot as plt -import pandas as pd from modelcards import CardData, ModelCard from sklearn.utils import estimator_html_repr from tabulate import tabulate # type: ignore @@ -375,29 +374,30 @@ def add_metrics(self, **kwargs: str) -> "Card": self._eval_results[metric] = value return self - def add_feature_importances(self, feature_importances) -> "Card": + def add_feature_importances(self, feature_importances, data) -> "Card": """Visualize permutation importance. Parameters ---------- - self : object - Card object. feature_importances : sklearn.utils.Bunch Output of sklearn.inspection.permutation_importance() + data : + Returns ------- self : object Card object. """ - - importances = pd.DataFrame( - feature_importances.importances.T, - columns=self.model.feature_names_in_, + sorted_importances_idx = feature_importances.importances_mean.argsort() + fig, ax = plt.subplots() + ax.boxplot( + x=feature_importances.importances[sorted_importances_idx].T, + labels=data.columns[sorted_importances_idx], + vert=False, ) - ax = importances.plot.box(vert=False, whis=10) ax.set_title("Permutation Importances") - ax.set_xlabel("Decrease in accuracy score") + ax.set_xlabel("Decrease in Accuracy Score") plt.savefig("feature_importances.png") self.add_plot(**{"Feature Importances": "feature_importances.png"}) return self diff --git a/skops/card/tests/test_card.py b/skops/card/tests/test_card.py index e2ed4596..f2ab84c3 100644 --- a/skops/card/tests/test_card.py +++ b/skops/card/tests/test_card.py @@ -10,6 +10,7 @@ import sklearn from huggingface_hub import CardData, metadata_load from sklearn.datasets import load_iris +from sklearn.inspection import permutation_importance from sklearn.linear_model import LinearRegression, LogisticRegression import skops @@ -169,6 +170,15 @@ def test_add_plot(destination_path, model_card): assert "![fig1](fig1.png)" in model_card +def test_feature_importances(iris_estimator, iris_data, model_card, destination_path): + X, y = iris_data + result = permutation_importance( + iris_estimator, X, y, n_repeats=10, random_state=42, n_jobs=2 + ) + model_card.add_feature_importances(result, X) + assert "![Feature Importances](feature_importances.png)" in model_card.render() + + def test_temporary_plot(destination_path, model_card): # test if the additions are made to a temporary template file # and not to default template or template provided From 4ef3549d7d5a31833d3fa7ccb0f03c92665c9c66 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Mon, 7 Nov 2022 15:21:35 +0100 Subject: [PATCH 05/68] change import --- skops/card/_model_card.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skops/card/_model_card.py b/skops/card/_model_card.py index c6cb247b..e3ec1bed 100644 --- a/skops/card/_model_card.py +++ b/skops/card/_model_card.py @@ -11,7 +11,7 @@ from typing import Any, Optional, Union import matplotlib.pyplot as plt -from modelcards import CardData, ModelCard +from huggingface_hub import CardData, ModelCard from sklearn.utils import estimator_html_repr from tabulate import tabulate # type: ignore From 133cc2e0ac0a82123dd6b3f17e9ca68d3b9497b5 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Mon, 7 Nov 2022 16:15:51 +0100 Subject: [PATCH 06/68] fixes --- skops/card/_model_card.py | 27 ++++++++++++++++++++------- skops/card/tests/test_card.py | 6 ++++-- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/skops/card/_model_card.py b/skops/card/_model_card.py index e3ec1bed..4e2121b1 100644 --- a/skops/card/_model_card.py +++ b/skops/card/_model_card.py @@ -374,15 +374,24 @@ def add_metrics(self, **kwargs: str) -> "Card": self._eval_results[metric] = value return self - def add_feature_importances(self, feature_importances, data) -> "Card": - """Visualize permutation importance. + def add_feature_importances( + self, feature_importances, columns, plot_file, plot_name + ) -> "Card": + """Plots feature importance and saves it to model card. Parameters ---------- feature_importances : sklearn.utils.Bunch Output of sklearn.inspection.permutation_importance() - data : + columns : + Column names of the data used to generate importances. + + plot_file : + Filename for the plot. + + plot_name : + Name of the plot. Returns ------- @@ -393,13 +402,17 @@ def add_feature_importances(self, feature_importances, data) -> "Card": fig, ax = plt.subplots() ax.boxplot( x=feature_importances.importances[sorted_importances_idx].T, - labels=data.columns[sorted_importances_idx], + labels=columns[sorted_importances_idx], vert=False, ) ax.set_title("Permutation Importances") - ax.set_xlabel("Decrease in Accuracy Score") - plt.savefig("feature_importances.png") - self.add_plot(**{"Feature Importances": "feature_importances.png"}) + ax.set_xlabel("Decrease in Score") + if plot_name is not None and plot_file is not None: + plt.savefig(plot_file) + self.add_plot(**{plot_name: plot_file}) + else: + plt.savefig("feature_importances.png") + self.add_plot(**{"Feature Importances": "feature_importances.png"}) return self def _generate_card(self) -> ModelCard: diff --git a/skops/card/tests/test_card.py b/skops/card/tests/test_card.py index f2ab84c3..56f416d3 100644 --- a/skops/card/tests/test_card.py +++ b/skops/card/tests/test_card.py @@ -175,8 +175,10 @@ def test_feature_importances(iris_estimator, iris_data, model_card, destination_ result = permutation_importance( iris_estimator, X, y, n_repeats=10, random_state=42, n_jobs=2 ) - model_card.add_feature_importances(result, X) - assert "![Feature Importances](feature_importances.png)" in model_card.render() + model_card.add_feature_importances( + result, X.columns, "importance.png", "Permutation Importance" + ) + assert "![Permutation Importance](importance.png)" in model_card.render() def test_temporary_plot(destination_path, model_card): From 1c448bcc3fe89fcb237008c6ec8ba048073176e9 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Mon, 7 Nov 2022 16:17:34 +0100 Subject: [PATCH 07/68] fixes --- skops/card/_model_card.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skops/card/_model_card.py b/skops/card/_model_card.py index 4e2121b1..696ea3f3 100644 --- a/skops/card/_model_card.py +++ b/skops/card/_model_card.py @@ -405,7 +405,7 @@ def add_feature_importances( labels=columns[sorted_importances_idx], vert=False, ) - ax.set_title("Permutation Importances") + ax.set_title(plot_name) ax.set_xlabel("Decrease in Score") if plot_name is not None and plot_file is not None: plt.savefig(plot_file) From 95ad03b2fbc0f98e75adf53255fa350a74236b8a Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Mon, 7 Nov 2022 16:20:30 +0100 Subject: [PATCH 08/68] updated docs & more --- skops/card/_model_card.py | 4 ++-- skops/card/tests/test_card.py | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/skops/card/_model_card.py b/skops/card/_model_card.py index 696ea3f3..0cb92558 100644 --- a/skops/card/_model_card.py +++ b/skops/card/_model_card.py @@ -374,10 +374,10 @@ def add_metrics(self, **kwargs: str) -> "Card": self._eval_results[metric] = value return self - def add_feature_importances( + def add_permutation_importances( self, feature_importances, columns, plot_file, plot_name ) -> "Card": - """Plots feature importance and saves it to model card. + """Plots permutation importance and saves it to model card. Parameters ---------- diff --git a/skops/card/tests/test_card.py b/skops/card/tests/test_card.py index 56f416d3..3457d5c0 100644 --- a/skops/card/tests/test_card.py +++ b/skops/card/tests/test_card.py @@ -170,12 +170,14 @@ def test_add_plot(destination_path, model_card): assert "![fig1](fig1.png)" in model_card -def test_feature_importances(iris_estimator, iris_data, model_card, destination_path): +def test_permutation_importances( + iris_estimator, iris_data, model_card, destination_path +): X, y = iris_data result = permutation_importance( iris_estimator, X, y, n_repeats=10, random_state=42, n_jobs=2 ) - model_card.add_feature_importances( + model_card.add_permutation_importances( result, X.columns, "importance.png", "Permutation Importance" ) assert "![Permutation Importance](importance.png)" in model_card.render() From 2bc714f1cc8a461107fd51adc7bde1abadec6655 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Mon, 7 Nov 2022 16:26:50 +0100 Subject: [PATCH 09/68] docs --- examples/plot_model_card.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/plot_model_card.py b/examples/plot_model_card.py index bc0f0465..bcd52ec6 100644 --- a/examples/plot_model_card.py +++ b/examples/plot_model_card.py @@ -150,7 +150,9 @@ model_card.add_plot(**{"Confusion matrix": "confusion_matrix.png"}) importances = permutation_importance(model, X_test, y_test, n_repeats=10) -model_card.add_feature_importances(importances) +model_card.add_permutation_importances( + importances, X_test.columns, "importance.png", "Permutation Importance" +) cv_results = model.cv_results_ clf_report = classification_report( From b457fb94a07bcf08e21f76d91e75507bb9c9a9e7 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Tue, 8 Nov 2022 12:14:17 +0100 Subject: [PATCH 10/68] added another test, updated docs, will add to model card rst --- examples/feature_importances.png | Bin 0 -> 55029 bytes examples/importance.png | Bin 0 -> 53328 bytes examples/plot_model_card.py | 5 ++++- skops/card/_model_card.py | 21 +++++++++++---------- skops/card/tests/test_card.py | 27 +++++++++++++++++++++++++++ 5 files changed, 42 insertions(+), 11 deletions(-) create mode 100644 examples/feature_importances.png create mode 100644 examples/importance.png diff --git a/examples/feature_importances.png b/examples/feature_importances.png new file mode 100644 index 0000000000000000000000000000000000000000..c40ea926fef9ab60acf8b95b412334c19864e0b1 GIT binary patch literal 55029 zcmd?Rhd_}B6%l16$}B6{6-vWQQVL}?>`@ZZkg{cj z?CkhGkIw75ulxJ`-uGYddpxe|ah|90`Mk$*yk5`sI)eA_+r`Sn&qPra>u#Ox2Puly zm!fFe8R_v8r4P+N@Q=;sb{sip;9z~u&D`0F(lbBjXzy^&-qu3oyp^+yt;1P`4N4m} zN{iT>JLl-4Dl2>Dzy87o2j^3=>y?Ff;6s)<>Kt{UD0Xx5f0{In2euUT#bWpNZHL_N z47OY_dEd0iFk<9-Z1`8qLCO0EZLg-;Tkf8;kUknHx}sF%EobR-GewD}saqR)Ya+Yt zgm0_~Gf&&L_VaVTFlm`Rb6blvW?Sm=U3KrLT+|Sbm`n3e@4Ztu=kmxyzju7*P9BS8 z=p_yEK5k4K?*tB>B^nTZuFx$G?7q)$vtWEEt><2;RLkU|p> z7^t;#XP}3Kq-5gpm**Yb+^WWV>jYF^83%`j1;ob-U%P(YuBA#}$w&U+Dz@vR7)6WI4Ii1=+lOAhOxyhG0@oI|q4ENk z-jR_G?X{K8ArHo#i(bf@{{ew&Hl+(`va>ht3||%8_|#N)LPkuCPD7)JDT|+vk32KY zCdps2Mf03g{Zmtop-;Kf&$}KPJQ%6qG1b)9XU8SV$;+4Ye|~hp*m%7Y%c;71JNE2h zYCNHK{YaCNuhG*J0e9~TPJ60<`uthm`G=00_xzEhaJ-+BCr?I3Mp8ybMrn^8Y3u2+ z8a&unfrs_zw@cLd!LmSB?d{u_yg2uh7Wa7M=uxLC0d8)3DJd!P!d-f6^L-Wzw|k7* zb{8!!2(YoSwU5u#fBaa6S6Iw@J?(aEY|xGn?vmnSid>+I$}TfAvw({mH*O>gB~d%5 zzR=4A5+Vr;nz4XL{p(N^#R?zUKy9yT)mpb2`BGV`|6eM@GUE z{6cE(94#+g{jOeRGJbAzN!@F`F6@THFYi3{@tOdLZ!{q }j1r08`2qo;DV4dQ)$eU9JR1XcZ$l2+H;R$+f? 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

_Tz2yBs5DBuQYmMa_RA7X@Wulq!GRpQB=I~ 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

l?f(z@#0^ro2u(> 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 !siW!5lZQ{9+(VQtodEE2XN#)F zsq=74_oB(SnqqWKa}xK__xSszj73>RPBw)FE6(5Y}GCv+g^nVd6c5qgL~!E z8c?oIoKKYT`JFL~{r$yJK+ne#n%~ERp%BaqTMdux>>4ULAQ`>3YU?qSEvb)88j+F zPe2lZ7nLll1(=xk{gB|;@pK;Cn)T38g$XBkJ3yCD4c0$SU_}@j2&Y*V0&=XZ6jZF- zssUng1O*OasYq-@lc)I7NokJ(28U7>4&r}N$lsWTFI;-#7?d&q+BUXBKLETELj=wN z6@fmtQHThG2cP+@{%WW5OYF_M8jqz*mS@EEA7&$mKoA*mO2$G&Wo()^VbMyS4H)0W zARJG);rIEo6Y{Az8hRFVB&E?X)^P#AtpePouuYN39s>44{~6!9#c@ZBH)`dLZ?5VVaYbBdS>U7JM-<&?3T!uLgY4i**#W)`0iTFVKzh|)wR4Mw<2FrCPI4gTz_RHowuGag8F)8q2d zZ>VWZ#_NAy@MK+h_zm!T4UrSU-3sR8b>|J&u7!l?6N9h-4W_O?#VrU!pw3>@L;4MK z?>N}dE2m6k{crQqf(OLgG%9KItid3RVN6oOzzZtg2p1Clb(rP3t8Z;vqf(tkD80T3 zJJG9bjk`ud&`<-)?pa!xhn20y3#pBd9?ACdiLi^#t13>Ywog;p-D}simktwXhIwP0 z=mR;F<9hY##j@Gaw++zzHR#gKoH*6g0iQOU;L-MFRTp)Rk0DyCZ)vY6uyw6zdP`>WY>X#Fb@jruV@t@x*x((@ZxCwoDeX%4bBB z-aj?^{1r7Co1%NJ9e;Ky6<+GM*vKWZ%&CslB(1{Jof$66fS_&Xu`>#g3G1MQeO}%l z>=hzwva=or1M=fS44H1`ty4zqn%?_)k6XB*0bwSu{CuW`kg?;v@n5iLfp7iaUv&2h YZRwx5eC3E43Vwa)GkZq1ci^^v0<@y?IsgCw literal 0 HcmV?d00001 diff --git a/examples/importance.png b/examples/importance.png new file mode 100644 index 0000000000000000000000000000000000000000..f3304a62fc26888d8a5ac184abdaa7d1b17612b7 GIT binary patch literal 53328 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 "Card": return self def add_permutation_importances( - self, feature_importances, columns, plot_file, plot_name + self, + permutation_importances, + columns, + plot_file="permutation_importances.png", + plot_name="Permutation Importances", ) -> "Card": """Plots permutation importance and saves it to model card. Parameters ---------- - feature_importances : sklearn.utils.Bunch + permutation_importances : sklearn.utils.Bunch Output of sklearn.inspection.permutation_importance() columns : @@ -398,21 +402,18 @@ def add_permutation_importances( self : object Card object. """ - sorted_importances_idx = feature_importances.importances_mean.argsort() + sorted_importances_idx = permutation_importances.importances_mean.argsort() fig, ax = plt.subplots() ax.boxplot( - x=feature_importances.importances[sorted_importances_idx].T, + x=permutation_importances.importances[sorted_importances_idx].T, labels=columns[sorted_importances_idx], vert=False, ) ax.set_title(plot_name) ax.set_xlabel("Decrease in Score") - if plot_name is not None and plot_file is not None: - plt.savefig(plot_file) - self.add_plot(**{plot_name: plot_file}) - else: - plt.savefig("feature_importances.png") - self.add_plot(**{"Feature Importances": "feature_importances.png"}) + plt.savefig(plot_file) + self.add_plot(**{plot_name: plot_file}) + return self def _generate_card(self) -> ModelCard: diff --git a/skops/card/tests/test_card.py b/skops/card/tests/test_card.py index 3457d5c0..cdc7089d 100644 --- a/skops/card/tests/test_card.py +++ b/skops/card/tests/test_card.py @@ -12,6 +12,7 @@ from sklearn.datasets import load_iris from sklearn.inspection import permutation_importance from sklearn.linear_model import LinearRegression, LogisticRegression +from sklearn.metrics import f1_score, make_scorer import skops from skops import hub_utils @@ -183,6 +184,32 @@ def test_permutation_importances( assert "![Permutation Importance](importance.png)" in model_card.render() +def test_multiple_permutation_importances( + iris_estimator, iris_data, model_card, destination_path +): + X, y = iris_data + result = permutation_importance( + iris_estimator, X, y, n_repeats=10, random_state=42, n_jobs=2 + ) + model_card.add_permutation_importances(result, X.columns) + f1 = make_scorer(f1_score, average="micro") + result = permutation_importance( + iris_estimator, X, y, scoring=f1, n_repeats=10, random_state=42, n_jobs=2 + ) + model_card.add_permutation_importances( + result, + X.columns, + plot_file="f1_importance.png", + plot_name="Permutation Importance on f1", + ) + # check for default one + assert ( + "![Permutation Importances](permutation_importances.png)" in model_card.render() + ) + # check for F1 + assert "![Permutation Importance on f1](f1_importance.png)" in model_card.render() + + def test_temporary_plot(destination_path, model_card): # test if the additions are made to a temporary template file # and not to default template or template provided From 7228e8389a7524e50c34ee0eb771c05f905114f2 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Tue, 8 Nov 2022 17:08:11 +0100 Subject: [PATCH 11/68] removed unnecessary files --- examples/feature_importances.png | Bin 55029 -> 0 bytes examples/importance.png | Bin 53328 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 examples/feature_importances.png delete mode 100644 examples/importance.png diff --git a/examples/feature_importances.png b/examples/feature_importances.png deleted file mode 100644 index c40ea926fef9ab60acf8b95b412334c19864e0b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55029 zcmd?Rhd_}B6%l16$}B6{6-vWQQVL}?>`@ZZkg{cj z?CkhGkIw75ulxJ`-uGYddpxe|ah|90`Mk$*yk5`sI)eA_+r`Sn&qPra>u#Ox2Puly zm!fFe8R_v8r4P+N@Q=;sb{sip;9z~u&D`0F(lbBjXzy^&-qu3oyp^+yt;1P`4N4m} zN{iT>JLl-4Dl2>Dzy87o2j^3=>y?Ff;6s)<>Kt{UD0Xx5f0{In2euUT#bWpNZHL_N z47OY_dEd0iFk<9-Z1`8qLCO0EZLg-;Tkf8;kUknHx}sF%EobR-GewD}saqR)Ya+Yt zgm0_~Gf&&L_VaVTFlm`Rb6blvW?Sm=U3KrLT+|Sbm`n3e@4Ztu=kmxyzju7*P9BS8 z=p_yEK5k4K?*tB>B^nTZuFx$G?7q)$vtWEEt><2;RLkU|p> z7^t;#XP}3Kq-5gpm**Yb+^WWV>jYF^83%`j1;ob-U%P(YuBA#}$w&U+Dz@vR7)6WI4Ii1=+lOAhOxyhG0@oI|q4ENk z-jR_G?X{K8ArHo#i(bf@{{ew&Hl+(`va>ht3||%8_|#N)LPkuCPD7)JDT|+vk32KY zCdps2Mf03g{Zmtop-;Kf&$}KPJQ%6qG1b)9XU8SV$;+4Ye|~hp*m%7Y%c;71JNE2h zYCNHK{YaCNuhG*J0e9~TPJ60<`uthm`G=00_xzEhaJ-+BCr?I3Mp8ybMrn^8Y3u2+ z8a&unfrs_zw@cLd!LmSB?d{u_yg2uh7Wa7M=uxLC0d8)3DJd!P!d-f6^L-Wzw|k7* zb{8!!2(YoSwU5u#fBaa6S6Iw@J?(aEY|xGn?vmnSid>+I$}TfAvw({mH*O>gB~d%5 zzR=4A5+Vr;nz4XL{p(N^#R?zUKy9yT)mpb2`BGV`|6eM@GUE z{6cE(94#+g{jOeRGJbAzN!@F`F6@THFYi3{@tOdLZ!{q }j1r08`2qo;DV4dQ)$eU9JR1XcZ$l2+H;R$+f? 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

_Tz2yBs5DBuQYmMa_RA7X@Wulq!GRpQB=I~ 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

l?f(z@#0^ro2u(> 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 !siW!5lZQ{9+(VQtodEE2XN#)F zsq=74_oB(SnqqWKa}xK__xSszj73>RPBw)FE6(5Y}GCv+g^nVd6c5qgL~!E z8c?oIoKKYT`JFL~{r$yJK+ne#n%~ERp%BaqTMdux>>4ULAQ`>3YU?qSEvb)88j+F zPe2lZ7nLll1(=xk{gB|;@pK;Cn)T38g$XBkJ3yCD4c0$SU_}@j2&Y*V0&=XZ6jZF- zssUng1O*OasYq-@lc)I7NokJ(28U7>4&r}N$lsWTFI;-#7?d&q+BUXBKLETELj=wN z6@fmtQHThG2cP+@{%WW5OYF_M8jqz*mS@EEA7&$mKoA*mO2$G&Wo()^VbMyS4H)0W zARJG);rIEo6Y{Az8hRFVB&E?X)^P#AtpePouuYN39s>44{~6!9#c@ZBH)`dLZ?5VVaYbBdS>U7JM-<&?3T!uLgY4i**#W)`0iTFVKzh|)wR4Mw<2FrCPI4gTz_RHowuGag8F)8q2d zZ>VWZ#_NAy@MK+h_zm!T4UrSU-3sR8b>|J&u7!l?6N9h-4W_O?#VrU!pw3>@L;4MK z?>N}dE2m6k{crQqf(OLgG%9KItid3RVN6oOzzZtg2p1Clb(rP3t8Z;vqf(tkD80T3 zJJG9bjk`ud&`<-)?pa!xhn20y3#pBd9?ACdiLi^#t13>Ywog;p-D}simktwXhIwP0 z=mR;F<9hY##j@Gaw++zzHR#gKoH*6g0iQOU;L-MFRTp)Rk0DyCZ)vY6uyw6zdP`>WY>X#Fb@jruV@t@x*x((@ZxCwoDeX%4bBB z-aj?^{1r7Co1%NJ9e;Ky6<+GM*vKWZ%&CslB(1{Jof$66fS_&Xu`>#g3G1MQeO}%l z>=hzwva=or1M=fS44H1`ty4zqn%?_)k6XB*0bwSu{CuW`kg?;v@n5iLfp7iaUv&2h YZRwx5eC3E43Vwa)GkZq1ci^^v0<@y?IsgCw diff --git a/examples/importance.png b/examples/importance.png deleted file mode 100644 index f3304a62fc26888d8a5ac184abdaa7d1b17612b7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53328 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 Date: Tue, 8 Nov 2022 17:11:42 +0100 Subject: [PATCH 12/68] added importance to model card guide --- docs/model_card.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/model_card.rst b/docs/model_card.rst index c1fe0fac..5f15d1c9 100644 --- a/docs/model_card.rst +++ b/docs/model_card.rst @@ -75,7 +75,10 @@ plots, save them on disk and then add them to the card by passing the path name to the :meth:`.Card.add_plot` method. For tables, you can pass either dictionaries with the key being the header and the values being list of row entries, or a pandas ``DataFrame``; use the :meth:`.Card.add_table` method for -this. +this. If you would like to add permutation importance results, you can pass +your importances to :meth:`.Card.add_permutation_importances`. If you want to +have multiple importance plots, you should pass a file name and a title for the +plot. This will create a boxplot and write it to the model card for you. To see how you can use the API in ``skops`` to create a model card, please refer to :ref:`sphx_glr_auto_examples_plot_model_card.py`. From 48c656d69d7c60387f252b606c431850a4d18e6b Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Tue, 8 Nov 2022 17:28:38 +0100 Subject: [PATCH 13/68] moved filepaths to tempfile --- skops/card/tests/test_card.py | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/skops/card/tests/test_card.py b/skops/card/tests/test_card.py index cdc7089d..6f34fb0d 100644 --- a/skops/card/tests/test_card.py +++ b/skops/card/tests/test_card.py @@ -178,10 +178,17 @@ def test_permutation_importances( result = permutation_importance( iris_estimator, X, y, n_repeats=10, random_state=42, n_jobs=2 ) + model_card.add_permutation_importances( - result, X.columns, "importance.png", "Permutation Importance" + result, + X.columns, + Path(destination_path) / "importance.png", + "Permutation Importance", + ) + assert ( + f"![Permutation Importance]({destination_path}/importance.png)" + in model_card.render() ) - assert "![Permutation Importance](importance.png)" in model_card.render() def test_multiple_permutation_importances( @@ -191,7 +198,9 @@ def test_multiple_permutation_importances( result = permutation_importance( iris_estimator, X, y, n_repeats=10, random_state=42, n_jobs=2 ) - model_card.add_permutation_importances(result, X.columns) + model_card.add_permutation_importances( + result, X.columns, plot_file=(Path(destination_path) / "importance.png") + ) f1 = make_scorer(f1_score, average="micro") result = permutation_importance( iris_estimator, X, y, scoring=f1, n_repeats=10, random_state=42, n_jobs=2 @@ -199,15 +208,19 @@ def test_multiple_permutation_importances( model_card.add_permutation_importances( result, X.columns, - plot_file="f1_importance.png", + plot_file=Path(destination_path) / "f1_importance.png", plot_name="Permutation Importance on f1", ) # check for default one assert ( - "![Permutation Importances](permutation_importances.png)" in model_card.render() + f"![Permutation Importances]({Path(destination_path)}/importance.png)" + in model_card.render() ) # check for F1 - assert "![Permutation Importance on f1](f1_importance.png)" in model_card.render() + assert ( + f"![Permutation Importance on f1]({Path(destination_path)}/f1_importance.png)" + in model_card.render() + ) def test_temporary_plot(destination_path, model_card): From a5140604e9109e882d272425d770c0a0816e4c6a Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Tue, 8 Nov 2022 17:32:29 +0100 Subject: [PATCH 14/68] moved filepaths to tempfile --- examples/plot_model_card.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/plot_model_card.py b/examples/plot_model_card.py index e25c15fc..643cdf98 100644 --- a/examples/plot_model_card.py +++ b/examples/plot_model_card.py @@ -153,7 +153,7 @@ model_card.add_permutation_importances( importances, X_test.columns, - plot_file="importance.png", + plot_file=Path(local_repo) / "importance.png", plot_name="Permutation Importance", ) From ac699c57175a2655fa565fbc355fc325bd851389 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Tue, 8 Nov 2022 18:08:03 +0100 Subject: [PATCH 15/68] test windows fix --- skops/card/tests/test_card.py | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/skops/card/tests/test_card.py b/skops/card/tests/test_card.py index 6f34fb0d..60f2aa4c 100644 --- a/skops/card/tests/test_card.py +++ b/skops/card/tests/test_card.py @@ -185,10 +185,8 @@ def test_permutation_importances( Path(destination_path) / "importance.png", "Permutation Importance", ) - assert ( - f"![Permutation Importance]({destination_path}/importance.png)" - in model_card.render() - ) + temp_path = Path(destination_path) / "importance.png" + assert f"![Permutation Importance]({temp_path}" in model_card.render() def test_multiple_permutation_importances( @@ -212,15 +210,11 @@ def test_multiple_permutation_importances( plot_name="Permutation Importance on f1", ) # check for default one - assert ( - f"![Permutation Importances]({Path(destination_path)}/importance.png)" - in model_card.render() - ) + temp_path = Path(destination_path) / "importance.png" + assert f"![Permutation Importances]({temp_path}" in model_card.render() # check for F1 - assert ( - f"![Permutation Importance on f1]({Path(destination_path)}/f1_importance.png)" - in model_card.render() - ) + temp_path_f1 = Path(destination_path) / "f1_importance.png" + assert f"![Permutation Importance on f1]({temp_path_f1}" in model_card.render() def test_temporary_plot(destination_path, model_card): From 76e5b0ed8ffbc8b9b9cc5a801da338945b2a2136 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Tue, 8 Nov 2022 20:02:19 +0100 Subject: [PATCH 16/68] added types --- skops/card/_model_card.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/skops/card/_model_card.py b/skops/card/_model_card.py index de77ccfd..35469b51 100644 --- a/skops/card/_model_card.py +++ b/skops/card/_model_card.py @@ -388,13 +388,13 @@ def add_permutation_importances( permutation_importances : sklearn.utils.Bunch Output of sklearn.inspection.permutation_importance() - columns : + columns : Index Column names of the data used to generate importances. - plot_file : + plot_file : str Filename for the plot. - plot_name : + plot_name : str, or Path Name of the plot. Returns From baccd1b3deb51b7a10fcce5473abf540676f7c27 Mon Sep 17 00:00:00 2001 From: Merve Noyan Date: Wed, 9 Nov 2022 17:28:31 +0100 Subject: [PATCH 17/68] Update skops/card/_model_card.py Co-authored-by: Benjamin Bossan --- skops/card/_model_card.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skops/card/_model_card.py b/skops/card/_model_card.py index 35469b51..82f68c49 100644 --- a/skops/card/_model_card.py +++ b/skops/card/_model_card.py @@ -386,7 +386,7 @@ def add_permutation_importances( Parameters ---------- permutation_importances : sklearn.utils.Bunch - Output of sklearn.inspection.permutation_importance() + Output of :func:`sklearn.inspection.permutation_importance`. columns : Index Column names of the data used to generate importances. From d3d0c1ca1d02243a42a5778ab5b3e7b70a0441fd Mon Sep 17 00:00:00 2001 From: Merve Noyan Date: Wed, 9 Nov 2022 17:28:52 +0100 Subject: [PATCH 18/68] Update skops/card/_model_card.py Co-authored-by: Benjamin Bossan --- skops/card/_model_card.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skops/card/_model_card.py b/skops/card/_model_card.py index 82f68c49..c45b8fcb 100644 --- a/skops/card/_model_card.py +++ b/skops/card/_model_card.py @@ -403,7 +403,7 @@ def add_permutation_importances( Card object. """ sorted_importances_idx = permutation_importances.importances_mean.argsort() - fig, ax = plt.subplots() + _, ax = plt.subplots() ax.boxplot( x=permutation_importances.importances[sorted_importances_idx].T, labels=columns[sorted_importances_idx], From 2489693dab74c492427b0b141f542e4d2cef6ce9 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Thu, 10 Nov 2022 17:35:52 +0100 Subject: [PATCH 19/68] added matplotlib mock and mock test --- skops/card/_model_card.py | 11 ++++++++++- skops/card/tests/test_card.py | 20 ++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/skops/card/_model_card.py b/skops/card/_model_card.py index c45b8fcb..2a96c635 100644 --- a/skops/card/_model_card.py +++ b/skops/card/_model_card.py @@ -10,12 +10,12 @@ from reprlib import Repr from typing import Any, Optional, Union -import matplotlib.pyplot as plt from huggingface_hub import CardData, ModelCard from sklearn.utils import estimator_html_repr from tabulate import tabulate # type: ignore import skops +from skops.utils.fixes import metadata # Repr attributes can be used to control the behavior of repr aRepr = Repr() @@ -402,6 +402,15 @@ def add_permutation_importances( self : object Card object. """ + try: + metadata.version("matplotlib") + except metadata.PackageNotFoundError: + raise ModuleNotFoundError( + "This feature requires matplotlib to be installed." + ) + + import matplotlib.pyplot as plt + sorted_importances_idx = permutation_importances.importances_mean.argsort() _, ax = plt.subplots() ax.boxplot( diff --git a/skops/card/tests/test_card.py b/skops/card/tests/test_card.py index 60f2aa4c..d05eae0b 100644 --- a/skops/card/tests/test_card.py +++ b/skops/card/tests/test_card.py @@ -1,8 +1,10 @@ import copy import os import pickle +import sys import tempfile from pathlib import Path +from unittest import mock import matplotlib.pyplot as plt import numpy as np @@ -189,6 +191,24 @@ def test_permutation_importances( assert f"![Permutation Importance]({temp_path}" in model_card.render() +def test_matplotlib_dependency_error( + iris_estimator, iris_data, model_card, destination_path +): + with mock.patch.dict(sys.modules): + sys.modules["matplotlib"] = None + X, y = iris_data + result = permutation_importance( + iris_estimator, X, y, n_repeats=10, random_state=42, n_jobs=2 + ) + with pytest.raises(ModuleNotFoundError): + model_card.add_permutation_importances( + result, + X.columns, + Path(destination_path) / "importance.png", + "Permutation Importance", + ) + + def test_multiple_permutation_importances( iris_estimator, iris_data, model_card, destination_path ): From a7ba7189218f07ad93349d5a2cb7b381d7d0b4c0 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Thu, 17 Nov 2022 15:01:33 +0100 Subject: [PATCH 20/68] fixed test --- skops/card/tests/test_card.py | 39 ++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/skops/card/tests/test_card.py b/skops/card/tests/test_card.py index d05eae0b..3bd79e1f 100644 --- a/skops/card/tests/test_card.py +++ b/skops/card/tests/test_card.py @@ -1,7 +1,6 @@ import copy import os import pickle -import sys import tempfile from pathlib import Path from unittest import mock @@ -194,19 +193,31 @@ def test_permutation_importances( def test_matplotlib_dependency_error( iris_estimator, iris_data, model_card, destination_path ): - with mock.patch.dict(sys.modules): - sys.modules["matplotlib"] = None - X, y = iris_data - result = permutation_importance( - iris_estimator, X, y, n_repeats=10, random_state=42, n_jobs=2 - ) - with pytest.raises(ModuleNotFoundError): - model_card.add_permutation_importances( - result, - X.columns, - Path(destination_path) / "importance.png", - "Permutation Importance", - ) + orig_import = __import__ + + def mock_import(name, *args): + if name == "matplotlib.pyplot": + pass + else: + return orig_import(name, *args) + + X, y = iris_data + result = permutation_importance( + iris_estimator, X, y, n_repeats=10, random_state=42, n_jobs=2 + ) + + with mock.patch("builtins.__import__", side_effect=mock_import): + with pytest.raises(ImportError, match="cannot import name*"): + with pytest.raises( + ModuleNotFoundError, + match="This feature requires matplotlib to be installed.", + ): + model_card.add_permutation_importances( + result, + X.columns, + Path(destination_path) / "importance.png", + "Permutation Importance", + ) def test_multiple_permutation_importances( From 1735a01410f60c954c50fa64e9accaf2a4643cec Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Thu, 17 Nov 2022 16:26:25 +0100 Subject: [PATCH 21/68] forgot to commit this lol --- skops/card/_model_card.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/skops/card/_model_card.py b/skops/card/_model_card.py index 2a96c635..2b639b36 100644 --- a/skops/card/_model_card.py +++ b/skops/card/_model_card.py @@ -403,14 +403,12 @@ def add_permutation_importances( Card object. """ try: - metadata.version("matplotlib") + import matplotlib.pyplot as plt except metadata.PackageNotFoundError: raise ModuleNotFoundError( "This feature requires matplotlib to be installed." ) - import matplotlib.pyplot as plt - sorted_importances_idx = permutation_importances.importances_mean.argsort() _, ax = plt.subplots() ax.boxplot( From 8dd9692ea5081b3e81433bd31dbadacb923fe052 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Thu, 17 Nov 2022 16:27:09 +0100 Subject: [PATCH 22/68] change type --- skops/card/_model_card.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skops/card/_model_card.py b/skops/card/_model_card.py index 2b639b36..5adf5e0f 100644 --- a/skops/card/_model_card.py +++ b/skops/card/_model_card.py @@ -388,7 +388,7 @@ def add_permutation_importances( permutation_importances : sklearn.utils.Bunch Output of :func:`sklearn.inspection.permutation_importance`. - columns : Index + columns : str, list or pandas.Index Column names of the data used to generate importances. plot_file : str From 510d41b8bfb393c4d136b486c72b5ee620a401f6 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Tue, 22 Nov 2022 18:17:39 +0300 Subject: [PATCH 23/68] added error and tests --- skops/card/_model_card.py | 10 +++++++- skops/card/tests/test_card.py | 44 +++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/skops/card/_model_card.py b/skops/card/_model_card.py index 5adf5e0f..9feb5561 100644 --- a/skops/card/_model_card.py +++ b/skops/card/_model_card.py @@ -380,6 +380,7 @@ def add_permutation_importances( columns, plot_file="permutation_importances.png", plot_name="Permutation Importances", + overwrite=False, ) -> "Card": """Plots permutation importance and saves it to model card. @@ -397,6 +398,9 @@ def add_permutation_importances( plot_name : str, or Path Name of the plot. + overwrite : bool + Whether to overwrite the permutation importance plot, if exists. + Returns ------- self : object @@ -408,7 +412,11 @@ def add_permutation_importances( raise ModuleNotFoundError( "This feature requires matplotlib to be installed." ) - + if str(plot_file) in self.render() and overwrite is False: + raise ValueError( + f"{str(plot_file)} already exists. Set `overwrite` to `True` or pass a" + " different filename for the plot." + ) sorted_importances_idx = permutation_importances.importances_mean.argsort() _, ax = plt.subplots() ax.boxplot( diff --git a/skops/card/tests/test_card.py b/skops/card/tests/test_card.py index 3bd79e1f..7eba5ed5 100644 --- a/skops/card/tests/test_card.py +++ b/skops/card/tests/test_card.py @@ -248,6 +248,50 @@ def test_multiple_permutation_importances( assert f"![Permutation Importance on f1]({temp_path_f1}" in model_card.render() +def test_duplicate_permutation_importances( + iris_estimator, iris_data, model_card, destination_path +): + X, y = iris_data + result = permutation_importance( + iris_estimator, X, y, n_repeats=10, random_state=42, n_jobs=2 + ) + plot_path = Path(destination_path) / "importance.png" + model_card.add_permutation_importances(result, X.columns, plot_file=plot_path) + with pytest.raises( + ValueError, + match=( + f"{str(plot_path)} already exists. Set `overwrite` to `True` or pass a" + " different filename for the plot." + ), + ): + model_card.add_permutation_importances( + result, + X.columns, + plot_file=plot_path, + plot_name="Permutation Importance on f1", + ) + + +def test_duplicate_permutation_importances_overwrite( + iris_estimator, iris_data, model_card, destination_path +): + X, y = iris_data + result = permutation_importance( + iris_estimator, X, y, n_repeats=10, random_state=42, n_jobs=2 + ) + plot_path = Path(destination_path) / "importance.png" + model_card.add_permutation_importances(result, X.columns, plot_file=plot_path) + + model_card.add_permutation_importances( + result, + X.columns, + plot_file=plot_path, + plot_name="Permutation Importance on f1", + overwrite=True, + ) + assert f"![Permutation Importance on f1]({plot_path}" in model_card.render() + + def test_temporary_plot(destination_path, model_card): # test if the additions are made to a temporary template file # and not to default template or template provided From 97ebde99224a2a9227800ea6e1f23e1171b56c37 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Tue, 22 Nov 2022 18:30:45 +0300 Subject: [PATCH 24/68] fix for windows tests --- skops/card/tests/test_card.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skops/card/tests/test_card.py b/skops/card/tests/test_card.py index 7eba5ed5..82b05a9e 100644 --- a/skops/card/tests/test_card.py +++ b/skops/card/tests/test_card.py @@ -260,7 +260,7 @@ def test_duplicate_permutation_importances( with pytest.raises( ValueError, match=( - f"{str(plot_path)} already exists. Set `overwrite` to `True` or pass a" + f"{plot_path} already exists. Set `overwrite` to `True` or pass a" " different filename for the plot." ), ): From dd6e7aa23e7df9bd3ca5f9e5ea4a69951aedea44 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Tue, 22 Nov 2022 18:48:38 +0300 Subject: [PATCH 25/68] fix for windows tests --- skops/card/tests/test_card.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skops/card/tests/test_card.py b/skops/card/tests/test_card.py index 82b05a9e..9faba29a 100644 --- a/skops/card/tests/test_card.py +++ b/skops/card/tests/test_card.py @@ -260,7 +260,7 @@ def test_duplicate_permutation_importances( with pytest.raises( ValueError, match=( - f"{plot_path} already exists. Set `overwrite` to `True` or pass a" + rf"{plot_path} already exists. Set `overwrite` to `True` or pass a" " different filename for the plot." ), ): From fcc16dd1822666f6d537bed1d1862a1ebe773171 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Tue, 22 Nov 2022 21:44:29 +0300 Subject: [PATCH 26/68] fix for windows tests --- skops/card/tests/test_card.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/skops/card/tests/test_card.py b/skops/card/tests/test_card.py index 9faba29a..14143798 100644 --- a/skops/card/tests/test_card.py +++ b/skops/card/tests/test_card.py @@ -255,13 +255,15 @@ def test_duplicate_permutation_importances( result = permutation_importance( iris_estimator, X, y, n_repeats=10, random_state=42, n_jobs=2 ) - plot_path = Path(destination_path) / "importance.png" + plot_path = os.path.join(destination_path, "importance.png") model_card.add_permutation_importances(result, X.columns, plot_file=plot_path) with pytest.raises( ValueError, match=( - rf"{plot_path} already exists. Set `overwrite` to `True` or pass a" - " different filename for the plot." + ( + rf"{plot_path} already exists. Set `overwrite` to `True` or pass a" + " different filename for the plot." + ) ), ): model_card.add_permutation_importances( @@ -279,7 +281,7 @@ def test_duplicate_permutation_importances_overwrite( result = permutation_importance( iris_estimator, X, y, n_repeats=10, random_state=42, n_jobs=2 ) - plot_path = Path(destination_path) / "importance.png" + plot_path = os.path.join(destination_path, "importance.png") model_card.add_permutation_importances(result, X.columns, plot_file=plot_path) model_card.add_permutation_importances( From 7fbaf89dc68c33baa547aa9dc474053c1ab72d6c Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Tue, 22 Nov 2022 21:49:08 +0300 Subject: [PATCH 27/68] fix for windows tests --- skops/card/tests/test_card.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/skops/card/tests/test_card.py b/skops/card/tests/test_card.py index 14143798..733f0f5f 100644 --- a/skops/card/tests/test_card.py +++ b/skops/card/tests/test_card.py @@ -260,10 +260,8 @@ def test_duplicate_permutation_importances( with pytest.raises( ValueError, match=( - ( - rf"{plot_path} already exists. Set `overwrite` to `True` or pass a" - " different filename for the plot." - ) + f"{plot_path} already exists. Set `overwrite` to `True` or pass a" + " different filename for the plot." ), ): model_card.add_permutation_importances( From a3435b83fa49e393352e6559aec7b6c258c2429b Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Wed, 23 Nov 2022 12:26:22 +0300 Subject: [PATCH 28/68] fix for windows tests --- skops/card/tests/test_card.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skops/card/tests/test_card.py b/skops/card/tests/test_card.py index 733f0f5f..2915b946 100644 --- a/skops/card/tests/test_card.py +++ b/skops/card/tests/test_card.py @@ -260,7 +260,7 @@ def test_duplicate_permutation_importances( with pytest.raises( ValueError, match=( - f"{plot_path} already exists. Set `overwrite` to `True` or pass a" + "already exists. Set `overwrite` to `True` or pass a" " different filename for the plot." ), ): From d0adddf64b6f9f146369b2e740806c0cb4355bdc Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Thu, 24 Nov 2022 14:53:42 +0300 Subject: [PATCH 29/68] swapped with path --- skops/card/_model_card.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/skops/card/_model_card.py b/skops/card/_model_card.py index 0ef9c295..6f4335ee 100644 --- a/skops/card/_model_card.py +++ b/skops/card/_model_card.py @@ -17,8 +17,8 @@ from tabulate import tabulate # type: ignore import skops -from skops.utils.fixes import metadata from skops.io import load +from skops.utils.fixes import metadata # Repr attributes can be used to control the behavior of repr aRepr = Repr() @@ -465,7 +465,7 @@ def add_permutation_importances( raise ModuleNotFoundError( "This feature requires matplotlib to be installed." ) - if str(plot_file) in self.render() and overwrite is False: + if Path(plot_file).exists() and overwrite is False: raise ValueError( f"{str(plot_file)} already exists. Set `overwrite` to `True` or pass a" " different filename for the plot." From 003544f237e696f138586a12121fc725681b2db0 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Tue, 29 Nov 2022 15:01:05 +0300 Subject: [PATCH 30/68] added import_or_raise --- skops/card/_model_card.py | 9 +++------ skops/utils/importutils.py | 22 ++++++++++++++++++++++ skops/utils/tests/test_importutils.py | 20 ++++++++++++++++++++ 3 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 skops/utils/importutils.py create mode 100644 skops/utils/tests/test_importutils.py diff --git a/skops/card/_model_card.py b/skops/card/_model_card.py index 6f4335ee..841c05c7 100644 --- a/skops/card/_model_card.py +++ b/skops/card/_model_card.py @@ -18,6 +18,7 @@ import skops from skops.io import load +from skops.utils.importutils import import_or_raise from skops.utils.fixes import metadata # Repr attributes can be used to control the behavior of repr @@ -459,12 +460,8 @@ def add_permutation_importances( self : object Card object. """ - try: - import matplotlib.pyplot as plt - except metadata.PackageNotFoundError: - raise ModuleNotFoundError( - "This feature requires matplotlib to be installed." - ) + import_or_raise("matplotlib") + import matplotlib.pyplot as plt if Path(plot_file).exists() and overwrite is False: raise ValueError( f"{str(plot_file)} already exists. Set `overwrite` to `True` or pass a" diff --git a/skops/utils/importutils.py b/skops/utils/importutils.py new file mode 100644 index 00000000..e5915656 --- /dev/null +++ b/skops/utils/importutils.py @@ -0,0 +1,22 @@ +from importlib import import_module +from skops.utils.fixes import metadata + +def import_or_raise(package): + """Raise error + + Parameters + ---------- + package: str + Name of the package. + + Raises + ------ + ModuleNotFoundError + Is raised if a given module is not present in the environment + """ + try: + import_module(package) + except metadata.PackageNotFoundError: + raise ModuleNotFoundError( + f"This feature requires {package} to be installed." + ) \ No newline at end of file diff --git a/skops/utils/tests/test_importutils.py b/skops/utils/tests/test_importutils.py new file mode 100644 index 00000000..3502e97b --- /dev/null +++ b/skops/utils/tests/test_importutils.py @@ -0,0 +1,20 @@ +import pytest +from unittest import mock +from skops.utils.importutils import import_or_raise + +def test_import_or_raise(): + orig_import = __import__ + + def mock_import(name, *args): + if name == "matplotlib": + pass + else: + return orig_import(name, *args) + + with mock.patch("builtins.__import__", side_effect=mock_import): + with pytest.raises(ImportError, match="cannot import name*"): + with pytest.raises( + ModuleNotFoundError, + match="This feature requires matplotlib to be installed.", + ): + import_or_raise("matplotlib") \ No newline at end of file From 1da474719cb40acd0a656632c484698fcfb5a273 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Tue, 29 Nov 2022 15:21:48 +0300 Subject: [PATCH 31/68] changed pre-commit config --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4068292e..247ca63a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,7 +12,7 @@ repos: rev: 22.6.0 hooks: - id: black -- repo: https://gitlab.com/pycqa/flake8 +- repo: https://github.com/pycqa/flake8 rev: 4.0.1 hooks: - id: flake8 From 280c6025b0146c2d8f5c2a410558d8d4a511bc50 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Tue, 29 Nov 2022 15:24:20 +0300 Subject: [PATCH 32/68] changed pre-commit config From 1521444f730e20d328c598fef393d07172464128 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Tue, 29 Nov 2022 15:26:42 +0300 Subject: [PATCH 33/68] black --- skops/card/_model_card.py | 2 +- skops/utils/importutils.py | 8 ++++---- skops/utils/tests/test_importutils.py | 7 +++++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/skops/card/_model_card.py b/skops/card/_model_card.py index 841c05c7..3226cbb1 100644 --- a/skops/card/_model_card.py +++ b/skops/card/_model_card.py @@ -19,7 +19,6 @@ import skops from skops.io import load from skops.utils.importutils import import_or_raise -from skops.utils.fixes import metadata # Repr attributes can be used to control the behavior of repr aRepr = Repr() @@ -462,6 +461,7 @@ def add_permutation_importances( """ import_or_raise("matplotlib") import matplotlib.pyplot as plt + if Path(plot_file).exists() and overwrite is False: raise ValueError( f"{str(plot_file)} already exists. Set `overwrite` to `True` or pass a" diff --git a/skops/utils/importutils.py b/skops/utils/importutils.py index e5915656..e842f8e9 100644 --- a/skops/utils/importutils.py +++ b/skops/utils/importutils.py @@ -1,8 +1,10 @@ from importlib import import_module + from skops.utils.fixes import metadata + def import_or_raise(package): - """Raise error + """Raise error Parameters ---------- @@ -17,6 +19,4 @@ def import_or_raise(package): try: import_module(package) except metadata.PackageNotFoundError: - raise ModuleNotFoundError( - f"This feature requires {package} to be installed." - ) \ No newline at end of file + raise ModuleNotFoundError(f"This feature requires {package} to be installed.") diff --git a/skops/utils/tests/test_importutils.py b/skops/utils/tests/test_importutils.py index 3502e97b..b3ba6707 100644 --- a/skops/utils/tests/test_importutils.py +++ b/skops/utils/tests/test_importutils.py @@ -1,7 +1,10 @@ -import pytest from unittest import mock + +import pytest + from skops.utils.importutils import import_or_raise + def test_import_or_raise(): orig_import = __import__ @@ -17,4 +20,4 @@ def mock_import(name, *args): ModuleNotFoundError, match="This feature requires matplotlib to be installed.", ): - import_or_raise("matplotlib") \ No newline at end of file + import_or_raise("matplotlib") From 61d17849867e0d3dd79b725b4ea8b7c37a39fa54 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Tue, 29 Nov 2022 17:34:26 +0300 Subject: [PATCH 34/68] fixed test --- skops/card/_model_card.py | 3 +- skops/card/tests/test_card.py | 116 +------------------------- skops/utils/importutils.py | 23 +++-- skops/utils/tests/test_importutils.py | 19 +++-- 4 files changed, 28 insertions(+), 133 deletions(-) diff --git a/skops/card/_model_card.py b/skops/card/_model_card.py index 3226cbb1..1900ced9 100644 --- a/skops/card/_model_card.py +++ b/skops/card/_model_card.py @@ -459,8 +459,7 @@ def add_permutation_importances( self : object Card object. """ - import_or_raise("matplotlib") - import matplotlib.pyplot as plt + plt = import_or_raise("matplotlib.pyplot", "permutation importance") if Path(plot_file).exists() and overwrite is False: raise ValueError( diff --git a/skops/card/tests/test_card.py b/skops/card/tests/test_card.py index 2a2ce594..d1386876 100644 --- a/skops/card/tests/test_card.py +++ b/skops/card/tests/test_card.py @@ -3,7 +3,6 @@ import pickle import tempfile from pathlib import Path -from unittest import mock import matplotlib.pyplot as plt import numpy as np @@ -18,7 +17,7 @@ import skops from skops import hub_utils from skops.card import Card, metadata_from_config -from skops.card._model_card import PlotSection, TableSection, _load_model +from skops.card._model_card import PlotSection, TableSection from skops.io import dump @@ -29,30 +28,6 @@ def fit_model(): return reg -def save_model_to_file(model_instance, suffix): - save_file_handle, save_file = tempfile.mkstemp(suffix=suffix, prefix="skops-test") - if suffix in (".pkl", ".pickle"): - with open(save_file, "wb") as f: - pickle.dump(model_instance, f) - elif suffix == ".skops": - dump(model_instance, save_file) - return save_file_handle, save_file - - -@pytest.mark.parametrize("suffix", [".pkl", ".pickle", ".skops"]) -def test_load_model(suffix): - model0 = LinearRegression(n_jobs=123) - _, save_file = save_model_to_file(model0, suffix) - loaded_model_str = _load_model(save_file) - save_file_path = Path(save_file) - loaded_model_path = _load_model(save_file_path) - loaded_model_instance = _load_model(model0) - - assert loaded_model_str.n_jobs == 123 - assert loaded_model_path.n_jobs == 123 - assert loaded_model_instance.n_jobs == 123 - - @pytest.fixture def model_card(model_diagram=True): model = fit_model() @@ -214,36 +189,6 @@ def test_permutation_importances( assert f"![Permutation Importance]({temp_path}" in model_card.render() -def test_matplotlib_dependency_error( - iris_estimator, iris_data, model_card, destination_path -): - orig_import = __import__ - - def mock_import(name, *args): - if name == "matplotlib.pyplot": - pass - else: - return orig_import(name, *args) - - X, y = iris_data - result = permutation_importance( - iris_estimator, X, y, n_repeats=10, random_state=42, n_jobs=2 - ) - - with mock.patch("builtins.__import__", side_effect=mock_import): - with pytest.raises(ImportError, match="cannot import name*"): - with pytest.raises( - ModuleNotFoundError, - match="This feature requires matplotlib to be installed.", - ): - model_card.add_permutation_importances( - result, - X.columns, - Path(destination_path) / "importance.png", - "Permutation Importance", - ) - - def test_multiple_permutation_importances( iris_estimator, iris_data, model_card, destination_path ): @@ -552,65 +497,6 @@ def test_with_metadata(self, card: Card, meth): assert result == expected -class TestCardModelAttribute: - def path_to_card(self, path): - card = Card(model=path) - card.add( - model_description="A description", - model_card_authors="Jane Doe", - ) - card.add_plot( - roc_curve="ROC_curve.png", - confusion_matrix="confusion_matrix.jpg", - ) - card.add_table(search_results={"split": [1, 2, 3], "score": [4, 5, 6]}) - return card - - @pytest.mark.parametrize("meth", [repr, str]) - @pytest.mark.parametrize("suffix", [".pkl", ".skops"]) - def test_model_card_repr(self, meth, suffix): - model = LinearRegression(fit_intercept=False) - file_handle, file_name = save_model_to_file(model, suffix) - os.close(file_handle) - card_from_path = self.path_to_card(file_name) - result_from_path = meth(card_from_path) - expected = ( - "Card(\n" - " model=LinearRegression(fit_intercept=False),\n" - " model_description='A description',\n" - " model_card_authors='Jane Doe',\n" - " roc_curve='ROC_curve.png',\n" - " confusion_matrix='confusion_matrix.jpg',\n" - " search_results=Table(3x2),\n" - ")" - ) - assert result_from_path == expected - - @pytest.mark.parametrize("suffix", [".pkl", ".skops"]) - @pytest.mark.parametrize("meth", [repr, str]) - def test_load_model_exception(self, meth, suffix): - file_handle, file_name = tempfile.mkstemp(suffix=suffix, prefix="skops-test") - - os.close(file_handle) - - with pytest.raises(Exception, match="occured during model loading."): - card = Card(file_name) - meth(card) - - @pytest.mark.parametrize("meth", [repr, str]) - def test_load_model_file_not_found(self, meth): - file_handle, file_name = tempfile.mkstemp(suffix=".pkl", prefix="skops-test") - - os.close(file_handle) - os.remove(file_name) - - with pytest.raises(FileNotFoundError) as excinfo: - card = Card(file_name) - meth(card) - - assert file_name in str(excinfo.value) - - class TestPlotSection: def test_format_path_is_str(self): section = PlotSection(alt_text="some title", path="path/plot.png") diff --git a/skops/utils/importutils.py b/skops/utils/importutils.py index e842f8e9..766739c4 100644 --- a/skops/utils/importutils.py +++ b/skops/utils/importutils.py @@ -1,15 +1,16 @@ from importlib import import_module -from skops.utils.fixes import metadata - -def import_or_raise(package): +def import_or_raise(module, feature_name): """Raise error Parameters ---------- - package: str - Name of the package. + module: str + Name of the module. + + feature_name: str + Name of the feature module is required for. Raises ------ @@ -17,6 +18,12 @@ def import_or_raise(package): Is raised if a given module is not present in the environment """ try: - import_module(package) - except metadata.PackageNotFoundError: - raise ModuleNotFoundError(f"This feature requires {package} to be installed.") + module = import_module(module) + except ImportError as e: + package = module.split(".")[0] + raise ModuleNotFoundError( + f"{feature_name.capitalize()} requires {package} to be installed. In order" + f" to use {feature_name}, you need to install the package in your current" + " python environment." + ) from e + return module diff --git a/skops/utils/tests/test_importutils.py b/skops/utils/tests/test_importutils.py index b3ba6707..5a03044f 100644 --- a/skops/utils/tests/test_importutils.py +++ b/skops/utils/tests/test_importutils.py @@ -10,14 +10,17 @@ def test_import_or_raise(): def mock_import(name, *args): if name == "matplotlib": - pass + raise ImportError("No module named 'matplotlib'") else: return orig_import(name, *args) - with mock.patch("builtins.__import__", side_effect=mock_import): - with pytest.raises(ImportError, match="cannot import name*"): - with pytest.raises( - ModuleNotFoundError, - match="This feature requires matplotlib to be installed.", - ): - import_or_raise("matplotlib") + with mock.patch("importlib.import_module", side_effect=mock_import): + with pytest.raises( + ModuleNotFoundError, + match=( + "Permutation importance requires matplotlib to be installed. In order" + " to use permutation importance, you need to install the package in" + " your current python environment." + ), + ): + import_or_raise("matplotlib", "permutation importance") From 5e5d6b358ea9c081db4725f4b343ec502d99c87f Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Tue, 29 Nov 2022 20:16:47 +0300 Subject: [PATCH 35/68] trigger CI From 2bf6c816a714dd5652ede190d3ac4654f989780d Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Tue, 29 Nov 2022 20:21:28 +0300 Subject: [PATCH 36/68] minor fix after merge conflict --- skops/card/tests/test_card.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/skops/card/tests/test_card.py b/skops/card/tests/test_card.py index 68a455a5..b02b8c5e 100644 --- a/skops/card/tests/test_card.py +++ b/skops/card/tests/test_card.py @@ -17,7 +17,7 @@ import skops from skops import hub_utils from skops.card import Card, metadata_from_config -from skops.card._model_card import PlotSection, TableSection +from skops.card._model_card import PlotSection, TableSection, _load_model from skops.io import dump @@ -28,7 +28,6 @@ def fit_model(): return reg - def save_model_to_file(model_instance, suffix): save_file_handle, save_file = tempfile.mkstemp(suffix=suffix, prefix="skops-test") if suffix in (".pkl", ".pickle"): @@ -53,7 +52,6 @@ def test_load_model(suffix): assert loaded_model_instance.n_jobs == 123 - @pytest.fixture def model_card(model_diagram=True): model = fit_model() @@ -523,7 +521,6 @@ def test_with_metadata(self, card: Card, meth): assert result == expected - class TestCardModelAttribute: def path_to_card(self, path): card = Card(model=path, trusted=True) From 04651636a53fa1fdaca62b72c8569e992fa51a87 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Tue, 29 Nov 2022 22:25:41 +0300 Subject: [PATCH 37/68] changed test --- skops/utils/tests/test_importutils.py | 31 +++++++++++---------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/skops/utils/tests/test_importutils.py b/skops/utils/tests/test_importutils.py index 5a03044f..824536fa 100644 --- a/skops/utils/tests/test_importutils.py +++ b/skops/utils/tests/test_importutils.py @@ -1,4 +1,5 @@ -from unittest import mock +import sys +from unittest.mock import MagicMock import pytest @@ -6,21 +7,13 @@ def test_import_or_raise(): - orig_import = __import__ - - def mock_import(name, *args): - if name == "matplotlib": - raise ImportError("No module named 'matplotlib'") - else: - return orig_import(name, *args) - - with mock.patch("importlib.import_module", side_effect=mock_import): - with pytest.raises( - ModuleNotFoundError, - match=( - "Permutation importance requires matplotlib to be installed. In order" - " to use permutation importance, you need to install the package in" - " your current python environment." - ), - ): - import_or_raise("matplotlib", "permutation importance") + sys.modules["matplotlib"] = MagicMock() + with pytest.raises( + ModuleNotFoundError, + match=( + "Permutation importance requires matplotlib to be installed. In order" + " to use permutation importance, you need to install the package in" + " your current python environment." + ), + ): + import_or_raise("matplotlib.pyplot", "permutation importance") From 8bf590e1ef923a42571c40abd6e93c1dc4426794 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Wed, 14 Dec 2022 17:25:44 +0300 Subject: [PATCH 38/68] latest version --- skops/utils/importutils.py | 1 + skops/utils/tests/test_importutils.py | 32 +++++++++++++++++---------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/skops/utils/importutils.py b/skops/utils/importutils.py index 766739c4..1d7a010c 100644 --- a/skops/utils/importutils.py +++ b/skops/utils/importutils.py @@ -17,6 +17,7 @@ def import_or_raise(module, feature_name): ModuleNotFoundError Is raised if a given module is not present in the environment """ + breakpoint() try: module = import_module(module) except ImportError as e: diff --git a/skops/utils/tests/test_importutils.py b/skops/utils/tests/test_importutils.py index 824536fa..3a14c030 100644 --- a/skops/utils/tests/test_importutils.py +++ b/skops/utils/tests/test_importutils.py @@ -1,5 +1,5 @@ -import sys -from unittest.mock import MagicMock +import importlib +from unittest import mock import pytest @@ -7,13 +7,21 @@ def test_import_or_raise(): - sys.modules["matplotlib"] = MagicMock() - with pytest.raises( - ModuleNotFoundError, - match=( - "Permutation importance requires matplotlib to be installed. In order" - " to use permutation importance, you need to install the package in" - " your current python environment." - ), - ): - import_or_raise("matplotlib.pyplot", "permutation importance") + # orig_import = __import__ + + def mock_import(name, *args): + if name == "matplotlib": + raise ImportError("No module named 'matplotlib'") + else: + return importlib.import_module(name) + + with mock.patch("importlib.import_module", side_effect=mock_import): + with pytest.raises( + ModuleNotFoundError, + match=( + "Permutation importance requires matplotlib to be installed. In order" + " to use permutation importance, you need to install the package in" + " your current python environment." + ), + ): + import_or_raise("matplotlib", "permutation importance") From 64996fbda90f475c150a9a8d0aeac05f8e2af551 Mon Sep 17 00:00:00 2001 From: adrinjalali Date: Wed, 14 Dec 2022 15:38:42 +0100 Subject: [PATCH 39/68] fix, but no idea why --- skops/utils/importutils.py | 1 - skops/utils/tests/test_importutils.py | 41 ++++++++++++++------------- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/skops/utils/importutils.py b/skops/utils/importutils.py index 1d7a010c..766739c4 100644 --- a/skops/utils/importutils.py +++ b/skops/utils/importutils.py @@ -17,7 +17,6 @@ def import_or_raise(module, feature_name): ModuleNotFoundError Is raised if a given module is not present in the environment """ - breakpoint() try: module = import_module(module) except ImportError as e: diff --git a/skops/utils/tests/test_importutils.py b/skops/utils/tests/test_importutils.py index 3a14c030..c61c43a4 100644 --- a/skops/utils/tests/test_importutils.py +++ b/skops/utils/tests/test_importutils.py @@ -1,27 +1,30 @@ -import importlib -from unittest import mock +import builtins import pytest from skops.utils.importutils import import_or_raise -def test_import_or_raise(): - # orig_import = __import__ +@pytest.fixture +def hide_available_matplotlib(monkeypatch): + import_orig = builtins.__import__ - def mock_import(name, *args): + def mocked_import(name, *args, **kwargs): if name == "matplotlib": - raise ImportError("No module named 'matplotlib'") - else: - return importlib.import_module(name) - - with mock.patch("importlib.import_module", side_effect=mock_import): - with pytest.raises( - ModuleNotFoundError, - match=( - "Permutation importance requires matplotlib to be installed. In order" - " to use permutation importance, you need to install the package in" - " your current python environment." - ), - ): - import_or_raise("matplotlib", "permutation importance") + raise ImportError() + return import_orig(name, *args, **kwargs) + + monkeypatch.setattr(builtins, "__import__", mocked_import) + + +@pytest.mark.usefixtures("hide_available_matplotlib") +def test_import_or_raise(): + with pytest.raises( + ModuleNotFoundError, + match=( + "Permutation importance requires matplotlib to be installed. In order" + " to use permutation importance, you need to install the package in" + " your current python environment." + ), + ): + import_or_raise("matplotlib", "permutation importance") From e03d30fdbc6f480b42e3bd7c48574fedf10b1ef2 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Fri, 6 Jan 2023 13:04:23 +0100 Subject: [PATCH 40/68] minor try --- skops/utils/tests/test_importutils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/skops/utils/tests/test_importutils.py b/skops/utils/tests/test_importutils.py index c61c43a4..6c788bf4 100644 --- a/skops/utils/tests/test_importutils.py +++ b/skops/utils/tests/test_importutils.py @@ -12,7 +12,8 @@ def hide_available_matplotlib(monkeypatch): def mocked_import(name, *args, **kwargs): if name == "matplotlib": raise ImportError() - return import_orig(name, *args, **kwargs) + else: + return import_orig(name, *args, **kwargs) monkeypatch.setattr(builtins, "__import__", mocked_import) From c9b881361844f6156f537b3695d8eb789194cb65 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Fri, 6 Jan 2023 13:12:31 +0100 Subject: [PATCH 41/68] trigger ci From a71cdace400d4a81e15712bdb64946ba82bd5cb7 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Fri, 6 Jan 2023 13:19:51 +0100 Subject: [PATCH 42/68] revert --- skops/utils/tests/test_importutils.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/skops/utils/tests/test_importutils.py b/skops/utils/tests/test_importutils.py index 6c788bf4..c61c43a4 100644 --- a/skops/utils/tests/test_importutils.py +++ b/skops/utils/tests/test_importutils.py @@ -12,8 +12,7 @@ def hide_available_matplotlib(monkeypatch): def mocked_import(name, *args, **kwargs): if name == "matplotlib": raise ImportError() - else: - return import_orig(name, *args, **kwargs) + return import_orig(name, *args, **kwargs) monkeypatch.setattr(builtins, "__import__", mocked_import) From 9e63a42d0ed36b8b51794ace5d01e10af506b020 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Mon, 16 Jan 2023 11:38:35 +0100 Subject: [PATCH 43/68] mypy fix --- skops/card/tests/test_card.py | 5 ++++- skops/conftest.py | 30 ++++++++++++++++++++++++++++-- skops/hub_utils/_hf_hub.py | 4 ++-- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/skops/card/tests/test_card.py b/skops/card/tests/test_card.py index b02b8c5e..ff4ae3dc 100644 --- a/skops/card/tests/test_card.py +++ b/skops/card/tests/test_card.py @@ -4,7 +4,6 @@ import tempfile from pathlib import Path -import matplotlib.pyplot as plt import numpy as np import pytest import sklearn @@ -189,6 +188,8 @@ def test_template_sections_not_mutated_by_save(destination_path, model_card): def test_add_plot(destination_path, model_card): + import matplotlib.pyplot as plt + plt.plot([4, 5, 6, 7]) plt.savefig(Path(destination_path) / "fig1.png") model_card = model_card.add_plot(fig1="fig1.png").render() @@ -289,6 +290,8 @@ def test_temporary_plot(destination_path, model_card): # test if the additions are made to a temporary template file # and not to default template or template provided root = skops.__path__ + import matplotlib.pyplot as plt + # read original template with open(Path(root[0]) / "card" / "default_template.md") as f: default_template = f.read() diff --git a/skops/conftest.py b/skops/conftest.py index a09c69b8..0c2ebe30 100644 --- a/skops/conftest.py +++ b/skops/conftest.py @@ -1,16 +1,42 @@ +import builtins from unittest.mock import patch import pytest -@pytest.fixture def pandas_not_installed(): # patch import so that it raises an ImportError when trying to import # pandas. This works because pandas is only imported lazily. + + orig_import = builtins.__import__ + def mock_import(name, *args, **kwargs): if name == "pandas": raise ImportError - return __import__(name, *args, **kwargs) + return orig_import(name, *args, **kwargs) + + with patch("builtins.__import__", side_effect=mock_import): + yield + + +@pytest.fixture +def matplotlib_not_installed(): + # patch import so that it raises an ImportError when trying to import + # matplotlib. This works because matplotlib is only imported lazily. + + # ugly way of removing matplotlib from cached imports + import sys + + for key in list(sys.modules.keys()): + if key.startswith("matplotlib"): + del sys.modules[key] + + orig_import = builtins.__import__ + + def mock_import(name, *args, **kwargs): + if name == "matplotlib": + raise ImportError + return orig_import(name, *args, **kwargs) with patch("builtins.__import__", side_effect=mock_import): yield diff --git a/skops/hub_utils/_hf_hub.py b/skops/hub_utils/_hf_hub.py index d76e1de3..bb049caa 100644 --- a/skops/hub_utils/_hf_hub.py +++ b/skops/hub_utils/_hf_hub.py @@ -142,7 +142,7 @@ def _create_config( model_path: Union[str, Path], requirements: List[str], dst: Union[str, Path], - task: Literal[ + task: Literal[ # type: ignore "tabular-classification", "tabular-regression", "text-classification", @@ -266,7 +266,7 @@ def init( model: Union[str, Path], requirements: List[str], dst: Union[str, Path], - task: Literal[ + task: Literal[ #  type: ignore "tabular-classification", "tabular-regression", "text-classification", From e33e2542f1c6dd37ef3506f64c5f4b3223ad0217 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Tue, 17 Jan 2023 15:28:31 +0100 Subject: [PATCH 44/68] fixed test and fixture --- skops/card/tests/test_card.py | 8 -------- skops/conftest.py | 1 + 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/skops/card/tests/test_card.py b/skops/card/tests/test_card.py index e60d27a1..f385881b 100644 --- a/skops/card/tests/test_card.py +++ b/skops/card/tests/test_card.py @@ -1,4 +1,3 @@ -import copy import os import pickle import re @@ -405,13 +404,6 @@ def test_add_twice(self, model_card): assert text1 == text2 -def test_template_sections_not_mutated_by_save(destination_path, model_card): - template_sections_before = copy.deepcopy(model_card._template_sections) - model_card.save(Path(destination_path) / "README.md") - template_sections_after = copy.deepcopy(model_card._template_sections) - assert template_sections_before == template_sections_after - - def test_add_plot(destination_path, model_card): import matplotlib.pyplot as plt diff --git a/skops/conftest.py b/skops/conftest.py index 0c2ebe30..2452f5d7 100644 --- a/skops/conftest.py +++ b/skops/conftest.py @@ -4,6 +4,7 @@ import pytest +@pytest.fixture def pandas_not_installed(): # patch import so that it raises an ImportError when trying to import # pandas. This works because pandas is only imported lazily. From d66be435d179e3b24af73ac685dc2ea8cdb44d50 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Tue, 17 Jan 2023 16:06:14 +0100 Subject: [PATCH 45/68] fix --- skops/utils/tests/test_importutils.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/skops/utils/tests/test_importutils.py b/skops/utils/tests/test_importutils.py index c61c43a4..be7fff68 100644 --- a/skops/utils/tests/test_importutils.py +++ b/skops/utils/tests/test_importutils.py @@ -9,6 +9,13 @@ def hide_available_matplotlib(monkeypatch): import_orig = builtins.__import__ + # ugly way of removing matplotlib from cached imports + import sys + + for key in list(sys.modules.keys()): + if key.startswith("matplotlib"): + del sys.modules[key] + def mocked_import(name, *args, **kwargs): if name == "matplotlib": raise ImportError() @@ -17,7 +24,7 @@ def mocked_import(name, *args, **kwargs): monkeypatch.setattr(builtins, "__import__", mocked_import) -@pytest.mark.usefixtures("hide_available_matplotlib") +@pytest.mark.usefixtures("matplotlib_not_installed") def test_import_or_raise(): with pytest.raises( ModuleNotFoundError, From ff9c7bf59cdedb086e8e8a6a685cb794e4f34e03 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Tue, 17 Jan 2023 16:14:09 +0100 Subject: [PATCH 46/68] removed redundant fixture --- skops/utils/tests/test_importutils.py | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/skops/utils/tests/test_importutils.py b/skops/utils/tests/test_importutils.py index be7fff68..c7424d09 100644 --- a/skops/utils/tests/test_importutils.py +++ b/skops/utils/tests/test_importutils.py @@ -1,29 +1,8 @@ -import builtins - import pytest from skops.utils.importutils import import_or_raise -@pytest.fixture -def hide_available_matplotlib(monkeypatch): - import_orig = builtins.__import__ - - # ugly way of removing matplotlib from cached imports - import sys - - for key in list(sys.modules.keys()): - if key.startswith("matplotlib"): - del sys.modules[key] - - def mocked_import(name, *args, **kwargs): - if name == "matplotlib": - raise ImportError() - return import_orig(name, *args, **kwargs) - - monkeypatch.setattr(builtins, "__import__", mocked_import) - - @pytest.mark.usefixtures("matplotlib_not_installed") def test_import_or_raise(): with pytest.raises( From bdeabc4f705dd6fb76ee791a653369a59e4d0223 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Fri, 20 Jan 2023 15:48:03 +0100 Subject: [PATCH 47/68] trigger black From e999a6f8b6b36ec93699fc4b0daa4ca4040c8ba2 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Fri, 20 Jan 2023 15:49:45 +0100 Subject: [PATCH 48/68] trigger black --- skops/card/_model_card.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skops/card/_model_card.py b/skops/card/_model_card.py index 95ac204e..4c438cbc 100644 --- a/skops/card/_model_card.py +++ b/skops/card/_model_card.py @@ -8,7 +8,7 @@ from dataclasses import dataclass, field from pathlib import Path from reprlib import Repr -from typing import Any, Iterator, Literal, Protocol, Sequence, Union # type: ignore +from typing import Any, Iterator, Literal, Protocol, Sequence, Union import joblib from huggingface_hub import ModelCardData From c9219d51b28fb587cc39a1d3308a11d0f5e9d530 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Fri, 20 Jan 2023 15:54:09 +0100 Subject: [PATCH 49/68] trigger black --- skops/conftest.py | 1 - 1 file changed, 1 deletion(-) diff --git a/skops/conftest.py b/skops/conftest.py index de867430..2452f5d7 100644 --- a/skops/conftest.py +++ b/skops/conftest.py @@ -39,6 +39,5 @@ def mock_import(name, *args, **kwargs): raise ImportError return orig_import(name, *args, **kwargs) - with patch("builtins.__import__", side_effect=mock_import): yield From bb864a694c1be6ae8cdc7642ebda767eba1b2b69 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Fri, 20 Jan 2023 16:05:56 +0100 Subject: [PATCH 50/68] trigger isort --- skops/hub_utils/_hf_hub.py | 1 - 1 file changed, 1 deletion(-) diff --git a/skops/hub_utils/_hf_hub.py b/skops/hub_utils/_hf_hub.py index da5177dd..4dbc2179 100644 --- a/skops/hub_utils/_hf_hub.py +++ b/skops/hub_utils/_hf_hub.py @@ -12,7 +12,6 @@ from pathlib import Path from typing import Any, List, Literal, MutableMapping, Optional, Sequence, Union - import numpy as np from huggingface_hub import HfApi, InferenceApi, snapshot_download from sklearn.utils import check_array From 9113aad1fe3b1e663d68c972c28805ebe86fb42a Mon Sep 17 00:00:00 2001 From: Merve Noyan Date: Mon, 23 Jan 2023 12:01:26 +0100 Subject: [PATCH 51/68] Update skops/card/_model_card.py Co-authored-by: Benjamin Bossan --- skops/card/_model_card.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skops/card/_model_card.py b/skops/card/_model_card.py index 4c438cbc..986a893f 100644 --- a/skops/card/_model_card.py +++ b/skops/card/_model_card.py @@ -204,7 +204,7 @@ def split_subsection_names(key: str) -> list[str]: def _getting_started_code( - file_name: str, model_format: Literal["pickle", "skops"], indent=" " # type: ignore + file_name: str, model_format: Literal["pickle", "skops"], indent: str = " " ) -> list[str]: # get lines of code required to load the model lines = [ From 5e8073260c20a8e87c58bc2dda19b0f40d357ef5 Mon Sep 17 00:00:00 2001 From: Merve Noyan Date: Mon, 23 Jan 2023 12:01:35 +0100 Subject: [PATCH 52/68] Update skops/card/_model_card.py Co-authored-by: Benjamin Bossan --- skops/card/_model_card.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skops/card/_model_card.py b/skops/card/_model_card.py index 986a893f..97f982e6 100644 --- a/skops/card/_model_card.py +++ b/skops/card/_model_card.py @@ -849,7 +849,7 @@ def add_get_started_code( section: str | None = None, description: str | None = None, file_name: str | None = None, - model_format: Literal["pickle", "skops"] | None = None, # type: ignore + model_format: Literal["pickle", "skops"] | None = None, ) -> Card: """Add getting started code From 322ed4d2b3d65ee3dcbf3f4d698eb240f4e477f8 Mon Sep 17 00:00:00 2001 From: Merve Noyan Date: Mon, 23 Jan 2023 12:01:49 +0100 Subject: [PATCH 53/68] Update skops/card/_model_card.py Co-authored-by: Benjamin Bossan --- skops/card/_model_card.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skops/card/_model_card.py b/skops/card/_model_card.py index 97f982e6..c142944b 100644 --- a/skops/card/_model_card.py +++ b/skops/card/_model_card.py @@ -1106,7 +1106,7 @@ def add_permutation_importances( plot_name : str, or Path Name of the plot. - overwrite : bool + overwrite : bool (default=False) Whether to overwrite the permutation importance plot, if exists. Returns From e5afe26d4174bcb1c1a38f67052304bb9f889927 Mon Sep 17 00:00:00 2001 From: Merve Noyan Date: Mon, 23 Jan 2023 12:02:01 +0100 Subject: [PATCH 54/68] Update skops/card/_model_card.py Co-authored-by: Benjamin Bossan --- skops/card/_model_card.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/skops/card/_model_card.py b/skops/card/_model_card.py index c142944b..d8f9bd07 100644 --- a/skops/card/_model_card.py +++ b/skops/card/_model_card.py @@ -1085,10 +1085,10 @@ def add_metrics( def add_permutation_importances( self, permutation_importances, - columns, - plot_file="permutation_importances.png", - plot_name="Permutation Importances", - overwrite=False, + columns: Sequence[str], + plot_file: str = "permutation_importances.png", + plot_name: str = "Permutation Importances", + overwrite: bool = False, ) -> "Card": """Plots permutation importance and saves it to model card. From 95189d8a54e3738e96d7f73c7e4ce20d0a2c9cde Mon Sep 17 00:00:00 2001 From: Merve Noyan Date: Mon, 23 Jan 2023 12:02:58 +0100 Subject: [PATCH 55/68] Update skops/card/_model_card.py Co-authored-by: Benjamin Bossan --- skops/card/_model_card.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/skops/card/_model_card.py b/skops/card/_model_card.py index d8f9bd07..ce07bfc2 100644 --- a/skops/card/_model_card.py +++ b/skops/card/_model_card.py @@ -1107,7 +1107,8 @@ def add_permutation_importances( Name of the plot. overwrite : bool (default=False) - Whether to overwrite the permutation importance plot, if exists. + Whether to overwrite the permutation importance plot file, if a plot by that + name already exists. Returns ------- From 55b968dd3d4ded91cf1f7ff2bfb02affe1ead011 Mon Sep 17 00:00:00 2001 From: Merve Noyan Date: Mon, 23 Jan 2023 12:04:04 +0100 Subject: [PATCH 56/68] Update skops/card/_model_card.py Co-authored-by: Benjamin Bossan --- skops/card/_model_card.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skops/card/_model_card.py b/skops/card/_model_card.py index ce07bfc2..b8c0c4a8 100644 --- a/skops/card/_model_card.py +++ b/skops/card/_model_card.py @@ -446,7 +446,7 @@ def __init__( model, model_diagram: bool = True, metadata: ModelCardData | None = None, - template: Literal["skops"] | dict[str, str] | None = "skops", # type: ignore + template: Literal["skops"] | dict[str, str] | None = "skops", trusted: bool = False, ) -> None: self.model = model From 6e3fd2b33ae5219326f4c76c4d2f3786a7bc3d3c Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Mon, 23 Jan 2023 12:14:00 +0100 Subject: [PATCH 57/68] removed test, nits and more --- skops/card/tests/test_card.py | 11 +---------- skops/conftest.py | 4 ++++ 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/skops/card/tests/test_card.py b/skops/card/tests/test_card.py index 0c1c0349..a71a0730 100644 --- a/skops/card/tests/test_card.py +++ b/skops/card/tests/test_card.py @@ -404,15 +404,6 @@ def test_add_twice(self, model_card): assert text1 == text2 -def test_add_plot(destination_path, model_card): - import matplotlib.pyplot as plt - - plt.plot([4, 5, 6, 7]) - plt.savefig(Path(destination_path) / "fig1.png") - model_card = model_card.add_plot(fig1="fig1.png").render() - assert "![fig1](fig1.png)" in model_card - - def test_permutation_importances( iris_estimator, iris_data, model_card, destination_path ): @@ -439,7 +430,7 @@ def test_multiple_permutation_importances( iris_estimator, X, y, n_repeats=10, random_state=42, n_jobs=2 ) model_card.add_permutation_importances( - result, X.columns, plot_file=(Path(destination_path) / "importance.png") + result, X.columns, plot_file=Path(destination_path) / "importance.png" ) f1 = make_scorer(f1_score, average="micro") result = permutation_importance( diff --git a/skops/conftest.py b/skops/conftest.py index 2452f5d7..094e2a39 100644 --- a/skops/conftest.py +++ b/skops/conftest.py @@ -19,6 +19,8 @@ def mock_import(name, *args, **kwargs): with patch("builtins.__import__", side_effect=mock_import): yield + import matplotlib # noqa + @pytest.fixture def matplotlib_not_installed(): @@ -41,3 +43,5 @@ def mock_import(name, *args, **kwargs): with patch("builtins.__import__", side_effect=mock_import): yield + + import matplotlib # noqa From 9d9800335d198eef4600279cefac94f3bcadaffc Mon Sep 17 00:00:00 2001 From: Merve Noyan Date: Mon, 23 Jan 2023 12:14:51 +0100 Subject: [PATCH 58/68] Update skops/card/_model_card.py Co-authored-by: Benjamin Bossan --- skops/card/_model_card.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skops/card/_model_card.py b/skops/card/_model_card.py index b8c0c4a8..8fa2a27e 100644 --- a/skops/card/_model_card.py +++ b/skops/card/_model_card.py @@ -930,7 +930,7 @@ def _add_get_started_code( self, section: str, file_name: str, - model_format: Literal["pickle", "skops"], # type: ignore + model_format: Literal["pickle", "skops"], description: str | None, indent: str = " ", ) -> None: From 17e025305a68ffff0628b07de455e50a96b140af Mon Sep 17 00:00:00 2001 From: Merve Noyan Date: Mon, 23 Jan 2023 12:15:01 +0100 Subject: [PATCH 59/68] Update skops/card/_model_card.py Co-authored-by: Benjamin Bossan --- skops/card/_model_card.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skops/card/_model_card.py b/skops/card/_model_card.py index 8fa2a27e..a8752c5d 100644 --- a/skops/card/_model_card.py +++ b/skops/card/_model_card.py @@ -1103,7 +1103,7 @@ def add_permutation_importances( plot_file : str Filename for the plot. - plot_name : str, or Path + plot_name : str Name of the plot. overwrite : bool (default=False) From cf18588b7878b6320a77a22d54db02bdd1f5bd87 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Wed, 25 Jan 2023 18:18:53 +0100 Subject: [PATCH 60/68] iterated --- skops/conftest.py | 2 -- skops/utils/importutils.py | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/skops/conftest.py b/skops/conftest.py index 094e2a39..9ee0a4db 100644 --- a/skops/conftest.py +++ b/skops/conftest.py @@ -19,8 +19,6 @@ def mock_import(name, *args, **kwargs): with patch("builtins.__import__", side_effect=mock_import): yield - import matplotlib # noqa - @pytest.fixture def matplotlib_not_installed(): diff --git a/skops/utils/importutils.py b/skops/utils/importutils.py index 766739c4..ac81a203 100644 --- a/skops/utils/importutils.py +++ b/skops/utils/importutils.py @@ -2,7 +2,7 @@ def import_or_raise(module, feature_name): - """Raise error + """Raise error if a given library is not present in the environment. Parameters ---------- From 7a02cd468fd2d0b6bbaf130762bfdd94f581e98c Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Sun, 29 Jan 2023 22:08:35 +0100 Subject: [PATCH 61/68] added print to debug on ubuntu --- skops/card/_markup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/skops/card/_markup.py b/skops/card/_markup.py index 7779a675..667fd6a6 100644 --- a/skops/card/_markup.py +++ b/skops/card/_markup.py @@ -207,6 +207,7 @@ def _table_body(self, items) -> list[list[str]]: def _table(self, item) -> str: # attr capt specs thead tbody tfoot + print(item) _, _, _, thead, tbody, _ = item # header From 602b8d219edd7ce5d1f37e433bfc04e1642ec6e9 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Sun, 29 Jan 2023 22:23:45 +0100 Subject: [PATCH 62/68] more debugging --- .github/workflows/build-test.yml | 2 +- skops/card/_markup.py | 1 + skops/card/tests/test_parser.py | 9 +++++++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 7920721e..078dfd59 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -80,7 +80,7 @@ jobs: env: SUPER_SECRET: ${{ secrets.HF_HUB_TOKEN }} run: | - python -m pytest -s -v --cov-report=xml -m "not inference" skops/ + python -m pytest -s -v --cov-report=xml -m "not inference" -k "test_example_model_cards" skops/ - name: Mypy run: mypy --config-file pyproject.toml skops diff --git a/skops/card/_markup.py b/skops/card/_markup.py index 667fd6a6..9355f3f1 100644 --- a/skops/card/_markup.py +++ b/skops/card/_markup.py @@ -207,6 +207,7 @@ def _table_body(self, items) -> list[list[str]]: def _table(self, item) -> str: # attr capt specs thead tbody tfoot + print("*" * 30) print(item) _, _, _, thead, tbody, _ = item diff --git a/skops/card/tests/test_parser.py b/skops/card/tests/test_parser.py index b74486fe..bc77d754 100644 --- a/skops/card/tests/test_parser.py +++ b/skops/card/tests/test_parser.py @@ -90,8 +90,13 @@ def test_example_model_cards(tmp_path, file_name): path = Path(os.getcwd()) / "skops" / "card" / "tests" / "examples" file0 = path / file_name diff = (path / file_name).with_suffix(".md.diff") - - parsed_card = parse_modelcard(file0) + try: + parsed_card = parse_modelcard(file0) + except Exception as exc: + print("*" * 30) + print(file0) + print(diff) + print(exc) file1 = tmp_path / "readme-parsed.md" parsed_card.save(file1) From c23f63f63ad49f28baf14aa6d9748efe9eb5d85b Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Sun, 29 Jan 2023 22:27:58 +0100 Subject: [PATCH 63/68] more debugging --- skops/card/_markup.py | 3 ++- skops/card/tests/test_parser.py | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/skops/card/_markup.py b/skops/card/_markup.py index 9355f3f1..e94da4f8 100644 --- a/skops/card/_markup.py +++ b/skops/card/_markup.py @@ -208,7 +208,8 @@ def _table_body(self, items) -> list[list[str]]: def _table(self, item) -> str: # attr capt specs thead tbody tfoot print("*" * 30) - print(item) + print(f"item = {item}") + print("*" * 30) _, _, _, thead, tbody, _ = item # header diff --git a/skops/card/tests/test_parser.py b/skops/card/tests/test_parser.py index bc77d754..237a7b86 100644 --- a/skops/card/tests/test_parser.py +++ b/skops/card/tests/test_parser.py @@ -94,9 +94,9 @@ def test_example_model_cards(tmp_path, file_name): parsed_card = parse_modelcard(file0) except Exception as exc: print("*" * 30) - print(file0) - print(diff) - print(exc) + print(f"file0 {file0}") + print("*" * 30) + print(f"diff {diff}") file1 = tmp_path / "readme-parsed.md" parsed_card.save(file1) From e046f88f33480396807fff9c25fb26779207cb9e Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Sun, 29 Jan 2023 23:10:52 +0100 Subject: [PATCH 64/68] removed debug --- skops/card/tests/test_parser.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/skops/card/tests/test_parser.py b/skops/card/tests/test_parser.py index 237a7b86..d140149b 100644 --- a/skops/card/tests/test_parser.py +++ b/skops/card/tests/test_parser.py @@ -90,13 +90,7 @@ def test_example_model_cards(tmp_path, file_name): path = Path(os.getcwd()) / "skops" / "card" / "tests" / "examples" file0 = path / file_name diff = (path / file_name).with_suffix(".md.diff") - try: - parsed_card = parse_modelcard(file0) - except Exception as exc: - print("*" * 30) - print(f"file0 {file0}") - print("*" * 30) - print(f"diff {diff}") + parsed_card = parse_modelcard(file0) file1 = tmp_path / "readme-parsed.md" parsed_card.save(file1) From a16d83f1a0a0a46279904b85d7f4956bde28127c Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Sun, 29 Jan 2023 23:14:36 +0100 Subject: [PATCH 65/68] removed debugging line from github workflow --- .github/workflows/build-test.yml | 2 +- skops/card/_markup.py | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 80446caa..513ce6d1 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -80,7 +80,7 @@ jobs: env: SUPER_SECRET: ${{ secrets.HF_HUB_TOKEN }} run: | - python -m pytest -s -v --cov-report=xml -m "not inference" -k "test_example_model_cards" skops/ + python -m pytest -s -v --cov-report=xml -m "not inference" skops/ - name: Mypy run: mypy --config-file pyproject.toml skops diff --git a/skops/card/_markup.py b/skops/card/_markup.py index 27460b77..32f94b36 100644 --- a/skops/card/_markup.py +++ b/skops/card/_markup.py @@ -239,9 +239,6 @@ def _table_old(self, item) -> tuple[list[str], list[list[str]]]: def _table_new(self, item) -> tuple[list[str], list[list[str]]]: # pragma: no cover # pandoc >= 2.10 # attr capt specs thead tbody tfoot - print("*" * 30) - print(f"item = {item}") - print("*" * 30) _, _, _, thead, tbody, _ = item # header (_, thead_bodies) = thead From fce9b142b3bdcadb9660d7c329c339611f025956 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Mon, 30 Jan 2023 13:02:58 +0100 Subject: [PATCH 66/68] removed mypy ignores --- skops/hub_utils/_hf_hub.py | 4 ++-- skops/io/_audit.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/skops/hub_utils/_hf_hub.py b/skops/hub_utils/_hf_hub.py index a43d25c5..5d7a4b35 100644 --- a/skops/hub_utils/_hf_hub.py +++ b/skops/hub_utils/_hf_hub.py @@ -199,14 +199,14 @@ def _create_config( model_path: Union[str, Path], requirements: List[str], dst: Union[str, Path], - task: Literal[ # type: ignore + task: Literal[ "tabular-classification", "tabular-regression", "text-classification", "text-regression", ], data, - model_format: Literal[ # type: ignore + model_format: Literal[ "skops", "pickle", "auto", diff --git a/skops/io/_audit.py b/skops/io/_audit.py index 294f1ed2..1e379308 100644 --- a/skops/io/_audit.py +++ b/skops/io/_audit.py @@ -2,7 +2,7 @@ import io from contextlib import contextmanager -from typing import Any, Generator, Literal, Sequence, Type, Union # type: ignore +from typing import Any, Generator, Literal, Sequence, Type, Union from ._trusted_types import PRIMITIVE_TYPE_NAMES from ._utils import LoadContext, get_module, get_type_paths From 01a5d78b75cc48e47a719cf8db5be60f3cff7665 Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Mon, 30 Jan 2023 13:08:51 +0100 Subject: [PATCH 67/68] removed mypy ignores --- skops/hub_utils/_hf_hub.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/skops/hub_utils/_hf_hub.py b/skops/hub_utils/_hf_hub.py index 5d7a4b35..bbd49513 100644 --- a/skops/hub_utils/_hf_hub.py +++ b/skops/hub_utils/_hf_hub.py @@ -330,14 +330,14 @@ def init( model: Union[str, Path], requirements: List[str], dst: Union[str, Path], - task: Literal[ #  type: ignore + task: Literal[ "tabular-classification", "tabular-regression", "text-classification", "text-regression", ], data, - model_format: Literal[ # type: ignore + model_format: Literal[ "skops", "pickle", "auto", From 77f9f8c4b002f609d1b3d934fcdc0b7a3bb3055d Mon Sep 17 00:00:00 2001 From: merveenoyan Date: Mon, 30 Jan 2023 13:09:20 +0100 Subject: [PATCH 68/68] removed mypy ignores --- skops/hub_utils/_hf_hub.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/skops/hub_utils/_hf_hub.py b/skops/hub_utils/_hf_hub.py index bbd49513..39139a15 100644 --- a/skops/hub_utils/_hf_hub.py +++ b/skops/hub_utils/_hf_hub.py @@ -330,14 +330,14 @@ def init( model: Union[str, Path], requirements: List[str], dst: Union[str, Path], - task: Literal[ + task: Literal[ "tabular-classification", "tabular-regression", "text-classification", "text-regression", ], data, - model_format: Literal[ + model_format: Literal[ "skops", "pickle", "auto",