proactive-gate 0.7.0__tar.gz → 0.7.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 (21) hide show
  1. {proactive_gate-0.7.0 → proactive_gate-0.7.2}/PKG-INFO +1 -1
  2. {proactive_gate-0.7.0 → proactive_gate-0.7.2}/pyproject.toml +1 -1
  3. {proactive_gate-0.7.0 → proactive_gate-0.7.2}/src/proactive_gate/__init__.py +1 -1
  4. {proactive_gate-0.7.0 → proactive_gate-0.7.2}/src/proactive_gate/clock.py +2 -2
  5. {proactive_gate-0.7.0 → proactive_gate-0.7.2}/tests/test_clock.py +22 -0
  6. {proactive_gate-0.7.0 → proactive_gate-0.7.2}/.gitignore +0 -0
  7. {proactive_gate-0.7.0 → proactive_gate-0.7.2}/README.md +0 -0
  8. {proactive_gate-0.7.0 → proactive_gate-0.7.2}/src/proactive_gate/checks.py +0 -0
  9. {proactive_gate-0.7.0 → proactive_gate-0.7.2}/src/proactive_gate/conformance.py +0 -0
  10. {proactive_gate-0.7.0 → proactive_gate-0.7.2}/src/proactive_gate/explain.py +0 -0
  11. {proactive_gate-0.7.0 → proactive_gate-0.7.2}/src/proactive_gate/gate.py +0 -0
  12. {proactive_gate-0.7.0 → proactive_gate-0.7.2}/src/proactive_gate/policy.py +0 -0
  13. {proactive_gate-0.7.0 → proactive_gate-0.7.2}/src/proactive_gate/presets.py +0 -0
  14. {proactive_gate-0.7.0 → proactive_gate-0.7.2}/src/proactive_gate/py.typed +0 -0
  15. {proactive_gate-0.7.0 → proactive_gate-0.7.2}/src/proactive_gate/stores.py +0 -0
  16. {proactive_gate-0.7.0 → proactive_gate-0.7.2}/src/proactive_gate/types.py +0 -0
  17. {proactive_gate-0.7.0 → proactive_gate-0.7.2}/tests/conftest.py +0 -0
  18. {proactive_gate-0.7.0 → proactive_gate-0.7.2}/tests/test_conformance.py +0 -0
  19. {proactive_gate-0.7.0 → proactive_gate-0.7.2}/tests/test_explain.py +0 -0
  20. {proactive_gate-0.7.0 → proactive_gate-0.7.2}/tests/test_stores.py +0 -0
  21. {proactive_gate-0.7.0 → proactive_gate-0.7.2}/tests/test_version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: proactive-gate
3
- Version: 0.7.0
3
+ Version: 0.7.2
4
4
  Summary: Decide whether a proactive assistant may speak now: ordered checks, budgets, quiet hours, JSON policies, shared conformance fixtures with the TypeScript package.
5
5
  Project-URL: Homepage, https://bubblegunn.github.io/proactive-gate/
6
6
  Project-URL: Documentation, https://bubblegunn.github.io/proactive-gate/start/
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "proactive-gate"
7
- version = "0.7.0"
7
+ version = "0.7.2"
8
8
  description = "Decide whether a proactive assistant may speak now: ordered checks, budgets, quiet hours, JSON policies, shared conformance fixtures with the TypeScript package."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -22,7 +22,7 @@ from .types import (
22
22
  UserState,
23
23
  )
24
24
 
25
- __version__ = "0.7.0"
25
+ __version__ = "0.7.2"
26
26
 
27
27
  __all__ = [
28
28
  "EN", "PRIORITY_RANK", "KNOWN_CHECKS", "AsyncGate", "AsyncMemoryStore", "AsyncSqliteStore", "AsyncStore", "Candidate", "Check",
@@ -10,7 +10,7 @@ DAY_SECONDS = 24 * 60 * 60
10
10
  def local_clock(now: datetime, tz: str) -> tuple[int, str]:
11
11
  """Minutes since local midnight and the local calendar day, ``YYYY-MM-DD``."""
12
12
  local = now.astimezone(ZoneInfo(tz))
13
- return local.hour * 60 + local.minute, local.strftime("%Y-%m-%d")
13
+ return local.hour * 60 + local.minute, f"{local.year:04d}-{local.month:02d}-{local.day:02d}"
14
14
 
15
15
 
16
16
  def parse_hhmm(text: str) -> int:
@@ -37,7 +37,7 @@ def local_day(now: datetime, tz: str | None) -> str:
37
37
 
38
38
  def iso_week_key(day: str) -> str:
39
39
  year, week, _ = datetime.strptime(day, "%Y-%m-%d").isocalendar()
40
- return f"{year}-W{week:02d}"
40
+ return f"{year:04d}-W{week:02d}"
41
41
 
42
42
 
43
43
  WEEKDAYS = ("mon", "tue", "wed", "thu", "fri", "sat", "sun")
@@ -33,3 +33,25 @@ def test_iso_week_key_uses_the_iso_year() -> None:
33
33
  assert iso_week_key("2026-01-01") == "2026-W01"
34
34
  assert iso_week_key("2027-01-01") == "2026-W53"
35
35
  assert iso_week_key("2026-09-07") == "2026-W37"
36
+
37
+
38
+ def test_local_day_is_four_digits_whatever_the_year() -> None:
39
+ """``strftime("%Y")`` pads on most builds and not on all of them (#38).
40
+
41
+ The day string is built from the fields instead, so the result does not depend on which
42
+ C library the interpreter was linked against. Two interpreters on one machine disagreed
43
+ about this before the fix, which is the worst kind of test to have to debug.
44
+ """
45
+ for year, expected in ((1, "0001-06-01"), (99, "0099-06-01"), (999, "0999-06-01"), (2026, "2026-06-01")):
46
+ now = datetime(year, 6, 1, 12, 0, tzinfo=timezone.utc)
47
+ assert local_clock(now, "UTC") == (720, expected)
48
+
49
+
50
+ def test_iso_week_key_pads_the_year_to_the_spec_format() -> None:
51
+ """5.1 fixes the key format at ``YYYY-Www``; this emitted ``1-W22`` (#37).
52
+
53
+ The TypeScript sibling writes ``0001-W22`` for the same instant, so an unpadded key here
54
+ meant one store served two sets of counters without either side noticing.
55
+ """
56
+ assert iso_week_key("0001-06-01") == "0001-W22"
57
+ assert iso_week_key("0999-06-01") == "0999-W22"
File without changes