orionis 0.653.0__py3-none-any.whl → 0.655.0__py3-none-any.whl

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.
@@ -88,37 +88,38 @@ class Container(IContainer):
88
88
 
89
89
  def __init__(self) -> None:
90
90
  """
91
- Initializes a new instance of the container.
91
+ Initializes the internal state of the container instance.
92
92
 
93
- This constructor sets up the internal dictionaries for bindings and aliases,
94
- ensuring that these are only initialized once per instance. The initialization
95
- is guarded by checking if the instance already has the required attributes.
93
+ This constructor sets up the internal dictionaries for service bindings, aliases,
94
+ singleton cache, and resolution cache. Initialization is performed only once per
95
+ instance, even if `__init__` is called multiple times due to inheritance or other
96
+ instantiation patterns. The container also registers itself under the `IContainer`
97
+ interface for dependency injection.
96
98
 
97
99
  Notes
98
100
  -----
99
- - The `__bindings` dictionary is used to store service bindings.
100
- - The `__aliases` dictionary is used to store service aliases.
101
- - Initialization occurs only once per instance, regardless of how many times __init__ is called.
102
- - The container registers itself under the IContainer interface to allow for dependency injection.
101
+ - The `__bindings` dictionary stores service bindings by abstract type.
102
+ - The `__aliases` dictionary maps aliases to their corresponding bindings.
103
+ - The `__singleton_cache` dictionary caches singleton instances.
104
+ - The `__resolution_cache` dictionary tracks types being resolved to prevent circular dependencies.
105
+ - Initialization is guarded to ensure it only occurs once per instance.
106
+
107
+ Returns
108
+ -------
109
+ None
110
+ This method does not return any value.
103
111
  """
104
112
 
105
- # Check if the instance has already been initialized
113
+ # Only initialize if this instance hasn't been initialized before
106
114
  if not hasattr(self, '_Container__initialized'):
107
115
 
108
- # Current Project Namespaces
109
- # Get current project namespace from the working directory
110
- current_project_namespace = Path().cwd().name
111
-
112
- # Add the current project namespace to valid namespaces
113
- self.__valid_namespaces = set(('app', 'orionis', 'requests', 'rich', 'apscheduler', 'dotenv', current_project_namespace))
116
+ # Set up the container's internal dictionaries for service management
117
+ self.__bindings = {} # Stores service bindings by abstract type
118
+ self.__aliases = {} # Maps aliases to bindings
119
+ self.__resolution_cache = {} # Tracks types currently being resolved
120
+ self.__singleton_cache = {} # Caches singleton instances
114
121
 
115
- # Initialize the container's internal state
116
- self.__bindings = {}
117
- self.__aliases = {}
118
- self.__resolution_cache = {}
119
- self.__singleton_cache = {}
120
-
121
- # Mark this instance as initialized
122
+ # Mark this instance as initialized to prevent re-initialization
122
123
  self.__initialized = True
123
124
 
124
125
  def __handleSyncAsyncResult(
@@ -867,15 +868,6 @@ class Container(IContainer):
867
868
  f"Unexpected error registering {Lifetime.SCOPED} service: {e}"
868
869
  ) from e
869
870
 
