velocity-python 0.2.4__py3-none-any.whl → 0.2.5__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.
velocity/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
- __version__ = version = "0.2.4"
1
+ __version__ = version = "0.2.5"
2
2
 
3
3
  import importlib as _importlib
4
4
 
velocity/aws/authz.py CHANGED
@@ -80,6 +80,7 @@ from __future__ import annotations
80
80
 
81
81
  import logging
82
82
  import re
83
+ import sys
83
84
  from dataclasses import dataclass, field, replace
84
85
  from fnmatch import fnmatchcase
85
86
  from typing import Any, Callable, Optional
@@ -379,22 +380,42 @@ BUILTIN_RULES = (permit("data.ordinary_tables", DATA_ACCESS, when=_ordinary_tabl
379
380
 
380
381
  _REGISTERED = {}
381
382
  _REGISTERED_TUPLE = None
383
+ # name -> the globals of the module that registered it. A module imported a
384
+ # second time (importlib.reload, a test that patches sys.modules) runs with
385
+ # new globals under the same __name__ and builds new condition closures, so
386
+ # its rules never compare equal to the first import's.
387
+ _OWNERS = {}
382
388
 
383
389
 
384
390
  def register(*rules):
385
391
  """Add rules to the ones every handler evaluates. Registering the same
386
- rule again is a no-op; a different rule under a taken name is an error."""
392
+ rule again is a no-op, and so is a module re-registering its own rules
393
+ when it is imported again (the new rules replace the old). A different
394
+ rule under a taken name is otherwise an error."""
387
395
  global _REGISTERED_TUPLE
396
+ caller = sys._getframe(1).f_globals
388
397
  for rule in rules:
389
398
  if not isinstance(rule, Rule):
390
399
  raise ValueError("register() takes rules made by permit() or forbid().")
391
400
  known = _REGISTERED.get(rule.name)
392
- if known is not None and known != rule:
401
+ if known is not None and known != rule and not _reimported(rule.name, caller):
393
402
  raise ValueError(f"An authorization rule named '{rule.name}' exists.")
394
403
  _REGISTERED[rule.name] = rule
404
+ _OWNERS[rule.name] = caller
395
405
  _REGISTERED_TUPLE = None
396
406
 
397
407
 
408
+ def _reimported(name, caller):
409
+ """True when ``caller`` is a fresh import of the module that registered
410
+ ``name``: same module name, different globals."""
411
+ owner = _OWNERS.get(name)
412
+ return (
413
+ owner is not None
414
+ and owner is not caller
415
+ and owner.get("__name__") == caller.get("__name__")
416
+ )
417
+
418
+
398
419
  def registered():
399
420
  """Every rule a handler evaluates before its own. The same tuple object
400
421
  until a rule is registered, so its action index is built once."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: velocity-python
3
- Version: 0.2.4
3
+ Version: 0.2.5
4
4
  Summary: A rapid application development library for interfacing with data storage
5
5
  Author-email: Velocity Team <info@codeclubs.org>
6
6
  License-Expression: MIT
@@ -1,9 +1,9 @@
1
- velocity/__init__.py,sha256=84gbnHEUDdcmEw4DdO9GRo7A5VBhALffvnNP7_LlCW8,362
1
+ velocity/__init__.py,sha256=V1lljCRWKU9tFCI6LxgFTWSNei85X0V-LOuyoqcJS3Y,362
2
2
  velocity/cache.py,sha256=pthvw7gDVEXRzkTcQtA5YVf4Q1IxAamWsba4UReT0RE,8933
3
3
  velocity/logging.py,sha256=MAsZap1cDSdOBNRc_9ezQxup5dHOS0ARxU9NI_-UK3E,4037
4
4
  velocity/aws/__init__.py,sha256=XJJ79gnPlhg3aJij713PB8-vjQOt-BkqxYeGCBOxAu8,3460
5
5
  velocity/aws/amplify.py,sha256=N_763LiraJfuLYSllGKG6jfP2oyCJgtrK_wI2UZKv1E,8852
6
- velocity/aws/authz.py,sha256=377Cse7T9-TlCbeUvPWtg5j6oMy2tvQi8rCA9892TXc,49811
6
+ velocity/aws/authz.py,sha256=C9D-_W6pKWrHCa8oLj2spFhpHKJ7FAhu_sNHRPl0y-8,50688
7
7
  velocity/aws/blobs.py,sha256=2TlTZ3KPxBdXDJ99aVSgDLR11wPQ8O3BbtNbY8mFQ28,9691
8
8
  velocity/aws/dirty_pipeline.py,sha256=DQHsCPQPWwiy_E7nxX8kO3DgvQTFkVDaDOjlBcmblyE,3331
9
9
  velocity/aws/email.py,sha256=CAvXTAUxJqMaT8ylpRwRcVEA4YLFMUuHCrwYLVE4G1E,6243
@@ -223,9 +223,9 @@ velocity/payment/stripe_adapter.py,sha256=6EmVBZZchg2s3Teya0eQGA_8pvSK_teizr036U
223
223
  velocity/payment/stripe_mirror.py,sha256=6GKJk_PjAgySqFEuxbcuV423OfuGXupVTiGu9QwS5W8,12320
224
224
  velocity/testing/__init__.py,sha256=WtYMDHgCLxOq6mlemcOYV5Y9HqF_2QQgSfuAjFRg69Q,731
225
225
  velocity/testing/fake_db.py,sha256=phgdulk5owf3noUDpEfI7yFsVcKxRGZ82f2BJPYnaiU,53226
226
- velocity_python-0.2.4.dist-info/licenses/LICENSE,sha256=aoN245GG8s9oRUU89KNiGTU4_4OtnNmVi4hQeChg6rM,1076
227
- velocity_python-0.2.4.dist-info/METADATA,sha256=wYu_9tM6EPj1sLFlthIKiPxjPin8VYr3h-TBzoteM5I,17782
228
- velocity_python-0.2.4.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
229
- velocity_python-0.2.4.dist-info/entry_points.txt,sha256=nXUKJHkOGQCSPoagdmMNd_qycrle1LVU-GhYknLGM1M,56
230
- velocity_python-0.2.4.dist-info/top_level.txt,sha256=JW2vJPmodgdgSz7H6yoZvnxF8S3fTMIv-YJWCT1sNW0,9
231
- velocity_python-0.2.4.dist-info/RECORD,,
226
+ velocity_python-0.2.5.dist-info/licenses/LICENSE,sha256=aoN245GG8s9oRUU89KNiGTU4_4OtnNmVi4hQeChg6rM,1076
227
+ velocity_python-0.2.5.dist-info/METADATA,sha256=yorIMbxWLu_XdjOPD6muPpfm-qldBUidXT7IR3G01Hc,17782
228
+ velocity_python-0.2.5.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
229
+ velocity_python-0.2.5.dist-info/entry_points.txt,sha256=nXUKJHkOGQCSPoagdmMNd_qycrle1LVU-GhYknLGM1M,56
230
+ velocity_python-0.2.5.dist-info/top_level.txt,sha256=JW2vJPmodgdgSz7H6yoZvnxF8S3fTMIv-YJWCT1sNW0,9
231
+ velocity_python-0.2.5.dist-info/RECORD,,