dragon-ml-toolbox 10.11.0__tar.gz → 10.11.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 (41) hide show
  1. {dragon_ml_toolbox-10.11.0/dragon_ml_toolbox.egg-info → dragon_ml_toolbox-10.11.2}/PKG-INFO +1 -1
  2. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2/dragon_ml_toolbox.egg-info}/PKG-INFO +1 -1
  3. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/ml_tools/path_manager.py +18 -11
  4. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/ml_tools/utilities.py +39 -5
  5. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/pyproject.toml +1 -1
  6. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/LICENSE +0 -0
  7. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/LICENSE-THIRD-PARTY.md +0 -0
  8. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/README.md +0 -0
  9. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/dragon_ml_toolbox.egg-info/SOURCES.txt +0 -0
  10. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/dragon_ml_toolbox.egg-info/dependency_links.txt +0 -0
  11. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/dragon_ml_toolbox.egg-info/requires.txt +0 -0
  12. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/dragon_ml_toolbox.egg-info/top_level.txt +0 -0
  13. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/ml_tools/ETL_cleaning.py +0 -0
  14. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/ml_tools/ETL_engineering.py +0 -0
  15. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/ml_tools/GUI_tools.py +0 -0
  16. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/ml_tools/MICE_imputation.py +0 -0
  17. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/ml_tools/ML_callbacks.py +0 -0
  18. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/ml_tools/ML_datasetmaster.py +0 -0
  19. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/ml_tools/ML_evaluation.py +0 -0
  20. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/ml_tools/ML_evaluation_multi.py +0 -0
  21. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/ml_tools/ML_inference.py +0 -0
  22. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/ml_tools/ML_models.py +0 -0
  23. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/ml_tools/ML_optimization.py +0 -0
  24. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/ml_tools/ML_scaler.py +0 -0
  25. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/ml_tools/ML_trainer.py +0 -0
  26. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/ml_tools/PSO_optimization.py +0 -0
  27. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/ml_tools/RNN_forecast.py +0 -0
  28. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/ml_tools/SQL.py +0 -0
  29. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/ml_tools/VIF_factor.py +0 -0
  30. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/ml_tools/__init__.py +0 -0
  31. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/ml_tools/_logger.py +0 -0
  32. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/ml_tools/_script_info.py +0 -0
  33. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/ml_tools/custom_logger.py +0 -0
  34. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/ml_tools/data_exploration.py +0 -0
  35. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/ml_tools/ensemble_evaluation.py +0 -0
  36. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/ml_tools/ensemble_inference.py +0 -0
  37. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/ml_tools/ensemble_learning.py +0 -0
  38. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/ml_tools/handle_excel.py +0 -0
  39. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/ml_tools/keys.py +0 -0
  40. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/ml_tools/optimization_tools.py +0 -0
  41. {dragon_ml_toolbox-10.11.0 → dragon_ml_toolbox-10.11.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dragon-ml-toolbox
3
- Version: 10.11.0
3
+ Version: 10.11.2
4
4
  Summary: A collection of tools for data science and machine learning projects.
5
5
  Author-email: Karl Loza <luigiloza@gmail.com>
6
6
  License-Expression: MIT
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dragon-ml-toolbox
3
- Version: 10.11.0
3
+ Version: 10.11.2
4
4
  Summary: A collection of tools for data science and machine learning projects.
5
5
  Author-email: Karl Loza <luigiloza@gmail.com>
6
6
  License-Expression: MIT
@@ -248,26 +248,33 @@ class PathManager:
248
248
  _LOGGER.error(f"'{type(self).__name__}' object has no attribute or path key '{sanitized_name}'")
249
249
  raise AttributeError()
250
250
 
251
- def __setattr__(self, name: str, value: Union[str, Path]):
251
+ def __setattr__(self, name: str, value: Union[str, Path, bool, dict, str, int, tuple]):
252
252
  """Allows attribute-style setting of paths, e.g., PM.data = 'path/to/data'."""
253
- # Check for internal attributes
253
+ # Check for internal attributes, which are set directly on the object.
254
254
  if name.startswith('_'):
255
- if hasattr(self, '_initialized') and self._initialized:
256
- self._check_underscore_key(name)
257
- return
258
- else:
259
- # During initialization, allow private attributes to be set.
260
- super().__setattr__(name, value)
255
+ # This check prevents setting new private attributes after __init__ is done.
256
+ is_initialized = self.__dict__.get('_initialized', False)
257
+ if is_initialized:
258
+ _LOGGER.error(f"Cannot set private attribute '{name}' after initialization.")
259
+ raise AttributeError()
260
+ super().__setattr__(name, value)
261
261
  return
262
262
 
263
- # Block overwriting of existing methods/attributes
263
+ # Sanitize the key for the public path.
264
264
  sanitized_name = self._sanitize_key(name)
265
265
  self._check_underscore_key(sanitized_name)
266
- if hasattr(self, sanitized_name):
266
+
267
+ # Prevent overwriting existing methods (e.g., PM.status = 'foo').
268
+ # This check looks at the class, not the instance therefore won't trigger __getattr__.
269
+ if hasattr(self.__class__, sanitized_name):
267
270
  _LOGGER.error(f"Cannot overwrite existing attribute or method '{sanitized_name}' ({name}).")
268
271
  raise AttributeError()
272
+
273
+ if not isinstance(value, (str, Path)):
274
+ _LOGGER.error(f"Cannot assign type '{type(value).__name__}' to a path. Must be str or Path.")
275
+ raise TypeError
269
276
 
270
- # If all checks pass, treat it as a public path.
277
+ # If all checks pass, treat it as a public path and store it in the _paths dictionary.
271
278
  self._paths[sanitized_name] = Path(value)
272
279
 
273
280
 
@@ -3,7 +3,7 @@ import numpy as np
3
3
  import pandas as pd
4
4
  import polars as pl
5
5
  from pathlib import Path
6
- from typing import Literal, Union, Sequence, Optional, Any, Iterator, Tuple, overload
6
+ from typing import Literal, Union, Sequence, Optional, Any, Iterator, Tuple, overload, TypeVar, get_origin, Type
7
7
  import joblib
8
8
  from joblib.externals.loky.process_executor import TerminatedWorkerError
9
9
  from .path_manager import sanitize_filename, make_fullpath, list_csv_paths, list_files_by_extension, list_subdirectories
@@ -444,16 +444,32 @@ def serialize_object(obj: Any, save_dir: Union[str,Path], filename: str, verbose
444
444
  _LOGGER.info(f"Object of type '{type(obj)}' saved to '{full_path}'")
445
445
  return None
446
446
 
447
-
448
- def deserialize_object(filepath: Union[str,Path], verbose: bool=True, raise_on_error: bool=True) -> Optional[Any]:
447
+ # Define a TypeVar to link the expected type to the return type of deserialization
448
+ T = TypeVar('T')
449
+
450
+ def deserialize_object(
451
+ filepath: Union[str, Path],
452
+ expected_type: Optional[Type[T]] = None,
453
+ verbose: bool = True,
454
+ raise_on_error: bool = True
455
+ ) -> Optional[T]:
449
456
  """
450
457
  Loads a serialized object from a .joblib file.
451
458
 
452
459
  Parameters:
453
460
  filepath (str | Path): Full path to the serialized .joblib file.
461
+ expected_type (Type[T] | None): The expected type of the object.
462
+ If provided, the function raises a TypeError if the loaded object
463
+ is not an instance of this type. It correctly handles generics
464
+ like `list[str]` by checking the base type (e.g., `list`).
465
+ Defaults to None, which skips the type check.
466
+ verbose (bool): If True, logs success messages.
467
+ raise_on_error (bool): If True, raises exceptions on errors. If False, returns None instead.
454
468
 
455
469
  Returns:
456
- (Any | None): The deserialized Python object, or None if loading fails.
470
+ (Any | None): The deserialized Python object, which will match the
471
+ `expected_type` if provided. Returns None if an error
472
+ occurs and `raise_on_error` is False.
457
473
  """
458
474
  true_filepath = make_fullpath(filepath)
459
475
 
@@ -465,8 +481,26 @@ def deserialize_object(filepath: Union[str,Path], verbose: bool=True, raise_on_e
465
481
  raise e
466
482
  return None
467
483
  else:
484
+ # --- Type Validation Step ---
485
+ if expected_type:
486
+ # get_origin handles generics (e.g., list[str] -> list)
487
+ # If it's not a generic, get_origin returns None, so we use the type itself.
488
+ type_to_check = get_origin(expected_type) or expected_type
489
+
490
+ # Can't do an isinstance check on 'Any', skip it.
491
+ if type_to_check is not Any and not isinstance(obj, type_to_check):
492
+ error_msg = (
493
+ f"Type mismatch: Expected an instance of '{expected_type}', "
494
+ f"but found '{type(obj)}' in '{true_filepath}'."
495
+ )
496
+ _LOGGER.error(error_msg)
497
+ if raise_on_error:
498
+ raise TypeError()
499
+ return None
500
+
468
501
  if verbose:
469
- _LOGGER.info(f"Loaded object of type '{type(obj)}'.")
502
+ _LOGGER.info(f"Loaded object of type '{type(obj)}' from '{true_filepath}'.")
503
+
470
504
  return obj
471
505
 
472
506
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "dragon-ml-toolbox"
3
- version = "10.11.0"
3
+ version = "10.11.2"
4
4
  description = "A collection of tools for data science and machine learning projects."
5
5
  authors = [
6
6
  { name = "Karl Loza", email = "luigiloza@gmail.com" }