code-loader 1.0.187__tar.gz → 1.0.187.dev0__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 (37) hide show
  1. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/PKG-INFO +3 -3
  2. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/code_loader/inner_leap_binder/leapbinder.py +36 -0
  3. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/code_loader/inner_leap_binder/leapbinder_decorators.py +7 -11
  4. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/pyproject.toml +1 -1
  5. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/LICENSE +0 -0
  6. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/README.md +0 -0
  7. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/code_loader/__init__.py +0 -0
  8. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/code_loader/contract/__init__.py +0 -0
  9. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/code_loader/contract/datasetclasses.py +0 -0
  10. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/code_loader/contract/enums.py +0 -0
  11. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/code_loader/contract/exceptions.py +0 -0
  12. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/code_loader/contract/mapping.py +0 -0
  13. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/code_loader/contract/responsedataclasses.py +0 -0
  14. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/code_loader/contract/sim_config.py +0 -0
  15. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/code_loader/contract/visualizer_classes.py +0 -0
  16. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/code_loader/default_losses.py +0 -0
  17. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/code_loader/default_metrics.py +0 -0
  18. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/code_loader/experiment_api/__init__.py +0 -0
  19. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/code_loader/experiment_api/api.py +0 -0
  20. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/code_loader/experiment_api/cli_config_utils.py +0 -0
  21. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/code_loader/experiment_api/client.py +0 -0
  22. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/code_loader/experiment_api/epoch.py +0 -0
  23. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/code_loader/experiment_api/experiment.py +0 -0
  24. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/code_loader/experiment_api/experiment_context.py +0 -0
  25. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/code_loader/experiment_api/types.py +0 -0
  26. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/code_loader/experiment_api/utils.py +0 -0
  27. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/code_loader/experiment_api/workingspace_config_utils.py +0 -0
  28. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/code_loader/inner_leap_binder/__init__.py +0 -0
  29. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/code_loader/leaploader.py +0 -0
  30. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/code_loader/leaploaderbase.py +0 -0
  31. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/code_loader/mixpanel_tracker.py +0 -0
  32. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/code_loader/plot_functions/__init__.py +0 -0
  33. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/code_loader/plot_functions/plot_functions.py +0 -0
  34. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/code_loader/plot_functions/visualize.py +0 -0
  35. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/code_loader/utils.py +0 -0
  36. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/code_loader/visualizers/__init__.py +0 -0
  37. {code_loader-1.0.187 → code_loader-1.0.187.dev0}/code_loader/visualizers/default_visualizers.py +0 -0
@@ -1,8 +1,7 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: code-loader
3
- Version: 1.0.187
3
+ Version: 1.0.187.dev0
4
4
  Summary:
5
- Home-page: https://github.com/tensorleap/code-loader
6
5
  License: MIT
7
6
  Author: dorhar
8
7
  Author-email: doron.harnoy@tensorleap.ai
@@ -20,6 +19,7 @@ Requires-Dist: numpy (>=2.3.2,<3.0.0) ; python_version >= "3.11" and python_vers
20
19
  Requires-Dist: psutil (>=5.9.5,<6.0.0)
21
20
  Requires-Dist: pyyaml (>=6.0.2,<7.0.0)
22
21
  Requires-Dist: requests (>=2.32.3,<3.0.0)
22
+ Project-URL: Homepage, https://github.com/tensorleap/code-loader
23
23
  Project-URL: Repository, https://github.com/tensorleap/code-loader
24
24
  Description-Content-Type: text/markdown
25
25
 
@@ -31,6 +31,31 @@ from code_loader.visualizers.default_visualizers import DefaultVisualizer, \
31
31
  mapping_runtime_mode_env_var_mame = '__MAPPING_RUNTIME_MODE__'
32
32
 
33
33
 
34
+ def _stringized_annotation_type_name(annotation: Any) -> Optional[str]:
35
+ """Return the bare type name when ``annotation`` is a *stringized* annotation
36
+ (e.g. produced by ``from __future__ import annotations`` or a quoted hint),
37
+ otherwise ``None``. code_loader inspects raw annotations expecting real classes,
38
+ so a stringized annotation silently breaks type detection."""
39
+ if isinstance(annotation, str):
40
+ return annotation.split("[")[0].strip().rsplit(".", 1)[-1]
41
+ return None
42
+
43
+
44
+ def _reject_stringized_sample_preprocess_response(function: Callable, arg_name: str, annotation: Any) -> None:
45
+ """Fail fast when a ``SamplePreprocessResponse`` argument was stringized. Otherwise
46
+ ``arg_type == SamplePreprocessResponse`` silently evaluates to ``False`` and the
47
+ argument is mis-wired as a regular input — a bug that only surfaces on the platform.
48
+ Fires only on the actual damage (a stringized SamplePreprocessResponse), not merely
49
+ because the file uses future annotations."""
50
+ if _stringized_annotation_type_name(annotation) == SamplePreprocessResponse.__name__:
51
+ raise Exception(
52
+ f"Argument '{arg_name}' of function '{function.__name__}' is annotated with a string "
53
+ f"('{annotation}') instead of the SamplePreprocessResponse type. This usually means the "
54
+ f"file uses 'from __future__ import annotations' (or a quoted hint), which stringizes "
55
+ f"annotations and breaks Tensorleap type detection. Remove that import (or the quotes) so "
56
+ f"SamplePreprocessResponse is referenced as a real type.")
57
+
58
+
34
59
 