870
-
871
-
872
-
873
-
874
-
875
-
876
-
877
-
878
-
879
871
  def scopedInstance(
880
872
  self,
881
873
  abstract: Callable[..., Any],
@@ -1062,10 +1054,15 @@ class Container(IContainer):
1062
1054
  """
1063
1055
 
1064
1056
  try:
1057
+
1065
1058
  # Use getBinding which includes validation
1066
1059
  binding = self.getBinding(abstract_or_alias)
1060
+
1061
+ # A valid binding must be present
1067
1062
  return binding is not None
1063
+
1068
1064
  except OrionisContainerException:
1065
+
1069
1066
  # If binding validation fails, consider it as not bound
1070
1067
  return False
1071
1068
 
@@ -1675,6 +1672,7 @@ class Container(IContainer):
1675
1672
  The singleton instance to store cross-references for.
1676
1673
  """
1677
1674
 
1675
+ # Determine the primary cache key for this binding
1678
1676
  primary_key = self.__getSingletonCacheKey(binding)
1679
1677
 
1680
1678
  # Store cross-reference for contract if it's not the primary key
@@ -2037,6 +2035,7 @@ class Container(IContainer):
2037
2035
  """
2038
2036
 
2039
2037
  try:
2038
+
2040
2039
  # If there are no dependencies, return empty dict
2041
2040
  if not dependencies:
2042
2041
  return {}
@@ -2053,6 +2052,7 @@ class Container(IContainer):
2053
2052
  for param_name, dep in dependencies.resolved.items():
2054
2053
  params[param_name] = self.__resolveSingleDependency(name, param_name, dep)
2055
2054
 
2055
+ # Return the dictionary of resolved parameters
2056
2056
  return params
2057
2057
 
2058
2058
  except Exception as e:
@@ -2186,43 +2186,61 @@ class Container(IContainer):
2186
2186
  **kwargs
2187
2187
  ) -> Any:
2188
2188
  """
2189
- Forces resolution of a type whether it's registered in the container or not.
2189
+ Resolves and instantiates a type or callable regardless of its registration in the container.
2190
+
2191
+ This method attempts to instantiate or invoke the provided type or callable, even if it is not
2192
+ registered in the container. It first tries direct instantiation/invocation if arguments are provided,
2193
+ then attempts auto-resolution for eligible types, and finally falls back to reflection-based instantiation.
2194
+ If the type cannot be resolved by any means, an exception is raised.
2190
2195
 
2191
2196
  Parameters
2192
2197
  ----------
2193
2198
  type_ : Callable[..., Any]
2194
- The type or callable to resolve.
2199
+ The class or callable to resolve and instantiate.
2195
2200
  *args : tuple
2196
- Positional arguments to pass to the constructor/callable.
2201
+ Positional arguments to pass to the constructor or callable.
2197
2202
  **kwargs : dict
2198
- Keyword arguments to pass to the constructor/callable.
2203
+ Keyword arguments to pass to the constructor or callable.
2199
2204
 
2200
2205
  Returns
2201
2206
  -------
2202
2207
  Any
2203
- The resolved instance.
2208
+ The instantiated object or the result of the callable. If the type is a class, a new instance is returned.
2209
+ If the type is a callable, the result of its invocation is returned.
2204
2210
 
2205
2211
  Raises
2206
2212
  ------
2207
2213
  OrionisContainerException
2208
- If the type cannot be resolved.
2214
+ If the type cannot be resolved, is not a concrete class or callable, or if an error occurs during instantiation.
2215
+
2216
+ Notes
2217
+ -----
2218
+ - Direct instantiation/invocation is prioritized when arguments are provided.
2219
+ - Auto-resolution is attempted for types eligible for automatic dependency resolution.
2220
+ - Reflection-based instantiation is used as a fallback for concrete classes or callables.
2221
+ - If none of the resolution strategies succeed, an exception is raised.
2209
2222
  """
2223
+
2210
2224
  try:
2211
- # If args or kwargs are provided, use them directly
2225
+
2226
+ # If explicit arguments are provided, attempt direct instantiation or invocation
2212
2227
  if args or kwargs:
2213
2228
  if isinstance(type_, type):
2229
+ # Instantiate the class directly with provided arguments
2214
2230
  return type_(*args, **kwargs)
2215
2231
  elif callable(type_):
2232
+ # Invoke the callable directly with provided arguments
2216
2233
  return type_(*args, **kwargs)
2217
2234
 
2218
- # Try auto-resolution first for unregistered types
2235
+ # Attempt auto-resolution for eligible types
2219
2236
  if self.__canAutoResolve(type_):
2220
2237
  return self.__autoResolve(type_)
2221
2238
 
2222
- # Use the unified reflection-based instantiation
2239
+ # Use reflection-based instantiation for concrete classes
2223
2240
  if ReflectionConcrete.isConcreteClass(type_):
2224
2241
  return self.__instantiateWithReflection(type_, is_class=True)
2225
2242
 
2243
+ # Use reflection-based invocation for callables that are not classes
2226
2244
  if callable(type_) and not isinstance(type_, type):
2227
2245
  return self.__instantiateWithReflection(type_, is_class=False)
2228
2246
 
@@ -2232,9 +2250,12 @@ class Container(IContainer):
2232
2250
  )
2233
2251
 
2234
2252
  except Exception as e:
2253
+
2254
+ # Re-raise container exceptions directly
2235
2255
  if isinstance(e, OrionisContainerException):
2236
2256
  raise e from None
2237
2257
 
2258
+ # Wrap other exceptions in an OrionisContainerException with context
2238
2259
  raise OrionisContainerException(
2239
2260
  f"Error resolving '{getattr(type_, '__name__', str(type_))}': {str(e)}"
2240
2261
  ) from e
@@ -2299,26 +2320,34 @@ class Container(IContainer):
2299
2320
 
2300
2321
  def __isValidNamespace(self, type_: type) -> bool:
2301
2322
  """
2302
- Checks if a type belongs to a valid namespace for auto-resolution.
2323
+ Determines if a type belongs to a valid namespace for auto-resolution.
2324
+
2325
+ This method checks whether the provided type is defined within one of the namespaces
2326
+ considered valid for automatic dependency resolution by the container. Valid namespaces
2327
+ are typically application-specific modules or packages that are explicitly allowed
2328
+ for auto-resolution. Built-in types and types from external libraries are excluded.
2303
2329
 
2304
2330
  Parameters
2305
2331
  ----------
2306
2332
  type_ : type
2307
- The type to check for valid namespace.
2333
+ The type to check for valid namespace membership.
2308
2334
 
2309
2335
  Returns
2310
2336
  -------
2311
2337
  bool
2312
- True if the type belongs to a valid namespace, False otherwise.
2313
- """
2338
+ True if the type belongs to a valid namespace (i.e., its `__module__` attribute
2339
+ matches one of the namespaces in `self.__valid_namespaces`), otherwise False.
2314
2340
 
2315
- # Verify that the module name starts with any of the valid namespace prefixes
2316
- if hasattr(type_, '__module__'):
2317
- module_name = type_.__module__
2318
- return any(module_name.startswith(namespace) for namespace in self.__valid_namespaces)
2341
+ Notes
2342
+ -----
2343
+ - The method relies on the presence of the `__module__` attribute on the type.
2344
+ - If the type does not have a `__module__` attribute, it cannot be considered valid.
2345
+ - The set of valid namespaces is initialized in the container and may include
2346
+ application modules, framework modules, and the current project namespace.
2347
+ """
2319
2348
 
2320
- # If the type has no module information, it cannot be auto-resolved
2321
- return False
2349
+ # Ensure the type has a __module__ attribute before checking namespace validity
2350
+ return hasattr(type_, '__module__')
2322
2351
 
2323
2352
  def __isInstantiable(self, type_: type) -> bool:
2324
2353
  """
@@ -2370,6 +2399,7 @@ class Container(IContainer):
2370
2399
  return self.__canQuickInstantiate(type_)
2371
2400
 
2372
2401
  except Exception:
2402
+
2373
2403
  # If any check fails with an exception, consider it non-instantiable
2374
2404
  return False
2375
2405
 
@@ -2394,22 +2424,31 @@ class Container(IContainer):
2394
2424
 
2395
2425
  # Check if it inherits from ABC (safely)
2396
2426
  try:
2427
+
2428
+ # Check if it inherits from abc.ABC
2397
2429
  if issubclass(type_, abc.ABC):
2398
2430
  return True
2431
+
2432
+ # type_ is not a class, so it can't be abstract
2399
2433
  except TypeError:
2400
- # type_ is not a class, so it can't be abstract
2401
2434
  pass
2402
2435
 
2403
2436
  # Check if it has abstract methods
2404
2437
  try:
2405
2438
  # Try to get abstract methods using reflection
2406
2439
  for attr_name in dir(type_):
2440
+
2441
+ # Get the attribute
2407
2442
  attr = getattr(type_, attr_name)
2443
+
2444
+ # Check if the attribute is marked as an abstract method
2408
2445
  if hasattr(attr, '__isabstractmethod__') and attr.__isabstractmethod__:
2409
2446
  return True
2447
+
2410
2448
  except Exception:
2411
2449
  pass
2412
2450
 
2451
+ # If none of the checks matched, it's not abstract
2413
2452
  return False
2414
2453
 
2415
2454
  def __isGenericType(self, type_: type) -> bool:
@@ -2443,6 +2482,7 @@ class Container(IContainer):
2443
2482
  if hasattr(typing, 'TypeVar') and isinstance(type_, typing.TypeVar):
2444
2483
  return True
2445
2484
 
2485
+ # If none of the checks matched, it's not a generic type
2446
2486
  return False
2447
2487
 
2448
2488
  def __isProtocolOrTyping(self, type_: type) -> bool:
@@ -2475,9 +2515,12 @@ class Container(IContainer):
2475
2515
 
2476
2516
  # Check for common typing constructs that shouldn't be instantiated
2477
2517
  typing_constructs = ['Union', 'Optional', 'Any', 'Callable', 'Type']
2518
+
2519
+ # If the type's name matches a known typing construct, it's not instantiable
2478
2520
  if hasattr(type_, '__name__') and type_.__name__ in typing_constructs:
2479
2521
  return True
2480
2522
 
2523
+ # If none of the checks matched, it's not a protocol or typing construct
2481
2524
  return False
2482
2525
 
2483
2526
  def __hasRequiredConstructorParams(self, type_: type) -> bool:
@@ -2539,6 +2582,7 @@ class Container(IContainer):
2539
2582
  """
2540
2583
 
2541
2584
  try:
2585
+
2542
2586
  # For safety, first check if the constructor signature suggests it's safe to instantiate
2543
2587
  try:
2544
2588
 
@@ -2563,8 +2607,10 @@ class Container(IContainer):
2563
2607
  # Attempt to create an instance only if it seems safe
2564
2608
  instance = type_()
2565
2609
 
2566
- # If successful, clean up and return True
2610
+ # If successful, clean up
2567
2611
  del instance
2612
+
2613
+ # Return True if instantiation succeeded
2568
2614
  return True
2569
2615
 
2570
2616
  except Exception:
@@ -2609,6 +2655,7 @@ class Container(IContainer):
2609
2655
  )
