firehot 0.3.4__tar.gz → 0.4.1.dev1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {firehot-0.3.4 → firehot-0.4.1.dev1}/.github/workflows/ci-build.yml +14 -6
- {firehot-0.3.4 → firehot-0.4.1.dev1}/Cargo.lock +1 -1
- {firehot-0.3.4 → firehot-0.4.1.dev1}/Cargo.toml +1 -1
- {firehot-0.3.4 → firehot-0.4.1.dev1}/PKG-INFO +1 -1
- firehot-0.4.1.dev1/dist_clean/firehot-0.4.1.dev1-cp310-cp310-macosx_10_12_x86_64.whl +0 -0
- firehot-0.4.1.dev1/dist_clean/firehot-0.4.1.dev1-cp310-cp310-macosx_11_0_arm64.whl +0 -0
- firehot-0.4.1.dev1/dist_clean/firehot-0.4.1.dev1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl +0 -0
- firehot-0.4.1.dev1/dist_clean/firehot-0.4.1.dev1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl +0 -0
- firehot-0.4.1.dev1/dist_clean/firehot-0.4.1.dev1-cp311-cp311-macosx_10_12_x86_64.whl +0 -0
- firehot-0.4.1.dev1/dist_clean/firehot-0.4.1.dev1-cp311-cp311-macosx_11_0_arm64.whl +0 -0
- firehot-0.4.1.dev1/dist_clean/firehot-0.4.1.dev1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl +0 -0
- firehot-0.4.1.dev1/dist_clean/firehot-0.4.1.dev1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl +0 -0
- firehot-0.4.1.dev1/dist_clean/firehot-0.4.1.dev1-cp312-cp312-macosx_10_12_x86_64.whl +0 -0
- firehot-0.4.1.dev1/dist_clean/firehot-0.4.1.dev1-cp312-cp312-macosx_11_0_arm64.whl +0 -0
- firehot-0.4.1.dev1/dist_clean/firehot-0.4.1.dev1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl +0 -0
- firehot-0.4.1.dev1/dist_clean/firehot-0.4.1.dev1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl +0 -0
- firehot-0.4.1.dev1/dist_clean/firehot-0.4.1.dev1-cp313-cp313-macosx_10_12_x86_64.whl +0 -0
- firehot-0.4.1.dev1/dist_clean/firehot-0.4.1.dev1-cp313-cp313-macosx_11_0_arm64.whl +0 -0
- firehot-0.4.1.dev1/dist_clean/firehot-0.4.1.dev1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl +0 -0
- firehot-0.4.1.dev1/dist_clean/firehot-0.4.1.dev1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/firehot/__tests__/test_context.py +17 -1
- {firehot-0.3.4 → firehot-0.4.1.dev1}/firehot/context.py +5 -2
- {firehot-0.3.4 → firehot-0.4.1.dev1}/pyproject.toml +1 -1
- {firehot-0.3.4 → firehot-0.4.1.dev1}/src/ast.rs +114 -7
- {firehot-0.3.4 → firehot-0.4.1.dev1}/src/environment.rs +19 -11
- {firehot-0.3.4 → firehot-0.4.1.dev1}/src/layer.rs +2 -2
- {firehot-0.3.4 → firehot-0.4.1.dev1}/src/lib.rs +12 -2
- {firehot-0.3.4 → firehot-0.4.1.dev1}/src/test_utils/harness.rs +1 -1
- firehot-0.3.4/dist_clean/firehot-0.3.4-cp310-cp310-macosx_11_0_arm64.whl +0 -0
- firehot-0.3.4/dist_clean/firehot-0.3.4-cp310-cp310-manylinux_2_39_x86_64.whl +0 -0
- firehot-0.3.4/dist_clean/firehot-0.3.4-cp311-cp311-macosx_11_0_arm64.whl +0 -0
- firehot-0.3.4/dist_clean/firehot-0.3.4-cp311-cp311-manylinux_2_39_x86_64.whl +0 -0
- firehot-0.3.4/dist_clean/firehot-0.3.4-cp312-cp312-macosx_11_0_arm64.whl +0 -0
- firehot-0.3.4/dist_clean/firehot-0.3.4-cp312-cp312-manylinux_2_39_x86_64.whl +0 -0
- firehot-0.3.4/dist_clean/firehot-0.3.4-cp313-cp313-macosx_11_0_arm64.whl +0 -0
- firehot-0.3.4/dist_clean/firehot-0.3.4-cp313-cp313-manylinux_2_39_x86_64.whl +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/.DS_Store +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/.github/scripts/update_version.py +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/.github/workflows/ci-test.yml +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/.gitignore +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/Makefile +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/README.md +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/demopackage/.python-version +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/demopackage/README.md +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/demopackage/demopackage/__init__.py +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/demopackage/demopackage/app.py +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/demopackage/demopackage/dep.py +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/demopackage/demopackage/test_hotreload.py +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/demopackage/external-package/.python-version +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/demopackage/external-package/README.md +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/demopackage/external-package/external_package/__init__.py +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/demopackage/external-package/external_package/mock_imports.py +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/demopackage/external-package/pyproject.toml +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/demopackage/external-package/uv.lock +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/demopackage/pyproject.toml +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/demopackage/uv.lock +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/firehot/__init__.py +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/firehot/__tests__/__init__.py +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/firehot/__tests__/conftest.py +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/firehot/__tests__/embedded/__init__.py +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/firehot/__tests__/embedded/test_call_serializer.py +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/firehot/__tests__/embedded/test_child_entrypoint.py +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/firehot/__tests__/embedded/test_parent_entrypoint.py +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/firehot/__tests__/test_environment.py +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/firehot/__tests__/test_naming.py +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/firehot/embedded/call_serializer.py +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/firehot/embedded/child_entrypoint.py +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/firehot/embedded/parent_entrypoint.py +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/firehot/embedded/types.py +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/firehot/environment.py +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/firehot/naming.py +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/firehot/py.typed +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/media/header.png +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/src/async_resolve.rs +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/src/messages.rs +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/src/multiplex_logs.rs +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/src/process.rs +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/src/scripts.rs +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/src/test_utils/mod.rs +0 -0
- {firehot-0.3.4 → firehot-0.4.1.dev1}/uv.lock +0 -0
|
@@ -87,6 +87,7 @@ jobs:
|
|
|
87
87
|
matrix:
|
|
88
88
|
os: [ubuntu-latest, macos-latest]
|
|
89
89
|
python-version: ['3.10', '3.11', '3.12', '3.13']
|
|
90
|
+
target: [aarch64, x86_64]
|
|
90
91
|
|
|
91
92
|
steps:
|
|
92
93
|
- uses: actions/checkout@v3
|
|
@@ -103,9 +104,6 @@ jobs:
|
|
|
103
104
|
toolchain: stable
|
|
104
105
|
override: true
|
|
105
106
|
|
|
106
|
-
- name: Install maturin
|
|
107
|
-
run: pip install maturin
|
|
108
|
-
|
|
109
107
|
- name: Update version
|
|
110
108
|
if: startsWith(github.ref, 'refs/tags/v')
|
|
111
109
|
shell: bash
|
|
@@ -113,13 +111,23 @@ jobs:
|
|
|
113
111
|
pip install packaging toml
|
|
114
112
|
python .github/scripts/update_version.py ${{ github.ref_name }}
|
|
115
113
|
|
|
116
|
-
- name:
|
|
117
|
-
|
|
114
|
+
- name: build wheels
|
|
115
|
+
uses: PyO3/maturin-action@v1
|
|
116
|
+
with:
|
|
117
|
+
target: ${{ matrix.target }}
|
|
118
|
+
manylinux: auto
|
|
119
|
+
args: -vv --release --out dist --interpreter ${{ matrix.python-version }}
|
|
120
|
+
rust-toolchain: stable
|
|
121
|
+
docker-options: -e CI -e CI_TARGET=${{ matrix.target }}
|
|
122
|
+
# Already defaults to build, but we make explicit here. Any arguments should
|
|
123
|
+
# be added to args above and not here - otherwise we will affect the switch()
|
|
124
|
+
# condition handling of maturin-action.
|
|
125
|
+
command: build
|
|
118
126
|
|
|
119
127
|
- name: Upload wheels
|
|
120
128
|
uses: actions/upload-artifact@v4
|
|
121
129
|
with:
|
|
122
|
-
name: wheels-${{ matrix.os }}-py${{ matrix.python-version }}
|
|
130
|
+
name: wheels-${{ matrix.os }}-py${{ matrix.python-version }}-${{ matrix.target }}
|
|
123
131
|
path: dist/*.whl
|
|
124
132
|
|
|
125
133
|
# Collate all wheels for PyPI upload
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import importlib
|
|
2
2
|
from pathlib import Path
|
|
3
3
|
|
|
4
|
-
from firehot.context import resolve_package_metadata
|
|
4
|
+
from firehot.context import isolate_imports, resolve_package_metadata
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
def test_resolve_package_metadata(sample_package):
|
|
@@ -29,3 +29,19 @@ def test_resolve_package_metadata(sample_package):
|
|
|
29
29
|
|
|
30
30
|
# Check that the directory name matches the package name
|
|
31
31
|
assert resolved_path.name == sample_package
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def test_isolate_imports(sample_package):
|
|
35
|
+
"""
|
|
36
|
+
Test that isolate_imports correctly creates an isolated environment and accepts ignored_modules.
|
|
37
|
+
"""
|
|
38
|
+
# Test basic functionality without ignored modules
|
|
39
|
+
with isolate_imports(sample_package) as env:
|
|
40
|
+
assert env.runner_id is not None, "Expected runner_id to be set"
|
|
41
|
+
|
|
42
|
+
# Test with ignored modules
|
|
43
|
+
ignored = ["numpy", "pandas"]
|
|
44
|
+
with isolate_imports(sample_package, ignored_modules=ignored) as env:
|
|
45
|
+
assert env.runner_id is not None, "Expected runner_id to be set"
|
|
46
|
+
# The runner_id should be different from the previous one
|
|
47
|
+
assert isinstance(env.runner_id, str), "Expected runner_id to be a string"
|
|
@@ -42,18 +42,21 @@ def resolve_package_metadata(package: str) -> tuple[str, str]:
|
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
@contextmanager
|
|
45
|
-
def isolate_imports(package: str):
|
|
45
|
+
def isolate_imports(package: str, *, ignored_modules: list[str] | None = None):
|
|
46
46
|
"""
|
|
47
47
|
Context manager that isolates imports for the given package path.
|
|
48
48
|
|
|
49
49
|
:param package: Package to isolate imports. This must be importable from the current
|
|
50
50
|
virtual environment
|
|
51
|
+
:param ignored_modules: Optional list of module names to ignore during hot reloading.
|
|
52
|
+
Changes to these modules will not trigger reloads.
|
|
51
53
|
:yields: An Environment object that can be used to execute code in the isolated environment
|
|
54
|
+
|
|
52
55
|
"""
|
|
53
56
|
package_path, package_name = resolve_package_metadata(package)
|
|
54
57
|
runner_id: str | None = None
|
|
55
58
|
try:
|
|
56
|
-
runner_id = start_import_runner_rs(package_name, package_path)
|
|
59
|
+
runner_id = start_import_runner_rs(package_name, package_path, ignored_modules)
|
|
57
60
|
yield Environment(runner_id)
|
|
58
61
|
finally:
|
|
59
62
|
if runner_id:
|
|
@@ -44,11 +44,17 @@ pub struct ProjectAstManager {
|
|
|
44
44
|
package_name: String,
|
|
45
45
|
/// The root path of the project
|
|
46
46
|
project_path: String,
|
|
47
|
+
/// Set of modules to ignore when determining third-party imports
|
|
48
|
+
ignored_modules: HashSet<String>,
|
|
47
49
|
}
|
|
48
50
|
|
|
49
51
|
impl ProjectAstManager {
|
|
50
52
|
/// Create a new ProjectAstManager for the given project path
|
|
51
|
-
pub fn new(
|
|
53
|
+
pub fn new(
|
|
54
|
+
project_name: &str,
|
|
55
|
+
project_path: &str,
|
|
56
|
+
ignored_modules: Option<HashSet<String>>,
|
|
57
|
+
) -> Self {
|
|
52
58
|
debug!(
|
|
53
59
|
"Creating new ProjectAstManager for {} at {}",
|
|
54
60
|
project_name, project_path
|
|
@@ -58,6 +64,7 @@ impl ProjectAstManager {
|
|
|
58
64
|
file_imports: HashMap::new(),
|
|
59
65
|
package_name: project_name.to_string(),
|
|
60
66
|
project_path: project_path.to_string(),
|
|
67
|
+
ignored_modules: ignored_modules.unwrap_or_default(),
|
|
61
68
|
}
|
|
62
69
|
}
|
|
63
70
|
|
|
@@ -226,6 +233,11 @@ impl ProjectAstManager {
|
|
|
226
233
|
trace!("Checking if import is third party: {:?}", imp);
|
|
227
234
|
trace!("Package name: {}", self.package_name);
|
|
228
235
|
|
|
236
|
+
// If the module is in the ignored list, it's not considered third-party
|
|
237
|
+
if self.ignored_modules.contains(&imp.module) {
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
|
|
229
241
|
let is_third_party = !imp.is_relative && !imp.module.starts_with(&self.package_name);
|
|
230
242
|
|
|
231
243
|
trace!("Is third party: {}", is_third_party);
|
|
@@ -350,7 +362,7 @@ mod tests {
|
|
|
350
362
|
|
|
351
363
|
#[test]
|
|
352
364
|
fn test_project_ast_manager_initialization() {
|
|
353
|
-
let manager = ProjectAstManager::new("test_package", "/test/path");
|
|
365
|
+
let manager = ProjectAstManager::new("test_package", "/test/path", None);
|
|
354
366
|
assert_eq!(manager.get_project_path(), "/test/path");
|
|
355
367
|
assert_eq!(manager.get_package_name(), "test_package");
|
|
356
368
|
}
|
|
@@ -360,7 +372,8 @@ mod tests {
|
|
|
360
372
|
let temp_dir = TempDir::new().unwrap();
|
|
361
373
|
let file_path = create_temp_py_file(&temp_dir, "test.py", "print('hello')");
|
|
362
374
|
|
|
363
|
-
let manager =
|
|
375
|
+
let manager =
|
|
376
|
+
ProjectAstManager::new("test_package", temp_dir.path().to_str().unwrap(), None);
|
|
364
377
|
let hash_result = manager.calculate_file_hash(file_path.to_str().unwrap());
|
|
365
378
|
|
|
366
379
|
assert!(hash_result.is_ok());
|
|
@@ -573,7 +586,7 @@ def function():
|
|
|
573
586
|
|
|
574
587
|
#[test]
|
|
575
588
|
fn test_is_third_party_import() {
|
|
576
|
-
let manager = ProjectAstManager::new("my_package", "/test/path");
|
|
589
|
+
let manager = ProjectAstManager::new("my_package", "/test/path", None);
|
|
577
590
|
|
|
578
591
|
// First-party absolute import (starts with package name)
|
|
579
592
|
let first_party = ImportInfo {
|
|
@@ -612,7 +625,8 @@ def function():
|
|
|
612
625
|
let python_code = "import os\nimport sys";
|
|
613
626
|
let file_path = create_temp_py_file(&temp_dir, "test_file.py", python_code);
|
|
614
627
|
|
|
615
|
-
let mut manager =
|
|
628
|
+
let mut manager =
|
|
629
|
+
ProjectAstManager::new("test_package", temp_dir.path().to_str().unwrap(), None);
|
|
616
630
|
let imports_result = manager.process_py_file(file_path.to_str().unwrap());
|
|
617
631
|
|
|
618
632
|
assert!(imports_result.is_ok());
|
|
@@ -630,7 +644,8 @@ def function():
|
|
|
630
644
|
let file_path = create_temp_py_file(&temp_dir, "test_cache.py", python_code);
|
|
631
645
|
let path_str = file_path.to_str().unwrap();
|
|
632
646
|
|
|
633
|
-
let mut manager =
|
|
647
|
+
let mut manager =
|
|
648
|
+
ProjectAstManager::new("test_package", temp_dir.path().to_str().unwrap(), None);
|
|
634
649
|
|
|
635
650
|
// First call should parse the file
|
|
636
651
|
let _ = manager.process_py_file(path_str).unwrap();
|
|
@@ -669,7 +684,8 @@ def function():
|
|
|
669
684
|
let file1_path = create_temp_py_file(&temp_dir, "file1.py", "import os\nimport requests");
|
|
670
685
|
let _file2_path = create_temp_py_file(&temp_dir, "file2.py", "import sys\nimport flask");
|
|
671
686
|
|
|
672
|
-
let mut manager =
|
|
687
|
+
let mut manager =
|
|
688
|
+
ProjectAstManager::new("testpkg", temp_dir.path().to_str().unwrap(), None);
|
|
673
689
|
|
|
674
690
|
// Initial processing
|
|
675
691
|
let initial_imports = manager.process_all_py_files().unwrap();
|
|
@@ -700,4 +716,95 @@ def function():
|
|
|
700
716
|
assert!(!removed.is_empty());
|
|
701
717
|
assert!(removed.contains("requests"));
|
|
702
718
|
}
|
|
719
|
+
|
|
720
|
+
#[test]
|
|
721
|
+
fn test_ignored_modules() {
|
|
722
|
+
let temp_dir = TempDir::new().unwrap();
|
|
723
|
+
|
|
724
|
+
// Create a Python file with various imports
|
|
725
|
+
let python_code = r#"
|
|
726
|
+
import os
|
|
727
|
+
import sys
|
|
728
|
+
import requests
|
|
729
|
+
from pandas import DataFrame
|
|
730
|
+
from my_package.utils import helper
|
|
731
|
+
from . import local_module
|
|
732
|
+
"#;
|
|
733
|
+
create_temp_py_file(&temp_dir, "test_imports.py", python_code);
|
|
734
|
+
|
|
735
|
+
// Create a manager with ignored modules
|
|
736
|
+
let mut ignored_modules = HashSet::new();
|
|
737
|
+
ignored_modules.insert("pandas".to_string());
|
|
738
|
+
ignored_modules.insert("requests".to_string());
|
|
739
|
+
|
|
740
|
+
let mut manager = ProjectAstManager::new(
|
|
741
|
+
"my_package",
|
|
742
|
+
temp_dir.path().to_str().unwrap(),
|
|
743
|
+
Some(ignored_modules),
|
|
744
|
+
);
|
|
745
|
+
|
|
746
|
+
// Process all files and get third-party imports
|
|
747
|
+
let third_party_imports = manager.process_all_py_files().unwrap();
|
|
748
|
+
|
|
749
|
+
// Verify that ignored modules are not included in third-party imports
|
|
750
|
+
assert!(
|
|
751
|
+
!third_party_imports.contains("pandas"),
|
|
752
|
+
"pandas should be ignored"
|
|
753
|
+
);
|
|
754
|
+
assert!(
|
|
755
|
+
!third_party_imports.contains("requests"),
|
|
756
|
+
"requests should be ignored"
|
|
757
|
+
);
|
|
758
|
+
|
|
759
|
+
// But other third-party modules should be included
|
|
760
|
+
assert!(third_party_imports.contains("os"), "os should be included");
|
|
761
|
+
assert!(
|
|
762
|
+
third_party_imports.contains("sys"),
|
|
763
|
+
"sys should be included"
|
|
764
|
+
);
|
|
765
|
+
|
|
766
|
+
// First-party imports should still be excluded
|
|
767
|
+
assert!(
|
|
768
|
+
!third_party_imports.contains("my_package.utils"),
|
|
769
|
+
"my_package.utils should not be included"
|
|
770
|
+
);
|
|
771
|
+
assert!(
|
|
772
|
+
!third_party_imports.contains("local_module"),
|
|
773
|
+
"local_module should not be included"
|
|
774
|
+
);
|
|
775
|
+
|
|
776
|
+
// Now test with no ignored modules
|
|
777
|
+
let mut manager_no_ignore =
|
|
778
|
+
ProjectAstManager::new("my_package", temp_dir.path().to_str().unwrap(), None);
|
|
779
|
+
|
|
780
|
+
let all_third_party_imports = manager_no_ignore.process_all_py_files().unwrap();
|
|
781
|
+
|
|
782
|
+
// Without ignore list, all third-party modules should be included
|
|
783
|
+
assert!(
|
|
784
|
+
all_third_party_imports.contains("pandas"),
|
|
785
|
+
"pandas should be included when not ignored"
|
|
786
|
+
);
|
|
787
|
+
assert!(
|
|
788
|
+
all_third_party_imports.contains("requests"),
|
|
789
|
+
"requests should be included when not ignored"
|
|
790
|
+
);
|
|
791
|
+
assert!(
|
|
792
|
+
all_third_party_imports.contains("os"),
|
|
793
|
+
"os should be included"
|
|
794
|
+
);
|
|
795
|
+
assert!(
|
|
796
|
+
all_third_party_imports.contains("sys"),
|
|
797
|
+
"sys should be included"
|
|
798
|
+
);
|
|
799
|
+
|
|
800
|
+
// First-party imports should still be excluded
|
|
801
|
+
assert!(
|
|
802
|
+
!all_third_party_imports.contains("my_package.utils"),
|
|
803
|
+
"my_package.utils should not be included"
|
|
804
|
+
);
|
|
805
|
+
assert!(
|
|
806
|
+
!all_third_party_imports.contains("local_module"),
|
|
807
|
+
"local_module should not be included"
|
|
808
|
+
);
|
|
809
|
+
}
|
|
703
810
|
}
|
|
@@ -30,9 +30,13 @@ pub struct Environment {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
impl Environment {
|
|
33
|
-
pub fn new(
|
|
33
|
+
pub fn new(
|
|
34
|
+
project_name: &str,
|
|
35
|
+
project_path: &str,
|
|
36
|
+
ignored_modules: Option<HashSet<String>>,
|
|
37
|
+
) -> Self {
|
|
34
38
|
// Create a new AST manager for this project
|
|
35
|
-
let ast_manager = ProjectAstManager::new(project_name, project_path);
|
|
39
|
+
let ast_manager = ProjectAstManager::new(project_name, project_path, ignored_modules);
|
|
36
40
|
info!("Created AST manager for project: {}", project_name);
|
|
37
41
|
|
|
38
42
|
Self {
|
|
@@ -45,9 +49,13 @@ impl Environment {
|
|
|
45
49
|
}
|
|
46
50
|
|
|
47
51
|
/// Create a new Environment in test mode (buffers output instead of printing)
|
|
48
|
-
pub fn new_for_test(
|
|
52
|
+
pub fn new_for_test(
|
|
53
|
+
project_name: &str,
|
|
54
|
+
project_path: &str,
|
|
55
|
+
ignored_modules: Option<HashSet<String>>,
|
|
56
|
+
) -> Self {
|
|
49
57
|
// Create a new AST manager for this project
|
|
50
|
-
let ast_manager = ProjectAstManager::new(project_name, project_path);
|
|
58
|
+
let ast_manager = ProjectAstManager::new(project_name, project_path, ignored_modules);
|
|
51
59
|
info!("Created AST manager for project: {}", project_name);
|
|
52
60
|
|
|
53
61
|
Self {
|
|
@@ -647,7 +655,7 @@ mod tests {
|
|
|
647
655
|
// Create a simple Python project
|
|
648
656
|
create_temp_py_file(&temp_dir, "main.py", "print('Hello, world!')");
|
|
649
657
|
|
|
650
|
-
let mut runner = Environment::new("test_package", dir_path);
|
|
658
|
+
let mut runner = Environment::new("test_package", dir_path, None);
|
|
651
659
|
assert_eq!(runner.ast_manager.get_project_path(), dir_path);
|
|
652
660
|
|
|
653
661
|
// Boot the environment before checking it
|
|
@@ -668,7 +676,7 @@ mod tests {
|
|
|
668
676
|
// Create a simple Python project with initial imports
|
|
669
677
|
create_temp_py_file(&temp_dir, "main.py", "import os\nimport sys");
|
|
670
678
|
|
|
671
|
-
let mut runner = Environment::new("test_package", dir_path);
|
|
679
|
+
let mut runner = Environment::new("test_package", dir_path, None);
|
|
672
680
|
|
|
673
681
|
// Boot the environment before accessing it
|
|
674
682
|
runner.boot_main().expect("Failed to boot main environment");
|
|
@@ -750,7 +758,7 @@ def main():
|
|
|
750
758
|
crate::test_utils::harness::prepare_script_for_isolation(python_script, "main")
|
|
751
759
|
.expect("Failed to prepare script for isolation");
|
|
752
760
|
|
|
753
|
-
let mut runner = Environment::new("test_package", &python_env.container_path);
|
|
761
|
+
let mut runner = Environment::new("test_package", &python_env.container_path, None);
|
|
754
762
|
|
|
755
763
|
// Boot the environment before accessing it
|
|
756
764
|
runner.boot_main().expect("Failed to boot main environment");
|
|
@@ -800,7 +808,7 @@ def main():
|
|
|
800
808
|
let temp_dir = TempDir::new().unwrap();
|
|
801
809
|
let dir_path = temp_dir.path().to_str().unwrap();
|
|
802
810
|
|
|
803
|
-
let mut runner = Environment::new("test_package", dir_path);
|
|
811
|
+
let mut runner = Environment::new("test_package", dir_path, None);
|
|
804
812
|
|
|
805
813
|
// Boot the environment before accessing it
|
|
806
814
|
runner.boot_main().expect("Failed to boot main environment");
|
|
@@ -885,7 +893,7 @@ def main():
|
|
|
885
893
|
let temp_dir = TempDir::new().unwrap();
|
|
886
894
|
let dir_path = temp_dir.path().to_str().unwrap();
|
|
887
895
|
|
|
888
|
-
let mut runner = Environment::new("test_package", dir_path);
|
|
896
|
+
let mut runner = Environment::new("test_package", dir_path, None);
|
|
889
897
|
|
|
890
898
|
// Boot the environment before stopping it
|
|
891
899
|
runner.boot_main().expect("Failed to boot main environment");
|
|
@@ -921,7 +929,7 @@ def main():
|
|
|
921
929
|
crate::test_utils::harness::prepare_script_for_isolation(python_script, "main")?;
|
|
922
930
|
|
|
923
931
|
// Create and boot the Environment
|
|
924
|
-
let mut runner = Environment::new("test_package", dir_path);
|
|
932
|
+
let mut runner = Environment::new("test_package", dir_path, None);
|
|
925
933
|
runner.boot_main()?;
|
|
926
934
|
|
|
927
935
|
// Execute the script in isolation - this should not fail at this point
|
|
@@ -980,7 +988,7 @@ def main():
|
|
|
980
988
|
.expect("Failed to prepare long-running script for isolation");
|
|
981
989
|
|
|
982
990
|
// Create and boot environment
|
|
983
|
-
let mut runner = Environment::new("test_package", &python_env.container_path);
|
|
991
|
+
let mut runner = Environment::new("test_package", &python_env.container_path, None);
|
|
984
992
|
runner.boot_main().expect("Failed to boot main environment");
|
|
985
993
|
|
|
986
994
|
// Execute the long-running function
|
|
@@ -648,7 +648,7 @@ def main():
|
|
|
648
648
|
crate::test_utils::harness::prepare_script_for_isolation(python_script, "main")?;
|
|
649
649
|
|
|
650
650
|
// Create and boot the Environment
|
|
651
|
-
let mut runner = Environment::new_for_test("test_package", dir_path);
|
|
651
|
+
let mut runner = Environment::new_for_test("test_package", dir_path, None);
|
|
652
652
|
runner.boot_main()?;
|
|
653
653
|
|
|
654
654
|
// Execute the script in isolation
|
|
@@ -725,7 +725,7 @@ def main():
|
|
|
725
725
|
crate::test_utils::harness::prepare_script_for_isolation(python_script, "main")?;
|
|
726
726
|
|
|
727
727
|
// Create and boot the Environment
|
|
728
|
-
let mut runner = Environment::new_for_test("test_package", dir_path);
|
|
728
|
+
let mut runner = Environment::new_for_test("test_package", dir_path, None);
|
|
729
729
|
runner.boot_main()?;
|
|
730
730
|
|
|
731
731
|
// Execute the script in isolation
|
|
@@ -7,6 +7,7 @@ use std::{collections::HashMap, time::Instant};
|
|
|
7
7
|
use pyo3::exceptions::PyRuntimeError;
|
|
8
8
|
use pyo3::prelude::*;
|
|
9
9
|
use pyo3::types::PyDict;
|
|
10
|
+
use std::collections::HashSet;
|
|
10
11
|
use std::sync::Mutex;
|
|
11
12
|
use uuid::Uuid;
|
|
12
13
|
|
|
@@ -86,7 +87,12 @@ fn firehot(_py: Python, m: &PyModule) -> PyResult<()> {
|
|
|
86
87
|
|
|
87
88
|
/// Initialize and start the import runner, returning a unique identifier
|
|
88
89
|
#[pyfunction]
|
|
89
|
-
fn start_import_runner(
|
|
90
|
+
fn start_import_runner(
|
|
91
|
+
_py: Python,
|
|
92
|
+
project_name: &str,
|
|
93
|
+
package_path: &str,
|
|
94
|
+
ignored_modules: Option<Vec<String>>,
|
|
95
|
+
) -> PyResult<String> {
|
|
90
96
|
// Generate a unique ID for this runner
|
|
91
97
|
let env_id = Uuid::new_v4().to_string();
|
|
92
98
|
|
|
@@ -98,9 +104,13 @@ fn start_import_runner(_py: Python, project_name: &str, package_path: &str) -> P
|
|
|
98
104
|
project_name.cyan().bold()
|
|
99
105
|
);
|
|
100
106
|
|
|
107
|
+
// Convert ignored_modules from Vec to HashSet if provided
|
|
108
|
+
let ignored_modules_set =
|
|
109
|
+
ignored_modules.map(|modules| modules.into_iter().collect::<HashSet<String>>());
|
|
110
|
+
|
|
101
111
|
// Create the runner object
|
|
102
112
|
info!("Creating environment with ID: {}", env_id);
|
|
103
|
-
let mut runner = environment::Environment::new(project_name, package_path);
|
|
113
|
+
let mut runner = environment::Environment::new(project_name, package_path, ignored_modules_set);
|
|
104
114
|
|
|
105
115
|
runner.boot_main().map_err(|e| {
|
|
106
116
|
error!("Failed to boot main: {}", e);
|
|
@@ -253,7 +253,7 @@ def main():
|
|
|
253
253
|
let (pickled_data, python_env) = prepare_script_for_isolation(python_script, "main")?;
|
|
254
254
|
|
|
255
255
|
// Create a mock Environment
|
|
256
|
-
let mut runner = Environment::new("test_package", &python_env.container_path);
|
|
256
|
+
let mut runner = Environment::new("test_package", &python_env.container_path, None);
|
|
257
257
|
|
|
258
258
|
// Boot the environment
|
|
259
259
|
runner.boot_main()?;
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{firehot-0.3.4 → firehot-0.4.1.dev1}/demopackage/external-package/external_package/__init__.py
RENAMED
|
File without changes
|
{firehot-0.3.4 → firehot-0.4.1.dev1}/demopackage/external-package/external_package/mock_imports.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|