Repository: huggingface/smolagents

Issue:
Code execution failed at line 'from sklearn.linear_model import LinearRegression' due to: AttributeError:module 'scipy.sparse._coo' has no attribute 'upcast'
I run following codes in local PC as well as colab. Error as indicated by the title occured when smolagents try to run the python codes suggested by deepseek comprised "from sklearn.linear_model import LinearRegression". Similar error happens in google colab as well. Please advice.




from smolagents import HfApiModel, CodeAgent
from pathlib import Path
from dotenv import load_dotenv
import os
#from sklearn.linear_model import LinearRegression

env_path = Path(__file__).resolve().parent.parent/ 'rag_test_branches' / '.env'
load_dotenv(dotenv_path=env_path)
TOGETHER_API_KEY = os.environ["TOGETHER_API_KEY"] 

model = HfApiModel(model_id="deepseek-ai/DeepSeek-V3", provider="together",token=TOGETHER_API_KEY, max_tokens = 2000)

agent = CodeAgent(
    tools=[],
    model=model,
    additional_authorized_imports=["numpy", "pandas", "matplotlib.pyplot", "seaborn","sklearn"],
    #use_e2b_executor=True,
    #max_iterations=10,
)

# Get the current working directory
current_directory = os.getcwd()

# Define the path to the "figures" directory
figures_path = os.path.join(current_directory, 'figures')

if not os.path.isdir(figures_path):
    os.mkdir("./figures")

additional_notes = """
### Variable Notes
pclass: A proxy for socio-economic status (SES)
1st = Upper
2nd = Middle
3rd = Lower
age: Age is fractional if less than 1. If the age is estimated, is it in the form of xx.5
sibsp: The dataset defines family relations in this way...
Sibling = brother, sister, stepbrother, stepsister
Spouse = husband, wife (mistresses and fiancés were ignored)
parch: The dataset defines family relations in this way...
Parent = mother, father
Child = daughter, son, stepdaughter, stepson
Some children travelled only with a nanny, therefore parch=0 for them.
"""

#According to the variables you have, begin by listing 3 interesting questions that could be asked on this data, for instance about specific correlation with survival rate.
#Then answer these questions one by one, by finding the relevant numbers.
analysis = agent.run(
    """You are an expert data analyst.
Please load the source file and analyze its content.

Meanwhile, plot some figures using matplotlib/seaborn and save them to the (already existing) folder './figures/': take care to clear each figure with plt.clf() before doing another plot.
According to the variables you have, do calculation related to linear regression.
In your final answer: summarize these correlations and trends
After each number derive real worlds insights, for instance: "Correlation between is_december and boredness is 1.3453, which suggest people are more bored in winter".
Your final answer should have at least 3 numbered and detailed parts.
""",
    additional_args=dict(additional_notes=additional_notes, source_file="titanic/train.csv"),
)


Discussion:

Patch:
diff --git a/examples/open_deep_research/README.md b/examples/open_deep_research/README.md
index 915bfc8..1324e46 100644
--- a/examples/open_deep_research/README.md
+++ b/examples/open_deep_research/README.md
@@ -13,7 +13,7 @@ pip install -r requirements.txt
 
 And install smolagents dev version
 ```bash
-pip install smolagents[dev]
+pip install -e ../../.[dev]
 ```
 
 Then you're good to go! Run the run.py script, as in:
diff --git a/src/smolagents/local_python_executor.py b/src/smolagents/local_python_executor.py
index 9912618..c6c74ac 100644
--- a/src/smolagents/local_python_executor.py
+++ b/src/smolagents/local_python_executor.py
@@ -1042,7 +1042,7 @@ def get_safe_module(raw_module, authorized_imports, visited=None):
 
         try:
             attr_value = getattr(raw_module, attr_name)
-        except ImportError as e:
+        except (ImportError, AttributeError) as e:
             # lazy / dynamic loading module -> INFO log and skip
             logger.info(
                 f"Skipping import error while copying {raw_module.__name__}.{attr_name}: {type(e).__name__} - {e}"


Test patch:
diff --git a/tests/test_local_python_executor.py b/tests/test_local_python_executor.py
index 91c6815..f88aa1b 100644
--- a/tests/test_local_python_executor.py
+++ b/tests/test_local_python_executor.py
@@ -1003,6 +1003,16 @@ texec(tcompile("1 + 1", "no filename", "exec"))
         dangerous_code = "import os; os.listdir('./')"
         evaluate_python_code(dangerous_code, authorized_imports=["*"])
 
+    @pytest.mark.filterwarnings("ignore::DeprecationWarning")
+    def test_can_import_scipy_if_explicitly_authorized(self):
+        code = "import scipy"
+        evaluate_python_code(code, authorized_imports=["scipy"])
+
+    @pytest.mark.filterwarnings("ignore::DeprecationWarning")
+    def test_can_import_sklearn_if_explicitly_authorized(self):
+        code = "import sklearn"
+        evaluate_python_code(code, authorized_imports=["sklearn"])
+
 
 @pytest.mark.parametrize(
     "code, expected_result",