Download tests/unit/test_python_sandbox.py from rohitdeshmukh318/Data_analysis_agent: direct link, hf CLI and curl.
- Browser
- Download file 4.4 kB
-
https://huggingface.co/spaces/rohitdeshmukh318/Data_analysis_agent/resolve/main/tests/unit/test_python_sandbox.py
- Command line
-
hf download hf://spaces/rohitdeshmukh318/Data_analysis_agent/tests/unit/test_python_sandbox.py
-
curl -L -o test_python_sandbox.py https://huggingface.co/spaces/rohitdeshmukh318/Data_analysis_agent/resolve/main/tests/unit/test_python_sandbox.py
4.4 kB
| """ | |
| tests/unit/test_python_sandbox.py | |
| Tests for RestrictedPython-based Pandas execution sandbox. | |
| """ | |
| import pandas as pd | |
| import pytest | |
| from sandbox.python_sandbox import validate_python, run_pandas | |
| def df(): | |
| return pd.DataFrame({ | |
| "product": ["Widget", "Gadget", "Widget", "Doohickey"], | |
| "amount": [99.99, 149.99, 99.99, 49.99], | |
| "region": ["North", "South", "North", "East"], | |
| }) | |
| # ββ validate_python βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| class TestValidatePython: | |
| def test_safe_code_passes(self): | |
| code = "result = df.groupby('product')['amount'].sum().to_frame()" | |
| ok, err = validate_python(code) | |
| assert ok, err | |
| def test_blocks_open(self): | |
| ok, err = validate_python("open('/etc/passwd')") | |
| assert not ok | |
| assert "open" in err | |
| def test_blocks_os_import(self): | |
| ok, err = validate_python("import os\nresult = df") | |
| assert not ok | |
| def test_blocks_subprocess(self): | |
| ok, err = validate_python("import subprocess\nresult = df") | |
| assert not ok | |
| def test_blocks_dunder_attr(self): | |
| ok, err = validate_python("df.__class__.__bases__") | |
| assert not ok | |
| def test_blocks_exec(self): | |
| ok, err = validate_python("exec('import os')") | |
| assert not ok | |
| def test_blocks_eval(self): | |
| ok, err = validate_python("eval('1+1')") | |
| assert not ok | |
| def test_allows_pandas_import(self): | |
| ok, err = validate_python("import pandas as pd\nresult = df") | |
| assert ok | |
| def test_allows_numpy_import(self): | |
| ok, err = validate_python("import numpy as np\nresult = df") | |
| assert ok | |
| def test_blocks_requests_import(self): | |
| ok, err = validate_python("import requests\nresult = df") | |
| assert not ok | |
| def test_syntax_error(self): | |
| ok, err = validate_python("def broken(:\n pass") | |
| assert not ok | |
| # ββ run_pandas ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| class TestRunPandas: | |
| def test_basic_groupby(self, df): | |
| code = "result = df.groupby('product')['amount'].sum().to_frame()" | |
| out = run_pandas(code, df) | |
| assert isinstance(out, pd.DataFrame) | |
| assert "amount" in out.columns | |
| def test_filter(self, df): | |
| code = "result = df[df['region'] == 'North'].copy()" | |
| out = run_pandas(code, df) | |
| assert len(out) == 2 | |
| def test_new_column(self, df): | |
| code = "result = df.copy()\nresult['doubled'] = result['amount'] * 2" | |
| out = run_pandas(code, df) | |
| assert "doubled" in out.columns | |
| def test_series_result_coerced_to_dataframe(self, df): | |
| code = "result = df['amount']" | |
| out = run_pandas(code, df) | |
| assert isinstance(out, pd.DataFrame) | |
| def test_missing_result_raises(self, df): | |
| with pytest.raises(ValueError, match="result"): | |
| run_pandas("x = 1", df) | |
| def test_non_dataframe_result_raises(self, df): | |
| with pytest.raises(TypeError): | |
| run_pandas("result = 42", df) | |
| def test_safety_block_raises_permission_error(self, df): | |
| with pytest.raises(PermissionError, match="SAFETY_BLOCK"): | |
| run_pandas("import os\nresult = df", df) | |
| def test_augmented_assignment(self, df): | |
| # RestrictedPython disallows augmented assignment on subscripts (result['col'] += x) | |
| # Use explicit assignment instead β the sandbox enforces this restriction correctly | |
| code = "result = df.copy()\nresult['amount'] = result['amount'] + 10" | |
| out = run_pandas(code, df) | |
| assert out["amount"].min() > 50 | |
| def test_sort_and_limit(self, df): | |
| code = "result = df.sort_values('amount', ascending=False).head(2)" | |
| out = run_pandas(code, df) | |
| assert len(out) == 2 | |
| assert out.iloc[0]["amount"] == pytest.approx(149.99) | |
| def test_pivot_table(self, df): | |
| code = """ | |
| result = df.pivot_table( | |
| index='region', values='amount', aggfunc='sum' | |
| ).reset_index() | |
| """ | |
| out = run_pandas(code, df) | |
| assert "region" in out.columns | |