grimp 3.8__tar.gz → 3.8.2__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.
Files changed (48) hide show
  1. {grimp-3.8 → grimp-3.8.2}/PKG-INFO +2 -1
  2. {grimp-3.8 → grimp-3.8.2}/pyproject.toml +2 -1
  3. {grimp-3.8 → grimp-3.8.2}/src/grimp/__init__.py +1 -1
  4. {grimp-3.8 → grimp-3.8.2}/src/grimp/application/usecases.py +28 -21
  5. {grimp-3.8 → grimp-3.8.2}/README.rst +0 -0
  6. {grimp-3.8 → grimp-3.8.2}/rust/.cargo/config.toml +0 -0
  7. {grimp-3.8 → grimp-3.8.2}/rust/Cargo.lock +0 -0
  8. {grimp-3.8 → grimp-3.8.2}/rust/Cargo.toml +0 -0
  9. {grimp-3.8 → grimp-3.8.2}/rust/src/errors.rs +0 -0
  10. {grimp-3.8 → grimp-3.8.2}/rust/src/exceptions.rs +0 -0
  11. {grimp-3.8 → grimp-3.8.2}/rust/src/graph/direct_import_queries.rs +0 -0
  12. {grimp-3.8 → grimp-3.8.2}/rust/src/graph/graph_manipulation.rs +0 -0
  13. {grimp-3.8 → grimp-3.8.2}/rust/src/graph/hierarchy_queries.rs +0 -0
  14. {grimp-3.8 → grimp-3.8.2}/rust/src/graph/higher_order_queries.rs +0 -0
  15. {grimp-3.8 → grimp-3.8.2}/rust/src/graph/import_chain_queries.rs +0 -0
  16. {grimp-3.8 → grimp-3.8.2}/rust/src/graph/mod.rs +0 -0
  17. {grimp-3.8 → grimp-3.8.2}/rust/src/graph/pathfinding.rs +0 -0
  18. {grimp-3.8 → grimp-3.8.2}/rust/src/lib.rs +0 -0
  19. {grimp-3.8 → grimp-3.8.2}/rust/src/module_expressions.rs +0 -0
  20. {grimp-3.8 → grimp-3.8.2}/rust/tests/large.rs +0 -0
  21. {grimp-3.8 → grimp-3.8.2}/rust/tests/large_graph.json +0 -0
  22. {grimp-3.8 → grimp-3.8.2}/src/grimp/adaptors/__init__.py +0 -0
  23. {grimp-3.8 → grimp-3.8.2}/src/grimp/adaptors/caching.py +0 -0
  24. {grimp-3.8 → grimp-3.8.2}/src/grimp/adaptors/filesystem.py +0 -0
  25. {grimp-3.8 → grimp-3.8.2}/src/grimp/adaptors/graph.py +0 -0
  26. {grimp-3.8 → grimp-3.8.2}/src/grimp/adaptors/importscanner.py +0 -0
  27. {grimp-3.8 → grimp-3.8.2}/src/grimp/adaptors/modulefinder.py +0 -0
  28. {grimp-3.8 → grimp-3.8.2}/src/grimp/adaptors/packagefinder.py +0 -0
  29. {grimp-3.8 → grimp-3.8.2}/src/grimp/adaptors/timing.py +0 -0
  30. {grimp-3.8 → grimp-3.8.2}/src/grimp/algorithms/__init__.py +0 -0
  31. {grimp-3.8 → grimp-3.8.2}/src/grimp/algorithms/shortest_path.py +0 -0
  32. {grimp-3.8 → grimp-3.8.2}/src/grimp/application/__init__.py +0 -0
  33. {grimp-3.8 → grimp-3.8.2}/src/grimp/application/config.py +0 -0
  34. {grimp-3.8 → grimp-3.8.2}/src/grimp/application/ports/__init__.py +0 -0
  35. {grimp-3.8 → grimp-3.8.2}/src/grimp/application/ports/caching.py +0 -0
  36. {grimp-3.8 → grimp-3.8.2}/src/grimp/application/ports/filesystem.py +0 -0
  37. {grimp-3.8 → grimp-3.8.2}/src/grimp/application/ports/graph.py +0 -0
  38. {grimp-3.8 → grimp-3.8.2}/src/grimp/application/ports/importscanner.py +0 -0
  39. {grimp-3.8 → grimp-3.8.2}/src/grimp/application/ports/modulefinder.py +0 -0
  40. {grimp-3.8 → grimp-3.8.2}/src/grimp/application/ports/packagefinder.py +0 -0
  41. {grimp-3.8 → grimp-3.8.2}/src/grimp/application/ports/timing.py +0 -0
  42. {grimp-3.8 → grimp-3.8.2}/src/grimp/domain/__init__.py +0 -0
  43. {grimp-3.8 → grimp-3.8.2}/src/grimp/domain/analysis.py +0 -0
  44. {grimp-3.8 → grimp-3.8.2}/src/grimp/domain/valueobjects.py +0 -0
  45. {grimp-3.8 → grimp-3.8.2}/src/grimp/exceptions.py +0 -0
  46. {grimp-3.8 → grimp-3.8.2}/src/grimp/helpers.py +0 -0
  47. {grimp-3.8 → grimp-3.8.2}/src/grimp/main.py +0 -0
  48. {grimp-3.8 → grimp-3.8.2}/src/grimp/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: grimp
