pytaskwarrior 2.0.3__tar.gz → 2.0.4__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 (34) hide show
  1. {pytaskwarrior-2.0.3 → pytaskwarrior-2.0.4}/PKG-INFO +1 -1
  2. {pytaskwarrior-2.0.3 → pytaskwarrior-2.0.4}/pyproject.toml +1 -1
  3. {pytaskwarrior-2.0.3 → pytaskwarrior-2.0.4}/src/pytaskwarrior.egg-info/PKG-INFO +1 -1
  4. {pytaskwarrior-2.0.3 → pytaskwarrior-2.0.4}/src/taskwarrior/main.py +41 -0
  5. {pytaskwarrior-2.0.3 → pytaskwarrior-2.0.4}/src/taskwarrior/services/uda_service.py +35 -2
  6. {pytaskwarrior-2.0.3 → pytaskwarrior-2.0.4}/LICENSE +0 -0
  7. {pytaskwarrior-2.0.3 → pytaskwarrior-2.0.4}/PYPI_README.md +0 -0
  8. {pytaskwarrior-2.0.3 → pytaskwarrior-2.0.4}/README.md +0 -0
  9. {pytaskwarrior-2.0.3 → pytaskwarrior-2.0.4}/setup.cfg +0 -0
  10. {pytaskwarrior-2.0.3 → pytaskwarrior-2.0.4}/src/__init__.py +0 -0
  11. {pytaskwarrior-2.0.3 → pytaskwarrior-2.0.4}/src/pytaskwarrior.egg-info/SOURCES.txt +0 -0
  12. {pytaskwarrior-2.0.3 → pytaskwarrior-2.0.4}/src/pytaskwarrior.egg-info/dependency_links.txt +0 -0
  13. {pytaskwarrior-2.0.3 → pytaskwarrior-2.0.4}/src/pytaskwarrior.egg-info/requires.txt +0 -0
  14. {pytaskwarrior-2.0.3 → pytaskwarrior-2.0.4}/src/pytaskwarrior.egg-info/top_level.txt +0 -0
  15. {pytaskwarrior-2.0.3 → pytaskwarrior-2.0.4}/src/taskwarrior/__init__.py +0 -0
  16. {pytaskwarrior-2.0.3 → pytaskwarrior-2.0.4}/src/taskwarrior/adapters/__init__.py +0 -0
  17. {pytaskwarrior-2.0.3 → pytaskwarrior-2.0.4}/src/taskwarrior/adapters/taskwarrior_adapter.py +0 -0
  18. {pytaskwarrior-2.0.3 → pytaskwarrior-2.0.4}/src/taskwarrior/config/config_store.py +0 -0
  19. {pytaskwarrior-2.0.3 → pytaskwarrior-2.0.4}/src/taskwarrior/config/uda_parser.py +0 -0
  20. {pytaskwarrior-2.0.3 → pytaskwarrior-2.0.4}/src/taskwarrior/dto/__init__.py +0 -0
  21. {pytaskwarrior-2.0.3 → pytaskwarrior-2.0.4}/src/taskwarrior/dto/annotation_dto.py +0 -0
  22. {pytaskwarrior-2.0.3 → pytaskwarrior-2.0.4}/src/taskwarrior/dto/context_dto.py +0 -0
  23. {pytaskwarrior-2.0.3 → pytaskwarrior-2.0.4}/src/taskwarrior/dto/task_dto.py +0 -0
  24. {pytaskwarrior-2.0.3 → pytaskwarrior-2.0.4}/src/taskwarrior/dto/uda_dto.py +0 -0
  25. {pytaskwarrior-2.0.3 → pytaskwarrior-2.0.4}/src/taskwarrior/enums.py +0 -0
  26. {pytaskwarrior-2.0.3 → pytaskwarrior-2.0.4}/src/taskwarrior/exceptions.py +0 -0
  27. {pytaskwarrior-2.0.3 → pytaskwarrior-2.0.4}/src/taskwarrior/py.typed +0 -0
  28. {pytaskwarrior-2.0.3 → pytaskwarrior-2.0.4}/src/taskwarrior/registry/__init__.py +0 -0
  29. {pytaskwarrior-2.0.3 → pytaskwarrior-2.0.4}/src/taskwarrior/registry/uda_registry.py +0 -0
  30. {pytaskwarrior-2.0.3 → pytaskwarrior-2.0.4}/src/taskwarrior/services/__init__.py +0 -0
  31. {pytaskwarrior-2.0.3 → pytaskwarrior-2.0.4}/src/taskwarrior/services/context_service.py +0 -0
  32. {pytaskwarrior-2.0.3 → pytaskwarrior-2.0.4}/src/taskwarrior/utils/__init__.py +0 -0
  33. {pytaskwarrior-2.0.3 → pytaskwarrior-2.0.4}/src/taskwarrior/utils/conversions.py +0 -0
  34. {pytaskwarrior-2.0.3 → pytaskwarrior-2.0.4}/src/taskwarrior/utils/dto_converter.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytaskwarrior
3
- Version: 2.0.3
3
+ Version: 2.0.4
4
4
  Summary: Taskwarrior wrapper python module
