pytaskwarrior 2.0.2__tar.gz → 2.0.3__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.2 → pytaskwarrior-2.0.3}/PKG-INFO +10 -1
  2. {pytaskwarrior-2.0.2 → pytaskwarrior-2.0.3}/PYPI_README.md +9 -0
  3. {pytaskwarrior-2.0.2 → pytaskwarrior-2.0.3}/README.md +8 -0
  4. {pytaskwarrior-2.0.2 → pytaskwarrior-2.0.3}/pyproject.toml +1 -1
  5. {pytaskwarrior-2.0.2 → pytaskwarrior-2.0.3}/src/pytaskwarrior.egg-info/PKG-INFO +10 -1
  6. {pytaskwarrior-2.0.2 → pytaskwarrior-2.0.3}/src/taskwarrior/adapters/taskwarrior_adapter.py +54 -0
  7. {pytaskwarrior-2.0.2 → pytaskwarrior-2.0.3}/src/taskwarrior/main.py +19 -0
  8. {pytaskwarrior-2.0.2 → pytaskwarrior-2.0.3}/LICENSE +0 -0
  9. {pytaskwarrior-2.0.2 → pytaskwarrior-2.0.3}/setup.cfg +0 -0
  10. {pytaskwarrior-2.0.2 → pytaskwarrior-2.0.3}/src/__init__.py +0 -0
  11. {pytaskwarrior-2.0.2 → pytaskwarrior-2.0.3}/src/pytaskwarrior.egg-info/SOURCES.txt +0 -0
  12. {pytaskwarrior-2.0.2 → pytaskwarrior-2.0.3}/src/pytaskwarrior.egg-info/dependency_links.txt +0 -0
  13. {pytaskwarrior-2.0.2 → pytaskwarrior-2.0.3}/src/pytaskwarrior.egg-info/requires.txt +0 -0
  14. {pytaskwarrior-2.0.2 → pytaskwarrior-2.0.3}/src/pytaskwarrior.egg-info/top_level.txt +0 -0
  15. {pytaskwarrior-2.0.2 → pytaskwarrior-2.0.3}/src/taskwarrior/__init__.py +0 -0
  16. {pytaskwarrior-2.0.2 → pytaskwarrior-2.0.3}/src/taskwarrior/adapters/__init__.py +0 -0
  17. {pytaskwarrior-2.0.2 → pytaskwarrior-2.0.3}/src/taskwarrior/config/config_store.py +0 -0
  18. {pytaskwarrior-2.0.2 → pytaskwarrior-2.0.3}/src/taskwarrior/config/uda_parser.py +0 -0
  19. {pytaskwarrior-2.0.2 → pytaskwarrior-2.0.3}/src/taskwarrior/dto/__init__.py +0 -0
  20. {pytaskwarrior-2.0.2 → pytaskwarrior-2.0.3}/src/taskwarrior/dto/annotation_dto.py +0 -0
  21. {pytaskwarrior-2.0.2 → pytaskwarrior-2.0.3}/src/taskwarrior/dto/context_dto.py +0 -0
  22. {pytaskwarrior-2.0.2 → pytaskwarrior-2.0.3}/src/taskwarrior/dto/task_dto.py +0 -0
  23. {pytaskwarrior-2.0.2 → pytaskwarrior-2.0.3}/src/taskwarrior/dto/uda_dto.py +0 -0
  24. {pytaskwarrior-2.0.2 → pytaskwarrior-2.0.3}/src/taskwarrior/enums.py +0 -0
  25. {pytaskwarrior-2.0.2 → pytaskwarrior-2.0.3}/src/taskwarrior/exceptions.py +0 -0
  26. {pytaskwarrior-2.0.2 → pytaskwarrior-2.0.3}/src/taskwarrior/py.typed +0 -0
  27. {pytaskwarrior-2.0.2 → pytaskwarrior-2.0.3}/src/taskwarrior/registry/__init__.py +0 -0
  28. {pytaskwarrior-2.0.2 → pytaskwarrior-2.0.3}/src/taskwarrior/registry/uda_registry.py +0 -0
  29. {pytaskwarrior-2.0.2 → pytaskwarrior-2.0.3}/src/taskwarrior/services/__init__.py +0 -0
  30. {pytaskwarrior-2.0.2 → pytaskwarrior-2.0.3}/src/taskwarrior/services/context_service.py +0 -0
  31. {pytaskwarrior-2.0.2 → pytaskwarrior-2.0.3}/src/taskwarrior/services/uda_service.py +0 -0
  32. {pytaskwarrior-2.0.2 → pytaskwarrior-2.0.3}/src/taskwarrior/utils/__init__.py +0 -0
  33. {pytaskwarrior-2.0.2 → pytaskwarrior-2.0.3}/src/taskwarrior/utils/conversions.py +0 -0
  34. {pytaskwarrior-2.0.2 → pytaskwarrior-2.0.3}/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.2