2610
2656
 
2611
2657
  try:
2658
+
2612
2659
  # Mark this type as being resolved to prevent circular dependencies
2613
2660
  self.__resolution_cache[type_key] = True
2614
2661
 
@@ -2634,17 +2681,21 @@ class Container(IContainer):
2634
2681
  )
2635
2682
 
2636
2683
  except Exception as e:
2684
+
2637
2685
  # Remove the type from the resolution cache on error
2638
2686
  self.__resolution_cache.pop(type_key, None)
2639
2687
 
2688
+ # If the exception is already an OrionisContainerException, re-raise it
2640
2689
  if isinstance(e, OrionisContainerException):
2641
2690
  raise
2642
- else:
2643
- raise OrionisContainerException(
2644
- f"Failed to auto-resolve '{type_.__name__}': {str(e)}"
2645
- ) from e
2691
+
2692
+ # Otherwise, raise a new OrionisContainerException with additional context
2693
+ raise OrionisContainerException(
2694
+ f"Failed to auto-resolve '{type_.__name__}': {str(e)}"
2695
+ ) from e
2646
2696
 
2647
2697
  finally:
2698
+
2648
2699
  # Always clean up the resolution cache after resolution attempt
2649
2700
  self.__resolution_cache.pop(type_key, None)
2650
2701
 