5
5
  Author-email: sznicolas <sznicolas@users.noreply.github.com>
6
6
  License-Expression: MIT
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pytaskwarrior"
3
- version = "2.0.3"
3
+ version = "2.0.4"
4
4
  description = "Taskwarrior wrapper python module"
5
5
  readme = "PYPI_README.md"
6
6
  requires-python = ">=3.12"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytaskwarrior
3
- Version: 2.0.3
3
+ Version: 2.0.4
4
4
  Summary: Taskwarrior wrapper python module
5
5
  Author-email: sznicolas <sznicolas@users.noreply.github.com>
6
6
  License-Expression: MIT
@@ -554,6 +554,47 @@ class TaskWarrior:
554
554
  """
555
555
  return self.uda_service.registry.get_uda(name)
556
556
 
557
+ def define_uda(self, uda: UdaConfig) -> None:
558
+ """Define a new UDA via the TaskWarrior facade.
559
+
560
+ Delegates to UdaService.define_uda which performs the necessary
561
+ TaskWarrior config writes and registers the UDA in the local registry.
562
+
563
+ Args:
564
+ uda: The UdaConfig describing the UDA to create.
565
+
566
+ Raises:
567
+ TaskOperationError: If creating the UDA via the underlying adapter fails.
568
+ """
569
+ self.uda_service.define_uda(uda)
570
+
571
+ def update_uda(self, uda: UdaConfig) -> None:
572
+ """Update an existing UDA via the TaskWarrior facade.
573
+
574
+ Delegates to UdaService.update_uda.
575
+
576
+ Args:
577
+ uda: The UdaConfig with updated fields.
578
+
579
+ Raises:
580
+ TaskOperationError: If applying the update fails.
581
+ """
582
+ self.uda_service.update_uda(uda)
583
+
584
+ def delete_uda(self, uda: UdaConfig) -> None:
585
+ """Delete a UDA via the TaskWarrior facade.
586
+
587
+ Delegates to UdaService.delete_uda which removes TaskWarrior config
588
+ keys and the UDA from the local registry.
589
+
590
+ Args:
591
+ uda: The UdaConfig identifying the UDA to remove.
592
+
593
+ Raises:
594
+ TaskOperationError: If deletion fails for reasons other than missing keys.
595
+ """
596
+ self.uda_service.delete_uda(uda)
597
+
557
598
  def get_projects(self) -> list[str]:
558
599
  """Get all projects defined in TaskWarrior.
559
600
 
@@ -59,6 +59,16 @@ class UdaService:
59
59
 
60
60
  The service executes the required `task config` commands via the adapter
61
61
  and only updates the registry if all commands succeed.
62
+
63
+ Args:
64
+ uda: The UdaConfig describing the UDA to create.
65
+
66
+ Raises:
67
+ TaskOperationError: If any underlying TaskWarrior config command fails.
68
+
69
+ Example:
70
+ >>> uda = UdaConfig(name="sev", uda_type=UdaType.STRING, label="Severity")
71
+ >>> service.define_uda(uda)
62
72
  """
63
73
  # Build commands to define the UDA
64
74
  field_names = uda.__class__.model_fields.keys() - {"name"}
@@ -86,6 +96,12 @@ class UdaService:
86
96
  """Update an existing UDA in TaskWarrior and in the registry.
87
97
 
88
98
  Executes commands via adapter and updates the registry on success.
99
+
100
+ Args:
101
+ uda: The UdaConfig with updated settings to apply.
102
+
103
+ Raises:
104
+ TaskOperationError: If applying the updated configuration fails.
89
105
  """
90
106
  # For now, same as define_uda
91
107
  self.define_uda(uda)
@@ -94,9 +110,26 @@ class UdaService:
94
110
  """Delete a UDA from TaskWarrior and remove it from the registry.
95
111
 
96
112
  Executes `task config <key>` without a value to remove each UDA key.
113
+
114
+ Args:
115
+ uda: The UdaConfig identifying the UDA to remove.
116
+
117
+ Raises:
118
+ TaskOperationError: If an unexpected TaskWarrior error occurs while
119
+ attempting to remove configuration keys (missing keys are tolerated).
97
120
  """
98
- field_names = uda.__class__.model_fields.keys()
99
- for key in field_names:
121
+ # Mirror define_uda: skip 'name' and map internal 'uda_type' -> TaskWarrior 'type'
122
+ field_names = set(uda.__class__.model_fields.keys()) - {"name"}
123
+ keys_to_delete: list[str] = []
124
+
125
+ if "uda_type" in field_names:
126
+ keys_to_delete.append("type")
127
+ field_names.remove("uda_type")
128
+
129
+ # delete remaining fields deterministically
130
+ keys_to_delete.extend(sorted(field_names))
131
+
132
+ for key in keys_to_delete:
100
133
  cmd = ["config", f"uda.{uda.name}.{key}"]
101
134
  result = self.adapter.run_task_command(cmd)
102
135
  if getattr(result, "returncode", 0) != 0:
File without changes
File without changes
File without changes