3
+ Version: 2.0.3
4
4
  Summary: Taskwarrior wrapper python module
5
5
  Author-email: sznicolas <sznicolas@users.noreply.github.com>
6
6
  License-Expression: MIT
@@ -42,6 +42,7 @@ Production-ready with 164 tests (96% coverage), strict type checking, and profes
42
42
  - Type-safe with Pydantic models
43
43
  - Context management
44
44
  - UDA (User Defined Attributes) support
45
+ - Tag discovery and `@` context tags
45
46
  - Recurring tasks and annotations
46
47
  - Consistent exception hierarchy (`TaskNotFound`, `TaskValidationError`, `TaskOperationError`, `TaskConfigurationError`, …)
47
48
 
@@ -80,6 +81,14 @@ for t in tw.get_tasks():
80
81
  tw.done_task(added.uuid)
81
82
  ```
82
83
 
84
+ ## Tags
85
+
86
+ ```python
87
+ tags = tw.get_tags() # virtual tags excluded
88
+ all_tags = tw.get_tags(include_virtual_tags=True)
89
+ context_tags = tw.get_context_tags() # tags starting with "@"
90
+ ```
91
+
83
92
  ## Documentation
84
93
 
85
94
  Full documentation: [GitHub Repository](https://github.com/sznicolas/pytaskwarrior/)
@@ -17,6 +17,7 @@ Production-ready with 164 tests (96% coverage), strict type checking, and profes
17
17
  - Type-safe with Pydantic models
18
18
  - Context management
19
19
  - UDA (User Defined Attributes) support
20
+ - Tag discovery and `@` context tags
20
21
  - Recurring tasks and annotations
21
22
  - Consistent exception hierarchy (`TaskNotFound`, `TaskValidationError`, `TaskOperationError`, `TaskConfigurationError`, …)
22
23
 
@@ -55,6 +56,14 @@ for t in tw.get_tasks():
55
56
  tw.done_task(added.uuid)
56
57
  ```
57
58
 
59
+ ## Tags
60
+
61
+ ```python
62
+ tags = tw.get_tags() # virtual tags excluded
63
+ all_tags = tw.get_tags(include_virtual_tags=True)
64
+ context_tags = tw.get_context_tags() # tags starting with "@"
65
+ ```
66
+
58
67
  ## Documentation
59
68
 
