django-bulk-hooks 0.1.219__py3-none-any.whl → 0.1.221__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.

Potentially problematic release.


This version of django-bulk-hooks might be problematic. Click here for more details.

@@ -1,3 +1,8 @@
1
+ import logging
2
+
3
+ logger = logging.getLogger(__name__)
4
+
5
+
1
6
  def resolve_dotted_attr(instance, dotted_path):
2
7
  """
3
8
  Recursively resolve a dotted attribute path, e.g., "type.category".
@@ -66,19 +71,16 @@ class HasChanged(HookCondition):
66
71
  self.has_changed = has_changed
67
72
 
68
73
  def check(self, instance, original_instance=None):
69
- print(f"DEBUG: HasChanged.check called for field '{self.field}' on instance {getattr(instance, 'pk', 'No PK')}")
70
- print(f"DEBUG: Original instance: {getattr(original_instance, 'pk', 'No PK') if original_instance else 'None'}")
71
-
72
74
  if not original_instance:
73
- print(f"DEBUG: No original instance, returning False")
74
75
  return False
75
76
 
76
77
  current = resolve_dotted_attr(instance, self.field)
77
78
  previous = resolve_dotted_attr(original_instance, self.field)
78
79
 
79
- # Add more detailed debugging
80
80
  result = (current != previous) == self.has_changed
81
- print(f"DEBUG: HasChanged {self.field} result={result}")
81
+ # Only log when there's an actual change to reduce noise
82
+ if result:
83
+ logger.debug(f"HasChanged {self.field} detected change on instance {getattr(instance, 'pk', 'No PK')}")
82
84
  return result
83
85
 
84
86
 
@@ -1,3 +1,4 @@
1
+ import logging
1
2
  from django.db import models
2
3
 
3
4
  from django_bulk_hooks.constants import (
@@ -15,6 +16,8 @@ from django_bulk_hooks.context import HookContext
15
16
  from django_bulk_hooks.engine import run
16
17
  from django_bulk_hooks.manager import BulkHookManager
17
18
 
19
+ logger = logging.getLogger(__name__)
20
+
18
21
 
19
22
  class HookModelMixin(models.Model):
20
23
  objects = BulkHookManager()
@@ -56,15 +59,13 @@ class HookModelMixin(models.Model):
56
59
  def save(self, *args, bypass_hooks=False, **kwargs):
57
60
  # If bypass_hooks is True, use base manager to avoid triggering hooks
58
61
  if bypass_hooks:
59
- print(
60
- f"DEBUG: save() called with bypass_hooks=True for {self.__class__.__name__} pk={self.pk}"
61
- )
62
+ logger.debug(f"save() called with bypass_hooks=True for {self.__class__.__name__} pk={self.pk}")
62
63
  return self._base_manager.save(self, *args, **kwargs)
63
64
 
64
65
  is_create = self.pk is None
65
66
 
66
67
  if is_create:
67
- print(f"DEBUG: save() creating new {self.__class__.__name__} instance")
68
+ logger.debug(f"save() creating new {self.__class__.__name__} instance")
68
69
  # For create operations, we don't have old records
69
70
  ctx = HookContext(self.__class__)
70
71
  run(self.__class__, BEFORE_CREATE, [self], ctx=ctx)
@@ -73,9 +74,7 @@ class HookModelMixin(models.Model):
73
74
 
74
75
  run(self.__class__, AFTER_CREATE, [self], ctx=ctx)
75
76
  else:
76
- print(
77
- f"DEBUG: save() updating existing {self.__class__.__name__} instance pk={self.pk}"
78
- )
77
+ logger.debug(f"save() updating existing {self.__class__.__name__} instance pk={self.pk}")
79
78
  # For update operations, we need to get the old record
80
79
  try:
81
80
  # Use _base_manager to avoid triggering hooks recursively
@@ -81,10 +81,10 @@ class HookQuerySetMixin:
81
81
 
82
82
  # If we're in a bulk operation context, skip hooks to prevent double execution
83
83
  if current_bypass_hooks:
84
- logger.debug("update skipping hooks (bulk context)")
84
+ logger.debug("update: skipping hooks (bulk context)")
85
85
  ctx = HookContext(model_cls, bypass_hooks=True)
86
86
  else:
87
- logger.debug("update running hooks (standalone)")
87
+ logger.debug("update: running hooks (standalone)")
88
88
  ctx = HookContext(model_cls, bypass_hooks=False)
89
89
  # Run validation hooks first
90
90
  engine.run(model_cls, VALIDATE_UPDATE, instances, originals, ctx=ctx)
@@ -118,10 +118,10 @@ class HookQuerySetMixin:
118
118
 
119
119
  # Run AFTER_UPDATE hooks only for standalone updates
120
120
  if not current_bypass_hooks:
121
- logger.debug("update running AFTER_UPDATE")
121
+ logger.debug("update: running AFTER_UPDATE")
122
122
  engine.run(model_cls, AFTER_UPDATE, instances, originals, ctx=ctx)
123
123
  else:
124
- logger.debug("update skipping AFTER_UPDATE (bulk context)")
124
+ logger.debug("update: skipping AFTER_UPDATE (bulk context)")
125
125
 
126
126
  return update_count
127
127
 
@@ -251,11 +251,11 @@ class HookQuerySetMixin:
251
251
  break
252
252
 
253
253
  if not bypass_hooks:
254
- logger.debug("bulk_update setting bypass_hooks=False (hooks will run in update())")
254
+ logger.debug("bulk_update: hooks will run in update()")
255
255
  ctx = HookContext(model_cls, bypass_hooks=False)
256
256
  originals = [None] * len(objs) # Placeholder for after_update call
257
257
  else:
258
- logger.debug("bulk_update setting bypass_hooks=True (no hooks)")
258
+ logger.debug("bulk_update: hooks bypassed")
259
259
  ctx = HookContext(model_cls, bypass_hooks=True)
260
260
  originals = [None] * len(objs) # Ensure originals is defined for after_update call
261
261
 
@@ -289,9 +289,9 @@ class HookQuerySetMixin:
289
289
  # Note: We don't run AFTER_UPDATE hooks here to prevent double execution
290
290
  # The update() method will handle all hook execution based on thread-local state
291
291
  if not bypass_hooks:
292
- logger.debug("bulk_update skipping AFTER_UPDATE (update() will handle)")
292
+ logger.debug("bulk_update: skipping AFTER_UPDATE (update() will handle)")
293
293
  else:
294
- logger.debug("bulk_update bypassed hooks")
294
+ logger.debug("bulk_update: hooks bypassed")
295
295
 
296
296
  return result
297
297
 
@@ -1,8 +1,11 @@
1
+ import logging
1
2
  from collections.abc import Callable
2
3
  from typing import Union
3
4
 
4
5
  from django_bulk_hooks.priority import Priority
5
6
 
7
+ logger = logging.getLogger(__name__)
8
+
6
9
  _hooks: dict[tuple[type, str], list[tuple[type, str, Callable, int]]] = {}
7
10
 
8
11
 
@@ -20,7 +23,9 @@ def register_hook(
20
23
  def get_hooks(model, event):
21
24
  key = (model, event)
22
25
  hooks = _hooks.get(key, [])
23
- logger.debug(f"get_hooks {model.__name__}.{event} found {len(hooks)} hooks")
26
+ # Only log when hooks are found or for specific events to reduce noise
27
+ if hooks or event in ['after_update', 'before_update', 'after_create', 'before_create']:
28
+ logger.debug(f"get_hooks {model.__name__}.{event} found {len(hooks)} hooks")
24
29
  return hooks
25
30
 
26
31
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: django-bulk-hooks
3
- Version: 0.1.219
3
+ Version: 0.1.221
4
4
  Summary: Hook-style hooks for Django bulk operations like bulk_create and bulk_update.
5
5
  License: MIT
6
6
  Keywords: django,bulk,hooks
@@ -1,5 +1,5 @@
1
1
  django_bulk_hooks/__init__.py,sha256=uUgpnb9AWjIAcWNpCMqBcOewSnpJjJYH6cjPbQkzoNU,140
2
- django_bulk_hooks/conditions.py,sha256=xHazd2hmSddQ3QcButFHjD4rG01tzD4hQMu8uoe7MRY,6513
2
+ django_bulk_hooks/conditions.py,sha256=V_f3Di2uCVUjoyfiU4BQCHmI4uUIRSRroApDcXlvnso,6349
3
3
  django_bulk_hooks/constants.py,sha256=3x1H1fSUUNo0DZONN7GUVDuySZctTR-jtByBHmAIX5w,303
4
4
  django_bulk_hooks/context.py,sha256=_NbGWTq9s66g0vbFIaqN4GlIHWQmFg3EQ44qY8YvvEg,1537
5
5
  django_bulk_hooks/decorators.py,sha256=WD7Jn7QAvY8F4wOsYlIpjoM9-FdHXSKB7hH9ot-lkYQ,4896
@@ -7,11 +7,11 @@ django_bulk_hooks/engine.py,sha256=t_kvgex6_iZEFc5LK-srBTZPe-1bdlYdip5LfWOc6lc,2
7
7
  django_bulk_hooks/enums.py,sha256=Zo8_tJzuzZ2IKfVc7gZ-0tWPT8q1QhqZbAyoh9ZVJbs,381
8
8
  django_bulk_hooks/handler.py,sha256=xZt8iNdYF-ACz-MnKMY0co6scWINU5V5wC1lyDn844k,4854
9
9
  django_bulk_hooks/manager.py,sha256=nfWiwU5-yAoxdnQsUMohxtyCpkV0MBv6X3wmipr9eQY,3697
10
- django_bulk_hooks/models.py,sha256=TA2dBIA1nJBiYt6joefWkpFIQZWysF9kZlkBYvEe59c,4358
10
+ django_bulk_hooks/models.py,sha256=exnXYVKEVbYAXhChCP8VdWTnKCnm9DiTcokEIBee1I0,4350
11
11
  django_bulk_hooks/priority.py,sha256=HG_2D35nga68lBCZmSXTcplXrjFoRgZFRDOy4ROKonY,376
12
- django_bulk_hooks/queryset.py,sha256=H9toczyQ4KZUGSi-M594vF3BRaSVQX-tqKb6GHe7ua0,32648
13
- django_bulk_hooks/registry.py,sha256=N7ZG67KdM1Vz1jpEkSnOWzzine8fUkaVquBSPkZorrU,901
14
- django_bulk_hooks-0.1.219.dist-info/LICENSE,sha256=dguKIcbDGeZD-vXWdLyErPUALYOvtX_fO4Zjhq481uk,1088
15
- django_bulk_hooks-0.1.219.dist-info/METADATA,sha256=zZC8QDWSEeetz38P_N83RqaTEufd99Qx2-U5Q9XpOJw,9061
16
- django_bulk_hooks-0.1.219.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
17
- django_bulk_hooks-0.1.219.dist-info/RECORD,,
12
+ django_bulk_hooks/queryset.py,sha256=YSDCMAf24YLeLJrRKCDYwbZInP2mK_Tcuw3EHLDkv_w,32605
13
+ django_bulk_hooks/registry.py,sha256=8UuhniiH5ChSeOKV1UUbqTEiIu25bZXvcHmkaRbxmME,1131
14
+ django_bulk_hooks-0.1.221.dist-info/LICENSE,sha256=dguKIcbDGeZD-vXWdLyErPUALYOvtX_fO4Zjhq481uk,1088
15
+ django_bulk_hooks-0.1.221.dist-info/METADATA,sha256=QVFXKdg3v7WcK1IsfDD3h3Nijg3tXdHtlqS6JoGemFo,9061
16
+ django_bulk_hooks-0.1.221.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
17
+ django_bulk_hooks-0.1.221.dist-info/RECORD,,