35
60
 
36
61
  class LeapBinder:
@@ -123,6 +148,7 @@ class LeapBinder:
123
148
  regular_arg_names = inspect.getfullargspec(function)[0]
124
149
  preprocess_response_arg_name = None
125
150
  for arg_name, arg_type in inspect.getfullargspec(function).annotations.items():
151
+ _reject_stringized_sample_preprocess_response(function, arg_name, arg_type)
126
152
  if arg_type == SamplePreprocessResponse:
127
153
  if preprocess_response_arg_name is not None:
128
154
  raise Exception("only one argument can be of type SamplePreprocessResponse")
@@ -155,6 +181,13 @@ class LeapBinder:
155
181
  f"https://docs.python.org/3/library/typing.html")
156
182
  else:
157
183
  return_type = func_annotations["return"]
184
+ if isinstance(return_type, str):
185
+ raise Exception(
186
+ f"The return type hint of function '{function.__name__}' is a string "
187
+ f"('{return_type}') instead of a type. This usually means the file uses "
188
+ f"'from __future__ import annotations' (or a quoted return hint), which stringizes "
189
+ f"annotations and prevents Tensorleap from detecting the visualizer type. Remove "
190
+ f"that import (or the quotes) so the return type is a real class.")
158
191
  if return_type not in LeapData.__args__: # type: ignore[attr-defined]
159
192
  raise Exception(
160
193
  f'The return type of function {function.__name__} is invalid. current return type: {return_type}, ' # type: ignore[attr-defined]
@@ -296,6 +329,7 @@ class LeapBinder:
296
329
  regular_arg_names = inspect.getfullargspec(function)[0]
297
330
  preprocess_response_arg_name = None
298
331
  for arg_name, arg_type in inspect.getfullargspec(function).annotations.items():
332
+ _reject_stringized_sample_preprocess_response(function, arg_name, arg_type)
299
333
  if arg_type == SamplePreprocessResponse:
300
334
  if preprocess_response_arg_name is not None:
301
335
  raise Exception("only one argument can be of type SamplePreprocessResponse")
@@ -339,6 +373,7 @@ class LeapBinder:
339
373
  regular_arg_names = inspect.getfullargspec(function)[0]
340
374
  preprocess_response_arg_name = None
341
375
  for arg_name, arg_type in inspect.getfullargspec(function).annotations.items():
376
+ _reject_stringized_sample_preprocess_response(function, arg_name, arg_type)
342
377
  if arg_type == SamplePreprocessResponse:
343
378
  if preprocess_response_arg_name is not None:
344
379
  raise Exception("only one argument can be of type SamplePreprocessResponse")
@@ -380,6 +415,7 @@ class LeapBinder:
380
415
  regular_arg_names = inspect.getfullargspec(function)[0]
381
416
  preprocess_response_arg_name = None
382
417
  for arg_name, arg_type in inspect.getfullargspec(function).annotations.items():
418
+ _reject_stringized_sample_preprocess_response(function, arg_name, arg_type)
383
419
  if arg_type == SamplePreprocessResponse:
384
420
  if preprocess_response_arg_name is not None:
385
421
  raise Exception("only one argument can be of type SamplePreprocessResponse")
@@ -768,18 +768,14 @@ def tensorleap_custom_metric(name: str,
768
768
 
769
769
  leap_binder.setup_container.metrics[-1].metric_handler_data.direction = effective_direction
770
770
 
771
- if compute_insights is None:
772
- effective_compute_insights = None
773
- elif isinstance(compute_insights, dict):
774
- effective_compute_insights = {key: compute_insights.get(key, True) for key in result_keys}
775
- else:
776
- effective_compute_insights = {key: compute_insights for key in result_keys}
777
-
778
- leap_binder.setup_container.metrics[-1].metric_handler_data.compute_insights = effective_compute_insights
779
-
780
771
  if defaulted_direction_keys and not _call_from_tl_platform:
781
- warning_keys = {key for key in defaulted_direction_keys
782
- if (effective_compute_insights or {}).get(key, True)}
772
+ if compute_insights is None:
773
+ effective_compute_insights = {}
774
+ elif isinstance(compute_insights, dict):
775
+ effective_compute_insights = compute_insights
776
+ else:
777
+ effective_compute_insights = {k: compute_insights for k in result_keys}
778
+ warning_keys = {key for key in defaulted_direction_keys if effective_compute_insights.get(key, True)}
783
779
  if warning_keys:
784
780
  store_warning_by_param(
785
781
  param_name=f"direction[{warning_keys}]",
@@ -1,7 +1,7 @@
1
1
  [tool.poetry]
2
2
  name = "code-loader"
3
3
 
4
- version = "1.0.187"
4
+ version = "1.0.187.dev0"
5
5
  description = ""
6
6
  authors = ["dorhar <doron.harnoy@tensorleap.ai>"]
7
7
  license = "MIT"