60
69
  Full documentation: [GitHub Repository](https://github.com/sznicolas/pytaskwarrior/)
@@ -17,6 +17,7 @@ A modern Python wrapper for [TaskWarrior](https://taskwarrior.org/) v3.4, the co
17
17
  - **Type-safe** - Pydantic models with full type hints
18
18
  - **Context management** - Define, apply, and switch contexts
19
19
  - **UDA support** - User Defined Attributes
20
+ - **Tag discovery** - List real tags, virtual tags, and `@` context tags
20
21
  - **Recurring tasks** - Full recurrence support
21
22
  - **Annotations** - Add notes to tasks
22
23
  - **Date calculations** - Use TaskWarrior's date expressions
@@ -128,6 +129,13 @@ tw = TaskWarrior(
128
129
  | `stop_task(uuid)` | Stop working on task |
129
130
  | `annotate_task(uuid, annotation)` | Add annotation to task |
130
131
 
132
+ #### Tags Operations
133
+
134
+ | Method | Description |
135
+ |--------|-------------|
136
+ | `get_tags(include_virtual_tags=False)` | List tags, excluding virtual tags by default |
137
+ | `get_context_tags()` | List tags that start with `@` |
138
+
131
139
  #### Context Operations
132
140
 
133
141
  | Method | Description |
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pytaskwarrior"
3
- version = "2.0.2"
3
+ version = "2.0.3"
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.2
3
+ Version: 2.0.3
4
4
  Summary: Taskwarrior wrapper python module
5
5
  Author-email: sznicolas <sznicolas@users.noreply.github.com>
6
6
  License-Expression: MIT
@@ -42,6 +42,7 @@ Production-ready with 164 tests (96% coverage), strict type checking, and profes
42
42
  - Type-safe with Pydantic models
43
43
  - Context management
44
44
  - UDA (User Defined Attributes) support
45
+ - Tag discovery and `@` context tags
45
46
  - Recurring tasks and annotations
46
47
  - Consistent exception hierarchy (`TaskNotFound`, `TaskValidationError`, `TaskOperationError`, `TaskConfigurationError`, …)
47
48
 
@@ -80,6 +81,14 @@ for t in tw.get_tasks():
80
81
  tw.done_task(added.uuid)
81
82
  ```
82
83
 
84
+ ## Tags
85
+
86
+ ```python
87
+ tags = tw.get_tags() # virtual tags excluded
88
+ all_tags = tw.get_tags(include_virtual_tags=True)
89
+ context_tags = tw.get_context_tags() # tags starting with "@"
90
+ ```
91
+
83
92
  ## Documentation
84
93
 
85
94
  Full documentation: [GitHub Repository](https://github.com/sznicolas/pytaskwarrior/)
@@ -26,6 +26,40 @@ from ..exceptions import (
26
26
 
27
27
  logger = logging.getLogger(__name__)
28
28
 
29
+ TASKWARRIOR_VIRTUAL_TAGS: tuple[str, ...] = (
30
+ "BLOCKED",
31
+ "UNBLOCKED",
32
+ "BLOCKING",
33
+ "DUE",
34
+ "DUETODAY",
35
+ "TODAY",
36
+ "OVERDUE",
37
+ "WEEK",
38
+ "MONTH",
39
+ "QUARTER",
40
+ "YEAR",
41
+ "ACTIVE",
42
+ "SCHEDULED",
43
+ "PARENT",
44
+ "CHILD",
45
+ "UNTIL",
46
+ "WAITING",
47
+ "ANNOTATED",
48
+ "READY",
49
+ "YESTERDAY",
50
+ "TOMORROW",
51
+ "TAGGED",
52
+ "PENDING",
53
+ "COMPLETED",
54
+ "DELETED",
55
+ "UDA",
56
+ "ORPHAN",
57
+ "PRIORITY",
58
+ "PROJECT",
59
+ "LATEST",
60
+ )
61
+ TASKWARRIOR_VIRTUAL_TAG_SET = frozenset(TASKWARRIOR_VIRTUAL_TAGS)
62
+
29
63
 
30
64
  class TaskWarriorAdapter:
31
65
  """Low-level adapter for TaskWarrior CLI commands.
@@ -515,3 +549,23 @@ class TaskWarriorAdapter:
515
549
 
516
550
  projects = [line.strip() for line in result.stdout.split("\n") if line.strip()]
517
551
  return projects
552
+
553
+ def get_tags(self, include_virtual_tags: bool = False) -> list[str]:
554
+ """Get all tags defined in TaskWarrior.
555
+
556
+ Args:
557
+ include_virtual_tags: If ``True``, include TaskWarrior virtual tags
558
+ such as ``TODAY`` and ``READY``.
559
+
560
+ Returns:
561
+ List of tag names.
562
+ """
563
+ result = self.run_task_command(["_tags"])
564
+
565
+ if result.returncode != 0:
566
+ raise TaskWarriorError(f"Failed to get tags: {result.stderr}")
567
+
568
+ tags = [line.strip() for line in result.stdout.splitlines() if line.strip()]
569
+ if include_virtual_tags:
570
+ return list(dict.fromkeys(tags + list(TASKWARRIOR_VIRTUAL_TAGS)))
571
+ return [tag for tag in tags if tag not in TASKWARRIOR_VIRTUAL_TAG_SET]
@@ -566,3 +566,22 @@ class TaskWarrior:
566
566
  ['dmc.fil.aretordre', 'dmc.fil.adérouler', 'perso', 'perso.orl', 'pro']
567
567
  """
568
568
  return self.adapter.get_projects()
569
+
570
+ def get_tags(self, include_virtual_tags: bool = False) -> list[str]:
571
+ """Get all tags defined in TaskWarrior.
572
+
573
+ Args:
574
+ include_virtual_tags: If ``True``, include TaskWarrior virtual tags
575
+ such as ``TODAY`` and ``READY``.
576
+
577
+ Returns:
578
+ List of tag names.
579
+ """
580
+ return self.adapter.get_tags(include_virtual_tags=include_virtual_tags)
581
+
582
+ def get_context_tags(self) -> list[str]:
583
+ """Return tags that follow the ``@`` context convention.
584
+
585
+ This is a convenience filter for user-defined tags such as ``@work``.
586
+ """
587
+ return [tag for tag in self.get_tags() if tag.startswith("@")]
File without changes
File without changes