3
- Version: 3.8
3
+ Version: 3.8.2
4
4
  Classifier: Development Status :: 5 - Production/Stable
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: License :: OSI Approved :: BSD License
@@ -16,6 +16,7 @@ Classifier: Programming Language :: Python :: 3.13
16
16
  Classifier: Programming Language :: Python :: Implementation :: CPython
17
17
  Classifier: Programming Language :: Rust
18
18
  Classifier: Topic :: Utilities
19
+ Requires-Dist: joblib>=1.3.0
19
20
  Requires-Dist: typing-extensions>=3.10.0.0
20
21
  License-File: LICENSE
21
22
  License-File: AUTHORS.rst
@@ -8,7 +8,7 @@ module-name = "grimp._rustgrimp"
8
8
 
9
9
  [project]
10
10
  name = "grimp"
11
- version = "3.8"
11
+ version = "3.8.2"
12
12
  license = {text = "BSD 2-Clause License"}
13
13
  description = "Builds a queryable graph of the imports within one or more Python packages."
14
14
  authors = [
@@ -16,6 +16,7 @@ authors = [
16
16
  ]
17
17
  requires-python = ">=3.9"
18
18
  dependencies = [
19
+ "joblib>=1.3.0",
19
20
  "typing-extensions>=3.10.0.0",
20
21
  ]
21
22
  classifiers = [
@@ -1,4 +1,4 @@
1
- __version__ = "3.8"
1
+ __version__ = "3.8.2"
2
2
 
3
3
  from .application.ports.graph import DetailedImport, ImportGraph, Import
4
4
  from .domain.analysis import PackageDependency, Route
@@ -3,9 +3,10 @@ Use cases handle application logic.
3
3
  """
4
4
 
5
5
  from typing import Dict, Sequence, Set, Type, Union, cast, Iterable, Collection
6
- import multiprocessing
7
6
  import math
8
7
 
8
+ import joblib # type: ignore
9
+
9
10
  from ..application.ports import caching
10
11
  from ..application.ports.filesystem import AbstractFileSystem
11
12
  from ..application.ports.graph import ImportGraph
@@ -14,14 +15,19 @@ from ..application.ports.modulefinder import AbstractModuleFinder, FoundPackage,
14
15
  from ..application.ports.packagefinder import AbstractPackageFinder
15
16
  from ..domain.valueobjects import DirectImport, Module
16
17
  from .config import settings
18
+ import os
17
19
 
18
20
 
19
21
  class NotSupplied:
20
22
  pass
21
23
 
22
24
 
25
+ # Calling code can set this environment variable if it wants to tune when to switch to
26
+ # multiprocessing, or set it to a large number to disable it altogether.
27
+ MIN_NUMBER_OF_MODULES_TO_SCAN_USING_MULTIPROCESSING_ENV_NAME = "GRIMP_MIN_MULTIPROCESSING_MODULES"
23
28
  # This is an arbitrary number, but setting it too low slows down our functional tests considerably.
24
- MIN_NUMBER_OF_MODULES_TO_SCAN_USING_MULTIPROCESSING = 50
29
+ # If you change this, update docs/usage.rst too!
30
+ DEFAULT_MIN_NUMBER_OF_MODULES_TO_SCAN_USING_MULTIPROCESSING = 50
25
31
 
26
32
 
27
33
  def build_graph(
@@ -228,7 +234,7 @@ def _create_chunks(module_files: Collection[ModuleFile]) -> tuple[tuple[ModuleFi
228
234
  module_files_tuple = tuple(module_files)
229
235
 
230
236
  number_of_module_files = len(module_files_tuple)
231
- n_chunks = _decide_number_of_of_processes(number_of_module_files)
237
+ n_chunks = _decide_number_of_processes(number_of_module_files)
232
238
  chunk_size = math.ceil(number_of_module_files / n_chunks)
233
239
 
234
240
  return tuple(
@@ -236,11 +242,17 @@ def _create_chunks(module_files: Collection[ModuleFile]) -> tuple[tuple[ModuleFi
236
242
  )
237
243
 
238
244
 
239
- def _decide_number_of_of_processes(number_of_module_files: int) -> int:
240
- if number_of_module_files < MIN_NUMBER_OF_MODULES_TO_SCAN_USING_MULTIPROCESSING:
241
- # Don't incur the overhead of multiprocessing.
245
+ def _decide_number_of_processes(number_of_module_files: int) -> int:
246
+ min_number_of_modules = int(
247
+ os.environ.get(
248
+ MIN_NUMBER_OF_MODULES_TO_SCAN_USING_MULTIPROCESSING_ENV_NAME,
249
+ DEFAULT_MIN_NUMBER_OF_MODULES_TO_SCAN_USING_MULTIPROCESSING,
250
+ )
251
+ )
252
+ if number_of_module_files < min_number_of_modules:
253
+ # Don't incur the overhead of multiple processes.
242
254
  return 1
243
- return min(multiprocessing.cpu_count(), number_of_module_files)
255
+ return min(joblib.cpu_count(), number_of_module_files)
244
256
 
245
257
 
246
258
  def _scan_chunks(
@@ -257,20 +269,15 @@ def _scan_chunks(
257
269
  )
258
270
 
259
271
  number_of_processes = len(chunks)
260
- if number_of_processes == 1:
261
- # No need to spawn a process if there's only one chunk.
262
- [chunk] = chunks
263
- return _scan_chunk(import_scanner, exclude_type_checking_imports, chunk)
264
- else:
265
- with multiprocessing.Pool(number_of_processes) as pool:
266
- imports_by_module_file: Dict[ModuleFile, Set[DirectImport]] = {}
267
- import_scanning_jobs = pool.starmap(
268
- _scan_chunk,
269
- [(import_scanner, exclude_type_checking_imports, chunk) for chunk in chunks],
270
- )
271
- for chunk_imports_by_module_file in import_scanning_jobs:
272
- imports_by_module_file.update(chunk_imports_by_module_file)
273
- return imports_by_module_file
272
+ import_scanning_jobs = joblib.Parallel(n_jobs=number_of_processes)(
273
+ joblib.delayed(_scan_chunk)(import_scanner, exclude_type_checking_imports, chunk)
274
+ for chunk in chunks
275
+ )
276
+
277
+ imports_by_module_file = {}
278
+ for chunk_imports_by_module_file in import_scanning_jobs:
279
+ imports_by_module_file.update(chunk_imports_by_module_file)
280
+ return imports_by_module_file
274
281
 
275
282
 
276
283
  def _scan_chunk(
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