@@ -5,7 +5,7 @@
5
5
  NAME = "orionis"
6
6
 
7
7
  # Current version of the framework
8
- VERSION = "0.653.0"
8
+ VERSION = "0.655.0"
9
9
 
10
10
  # Full name of the author or maintainer of the project
11
11
  AUTHOR = "Raul Mauricio Uñate Castro"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: orionis
3
- Version: 0.653.0
3
+ Version: 0.655.0
4
4
  Summary: Orionis Framework – Elegant, Fast, and Powerful.
5
5
  Home-page: https://github.com/orionis-framework/framework
6
6
  Author: Raul Mauricio Uñate Castro
@@ -67,7 +67,7 @@ orionis/console/stubs/listener.stub,sha256=DbX-ghx2-vb73kzQ6L20lyg5vSKn58jSLTwFu
67
67
  orionis/console/tasks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
68
68
  orionis/console/tasks/schedule.py,sha256=ZeeuQ9Tbu5KNowKC5oIk7yWeJXzlDQiQ278mWEgoCXc,87989
69
69
  orionis/container/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
70
- orionis/container/container.py,sha256=cbwsntr_yRy-W18MipLZ8Gy2d7mCoO51_eq4z53bxVk,109309
70
+ orionis/container/container.py,sha256=wykXRHbXuj5uR_dLWSGV2dP6HJhat9O22xhZ1qrJ710,112458
71
71
  orionis/container/context/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
