|
11 | 11 | from rsconnect.exception import RSConnectException |
12 | 12 | from rsconnect.environment import Environment, which_python |
13 | 13 | from rsconnect.subprocesses.inspect_environment import ( |
| 14 | + EnvironmentException, |
14 | 15 | detect_environment, |
15 | 16 | filter_pip_freeze_output, |
16 | 17 | get_default_locale, |
@@ -83,7 +84,7 @@ def test_requirements_override(self): |
83 | 84 | assert result.source == "file" |
84 | 85 |
|
85 | 86 | def test_pip_freeze(self): |
86 | | - result = Environment.create_python_environment(get_dir("pip2")) |
| 87 | + result = Environment.create_python_environment(get_dir("pip2"), requirements_file=None) |
87 | 88 |
|
88 | 89 | # these are the dependencies declared in our pyproject.toml |
89 | 90 | self.assertIn("six", result.contents) |
@@ -223,22 +224,30 @@ def test_is_not_executable(self): |
223 | 224 |
|
224 | 225 | class TestPythonVersionRequirements: |
225 | 226 | def test_pyproject_toml(self): |
226 | | - env = Environment.create_python_environment(os.path.join(TESTDATA, "python-project", "using_pyproject")) |
| 227 | + env = Environment.create_python_environment( |
| 228 | + os.path.join(TESTDATA, "python-project", "using_pyproject"), requirements_file=None |
| 229 | + ) |
227 | 230 | assert env.python_interpreter == sys.executable |
228 | 231 | assert env.python_version_requirement == ">=3.8" |
229 | 232 |
|
230 | 233 | def test_python_version(self): |
231 | | - env = Environment.create_python_environment(os.path.join(TESTDATA, "python-project", "using_pyversion")) |
| 234 | + env = Environment.create_python_environment( |
| 235 | + os.path.join(TESTDATA, "python-project", "using_pyversion"), requirements_file=None |
| 236 | + ) |
232 | 237 | assert env.python_interpreter == sys.executable |
233 | 238 | assert env.python_version_requirement == ">=3.8,<3.12" |
234 | 239 |
|
235 | 240 | def test_all_of_them(self): |
236 | | - env = Environment.create_python_environment(os.path.join(TESTDATA, "python-project", "allofthem")) |
| 241 | + env = Environment.create_python_environment( |
| 242 | + os.path.join(TESTDATA, "python-project", "allofthem"), requirements_file=None |
| 243 | + ) |
237 | 244 | assert env.python_interpreter == sys.executable |
238 | 245 | assert env.python_version_requirement == ">=3.8,<3.12" |
239 | 246 |
|
240 | 247 | def test_missing(self): |
241 | | - env = Environment.create_python_environment(os.path.join(TESTDATA, "python-project", "empty")) |
| 248 | + env = Environment.create_python_environment( |
| 249 | + os.path.join(TESTDATA, "python-project", "empty"), requirements_file=None |
| 250 | + ) |
242 | 251 | assert env.python_interpreter == sys.executable |
243 | 252 | assert env.python_version_requirement is None |
244 | 253 |
|
@@ -393,3 +402,44 @@ def test_python_interpreter(self): |
393 | 402 | "Please use a .python-version file to force a specific interpreter version." |
394 | 403 | ) |
395 | 404 | assert result.python == current_python_version |
| 405 | + |
| 406 | + |
| 407 | +class TestRequirementsFileRequired: |
| 408 | + """When a requirements file is requested (the default), it must exist. |
| 409 | + When force-generate is used (requirements_file=None), pip freeze is used regardless.""" |
| 410 | + |
| 411 | + def test_requirements_requested_and_file_exists(self): |
| 412 | + """Default behavior with requirements.txt present succeeds and reads the file.""" |
| 413 | + result = Environment.create_python_environment(get_dir("pip1")) |
| 414 | + assert result.source == "file" |
| 415 | + assert result.filename == "requirements.txt" |
| 416 | + |
| 417 | + def test_requirements_requested_and_file_missing(self): |
| 418 | + """Default behavior without requirements.txt raises an error.""" |
| 419 | + with pytest.raises(RSConnectException, match="does not exist"): |
| 420 | + Environment.create_python_environment(get_dir("pip2")) |
| 421 | + |
| 422 | + def test_force_generate_and_file_exists(self): |
| 423 | + """Force-generate ignores the existing requirements.txt and uses pip freeze.""" |
| 424 | + result = Environment.create_python_environment(get_dir("pip1"), requirements_file=None) |
| 425 | + assert result.source == "pip_freeze" |
| 426 | + |
| 427 | + def test_force_generate_and_file_missing(self): |
| 428 | + """Force-generate works even without requirements.txt.""" |
| 429 | + result = Environment.create_python_environment(get_dir("pip2"), requirements_file=None) |
| 430 | + assert result.source == "pip_freeze" |
| 431 | + |
| 432 | + def test_detect_environment_requires_file(self): |
| 433 | + """Subprocess-level: detect_environment errors when the file is missing.""" |
| 434 | + with pytest.raises(EnvironmentException, match="was not found"): |
| 435 | + detect_environment(get_dir("pip2"), requirements_file="requirements.txt") |
| 436 | + |
| 437 | + def test_detect_environment_reads_file(self): |
| 438 | + """Subprocess-level: detect_environment reads the file when present.""" |
| 439 | + result = detect_environment(get_dir("pip1"), requirements_file="requirements.txt") |
| 440 | + assert result.source == "file" |
| 441 | + |
| 442 | + def test_detect_environment_force_generate(self): |
| 443 | + """Subprocess-level: detect_environment uses pip freeze when requirements_file=None.""" |
| 444 | + result = detect_environment(get_dir("pip2"), requirements_file=None) |
| 445 | + assert result.source == "pip_freeze" |
0 commit comments