72
72
  orionis/container/context/manager.py,sha256=I08K_jKXSKmrq18Pv33qYyMKIlAovVOwIgmfiVm-J7c,2971
73
73
  orionis/container/context/scope.py,sha256=p_oCzR7dDz-5ZAd16ab4vfLc3gBf34CaN0f4iR9D0bQ,1155
@@ -217,7 +217,7 @@ orionis/foundation/providers/scheduler_provider.py,sha256=IrPQJwvQVLRm5Qnz0Cxon4
217
217
  orionis/foundation/providers/testing_provider.py,sha256=eI1p2lUlxl25b5Z487O4nmqLE31CTDb4c3Q21xFadkE,1615
218
218
  orionis/foundation/providers/workers_provider.py,sha256=GdHENYV_yGyqmHJHn0DCyWmWId5xWjD48e6Zq2PGCWY,1674
219
219
  orionis/metadata/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
220
- orionis/metadata/framework.py,sha256=otOsCfm3C9Cc9HHO-slNc79h08eMiZuSsG_zqA0F3i4,4089
220
+ orionis/metadata/framework.py,sha256=fCnJNnu6flu1dXdRyr3BiuEpSCKb5vSVvYYbZ4DsghA,4089
221
221
  orionis/metadata/package.py,sha256=k7Yriyp5aUcR-iR8SK2ec_lf0_Cyc-C7JczgXa-I67w,16039
222
222
  orionis/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
223
223
  orionis/services/asynchrony/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -404,8 +404,8 @@ orionis/test/validators/workers.py,sha256=rWcdRexINNEmGaO7mnc1MKUxkHKxrTsVuHgbnI
404
404
  orionis/test/view/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
405
405
  orionis/test/view/render.py,sha256=R55ykeRs0wDKcdTf4O1YZ8GDHTFmJ0IK6VQkbJkYUvo,5571
406
406
  orionis/test/view/report.stub,sha256=QLqqCdRoENr3ECiritRB3DO_MOjRQvgBh5jxZ3Hs1r0,28189
407
- orionis-0.653.0.dist-info/licenses/LICENCE,sha256=JhC-z_9mbpUrCfPjcl3DhDA8trNDMzb57cvRSam1avc,1463
408
- orionis-0.653.0.dist-info/METADATA,sha256=QjGBZ4J_obp_gOTBFsYVPHTNKkvUTAm8yZMmLT-Tszk,4772
409
- orionis-0.653.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
410
- orionis-0.653.0.dist-info/top_level.txt,sha256=lyXi6jArpqJ-0zzNqd_uwsH-z9TCEBVBL-pC3Ekv7hU,8
411
- orionis-0.653.0.dist-info/RECORD,,
407
+ orionis-0.655.0.dist-info/licenses/LICENCE,sha256=JhC-z_9mbpUrCfPjcl3DhDA8trNDMzb57cvRSam1avc,1463
408
+ orionis-0.655.0.dist-info/METADATA,sha256=aPpUeCj0hOqdFHu448hacU_JrJNuv41S-Kp0km98Uwc,4772
409
+ orionis-0.655.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
410
+ orionis-0.655.0.dist-info/top_level.txt,sha256=lyXi6jArpqJ-0zzNqd_uwsH-z9TCEBVBL-pC3Ekv7hU,8
411
+ orionis-0.655.0.dist-info/RECORD,,