rustfava 0.1.0__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.
Files changed (187) hide show
  1. rustfava/__init__.py +30 -0
  2. rustfava/_ctx_globals_class.py +55 -0
  3. rustfava/api_models.py +36 -0
  4. rustfava/application.py +534 -0
  5. rustfava/beans/__init__.py +6 -0
  6. rustfava/beans/abc.py +327 -0
  7. rustfava/beans/account.py +79 -0
  8. rustfava/beans/create.py +377 -0
  9. rustfava/beans/flags.py +20 -0
  10. rustfava/beans/funcs.py +38 -0
  11. rustfava/beans/helpers.py +52 -0
  12. rustfava/beans/ingest.py +75 -0
  13. rustfava/beans/load.py +31 -0
  14. rustfava/beans/prices.py +151 -0
  15. rustfava/beans/protocols.py +82 -0
  16. rustfava/beans/str.py +454 -0
  17. rustfava/beans/types.py +63 -0
  18. rustfava/cli.py +187 -0
  19. rustfava/context.py +13 -0
  20. rustfava/core/__init__.py +729 -0
  21. rustfava/core/accounts.py +161 -0
  22. rustfava/core/attributes.py +145 -0
  23. rustfava/core/budgets.py +207 -0
  24. rustfava/core/charts.py +301 -0
  25. rustfava/core/commodities.py +37 -0
  26. rustfava/core/conversion.py +229 -0
  27. rustfava/core/documents.py +87 -0
  28. rustfava/core/extensions.py +132 -0
  29. rustfava/core/fava_options.py +255 -0
  30. rustfava/core/file.py +542 -0
  31. rustfava/core/filters.py +484 -0
  32. rustfava/core/group_entries.py +97 -0
  33. rustfava/core/ingest.py +509 -0
  34. rustfava/core/inventory.py +167 -0
  35. rustfava/core/misc.py +105 -0
  36. rustfava/core/module_base.py +18 -0
  37. rustfava/core/number.py +106 -0
  38. rustfava/core/query.py +180 -0
  39. rustfava/core/query_shell.py +301 -0
  40. rustfava/core/tree.py +265 -0
  41. rustfava/core/watcher.py +219 -0
  42. rustfava/ext/__init__.py +232 -0
  43. rustfava/ext/auto_commit.py +61 -0
  44. rustfava/ext/portfolio_list/PortfolioList.js +34 -0
  45. rustfava/ext/portfolio_list/__init__.py +29 -0
  46. rustfava/ext/portfolio_list/templates/PortfolioList.html +15 -0
  47. rustfava/ext/rustfava_ext_test/RustfavaExtTest.js +42 -0
  48. rustfava/ext/rustfava_ext_test/__init__.py +207 -0
  49. rustfava/ext/rustfava_ext_test/templates/RustfavaExtTest.html +45 -0
  50. rustfava/ext/rustfava_ext_test/templates/RustfavaExtTestInclude.html +1 -0
  51. rustfava/help/__init__.py +15 -0
  52. rustfava/help/_index.md +29 -0
  53. rustfava/help/beancount_syntax.md +156 -0
  54. rustfava/help/budgets.md +31 -0
  55. rustfava/help/conversion.md +29 -0
  56. rustfava/help/extensions.md +111 -0
  57. rustfava/help/features.md +179 -0
  58. rustfava/help/filters.md +103 -0
  59. rustfava/help/import.md +27 -0
  60. rustfava/help/options.md +289 -0
  61. rustfava/helpers.py +30 -0
  62. rustfava/internal_api.py +221 -0
  63. rustfava/json_api.py +952 -0
  64. rustfava/plugins/__init__.py +3 -0
  65. rustfava/plugins/link_documents.py +107 -0
  66. rustfava/plugins/tag_discovered_documents.py +44 -0
  67. rustfava/py.typed +0 -0
  68. rustfava/rustledger/__init__.py +31 -0
  69. rustfava/rustledger/constants.py +76 -0
  70. rustfava/rustledger/engine.py +485 -0
  71. rustfava/rustledger/loader.py +273 -0
  72. rustfava/rustledger/options.py +202 -0
  73. rustfava/rustledger/query.py +331 -0
  74. rustfava/rustledger/types.py +830 -0
  75. rustfava/serialisation.py +220 -0
  76. rustfava/static/app.css +2988 -0
  77. rustfava/static/app.css.map +7 -0
  78. rustfava/static/app.js +12854 -0
  79. rustfava/static/app.js.map +7 -0
  80. rustfava/static/beancount-JFV44ZVZ.css +5 -0
  81. rustfava/static/beancount-JFV44ZVZ.css.map +7 -0
  82. rustfava/static/beancount-VTTKRGSK.js +4642 -0
  83. rustfava/static/beancount-VTTKRGSK.js.map +7 -0
  84. rustfava/static/bql-MGFRUMBP.js +333 -0
  85. rustfava/static/bql-MGFRUMBP.js.map +7 -0
  86. rustfava/static/chunk-E7ZF4ASL.js +23061 -0
  87. rustfava/static/chunk-E7ZF4ASL.js.map +7 -0
  88. rustfava/static/chunk-V24TLQHT.js +12673 -0
  89. rustfava/static/chunk-V24TLQHT.js.map +7 -0
  90. rustfava/static/favicon.ico +0 -0
  91. rustfava/static/fira-mono-cyrillic-400-normal-BLAGXRCE.woff2 +0 -0
  92. rustfava/static/fira-mono-cyrillic-500-normal-EN7JUAAW.woff2 +0 -0
  93. rustfava/static/fira-mono-cyrillic-ext-400-normal-EX7VARTS.woff2 +0 -0
  94. rustfava/static/fira-mono-cyrillic-ext-500-normal-ZDPTUPRR.woff2 +0 -0
  95. rustfava/static/fira-mono-greek-400-normal-COGHKMOA.woff2 +0 -0
  96. rustfava/static/fira-mono-greek-500-normal-4EN2PKZT.woff2 +0 -0
  97. rustfava/static/fira-mono-greek-ext-400-normal-DYEQIJH7.woff2 +0 -0
  98. rustfava/static/fira-mono-greek-ext-500-normal-SG73CVKQ.woff2 +0 -0
  99. rustfava/static/fira-mono-latin-400-normal-NA3VLV7E.woff2 +0 -0
  100. rustfava/static/fira-mono-latin-500-normal-YC77GFWD.woff2 +0 -0
  101. rustfava/static/fira-mono-latin-ext-400-normal-DIKTZ5PW.woff2 +0 -0
  102. rustfava/static/fira-mono-latin-ext-500-normal-ZWY4UO4V.woff2 +0 -0
  103. rustfava/static/fira-mono-symbols2-400-normal-UITXT77Q.woff2 +0 -0
  104. rustfava/static/fira-mono-symbols2-500-normal-VWPC2EFN.woff2 +0 -0
  105. rustfava/static/fira-sans-cyrillic-400-normal-KLQMBCA6.woff2 +0 -0
  106. rustfava/static/fira-sans-cyrillic-500-normal-NFG7UD6J.woff2 +0 -0
  107. rustfava/static/fira-sans-cyrillic-ext-400-normal-GWO44OPC.woff2 +0 -0
  108. rustfava/static/fira-sans-cyrillic-ext-500-normal-SP47E5SC.woff2 +0 -0
  109. rustfava/static/fira-sans-greek-400-normal-UMQBTLC3.woff2 +0 -0
  110. rustfava/static/fira-sans-greek-500-normal-4ZKHN4FQ.woff2 +0 -0
  111. rustfava/static/fira-sans-greek-ext-400-normal-O2DVJAJZ.woff2 +0 -0
  112. rustfava/static/fira-sans-greek-ext-500-normal-SK6GNWGO.woff2 +0 -0
  113. rustfava/static/fira-sans-latin-400-normal-OYYTPMAV.woff2 +0 -0
  114. rustfava/static/fira-sans-latin-500-normal-SMQPZW5A.woff2 +0 -0
  115. rustfava/static/fira-sans-latin-ext-400-normal-OAUP3WK5.woff2 +0 -0
  116. rustfava/static/fira-sans-latin-ext-500-normal-LY3YDR5Y.woff2 +0 -0
  117. rustfava/static/fira-sans-vietnamese-400-normal-OBMQ72MR.woff2 +0 -0
  118. rustfava/static/fira-sans-vietnamese-500-normal-Y4NZR5EU.woff2 +0 -0
  119. rustfava/static/source-code-pro-cyrillic-400-normal-TO22V6M3.woff2 +0 -0
  120. rustfava/static/source-code-pro-cyrillic-500-normal-OGBWWWYW.woff2 +0 -0
  121. rustfava/static/source-code-pro-cyrillic-ext-400-normal-XH44UCIA.woff2 +0 -0
  122. rustfava/static/source-code-pro-cyrillic-ext-500-normal-3Z6MMVM6.woff2 +0 -0
  123. rustfava/static/source-code-pro-greek-400-normal-OUXXUQWK.woff2 +0 -0
  124. rustfava/static/source-code-pro-greek-500-normal-JA2Z5UXO.woff2 +0 -0
  125. rustfava/static/source-code-pro-greek-ext-400-normal-WCDKMX7U.woff2 +0 -0
  126. rustfava/static/source-code-pro-greek-ext-500-normal-ZHVI4VKW.woff2 +0 -0
  127. rustfava/static/source-code-pro-latin-400-normal-QOGTXED5.woff2 +0 -0
  128. rustfava/static/source-code-pro-latin-500-normal-X57QEOLQ.woff2 +0 -0
  129. rustfava/static/source-code-pro-latin-ext-400-normal-QXC74NBF.woff2 +0 -0
  130. rustfava/static/source-code-pro-latin-ext-500-normal-QGOY7MTT.woff2 +0 -0
  131. rustfava/static/source-code-pro-vietnamese-400-normal-NPDCDTBA.woff2 +0 -0
  132. rustfava/static/source-code-pro-vietnamese-500-normal-M6PJKTR5.woff2 +0 -0
  133. rustfava/static/tree-sitter-beancount-MLXFQBZ5.wasm +0 -0
  134. rustfava/static/web-tree-sitter-RNOQ6E74.wasm +0 -0
  135. rustfava/template_filters.py +64 -0
  136. rustfava/templates/_journal_table.html +156 -0
  137. rustfava/templates/_layout.html +26 -0
  138. rustfava/templates/_query_table.html +88 -0
  139. rustfava/templates/beancount_file +18 -0
  140. rustfava/templates/help.html +23 -0
  141. rustfava/templates/macros/_account_macros.html +5 -0
  142. rustfava/templates/macros/_commodity_macros.html +13 -0
  143. rustfava/translations/bg/LC_MESSAGES/messages.mo +0 -0
  144. rustfava/translations/bg/LC_MESSAGES/messages.po +618 -0
  145. rustfava/translations/ca/LC_MESSAGES/messages.mo +0 -0
  146. rustfava/translations/ca/LC_MESSAGES/messages.po +618 -0
  147. rustfava/translations/de/LC_MESSAGES/messages.mo +0 -0
  148. rustfava/translations/de/LC_MESSAGES/messages.po +618 -0
  149. rustfava/translations/es/LC_MESSAGES/messages.mo +0 -0
  150. rustfava/translations/es/LC_MESSAGES/messages.po +619 -0
  151. rustfava/translations/fa/LC_MESSAGES/messages.mo +0 -0
  152. rustfava/translations/fa/LC_MESSAGES/messages.po +618 -0
  153. rustfava/translations/fr/LC_MESSAGES/messages.mo +0 -0
  154. rustfava/translations/fr/LC_MESSAGES/messages.po +618 -0
  155. rustfava/translations/ja/LC_MESSAGES/messages.mo +0 -0
  156. rustfava/translations/ja/LC_MESSAGES/messages.po +618 -0
  157. rustfava/translations/nl/LC_MESSAGES/messages.mo +0 -0
  158. rustfava/translations/nl/LC_MESSAGES/messages.po +617 -0
  159. rustfava/translations/pt/LC_MESSAGES/messages.mo +0 -0
  160. rustfava/translations/pt/LC_MESSAGES/messages.po +617 -0
  161. rustfava/translations/pt_BR/LC_MESSAGES/messages.mo +0 -0
  162. rustfava/translations/pt_BR/LC_MESSAGES/messages.po +618 -0
  163. rustfava/translations/ru/LC_MESSAGES/messages.mo +0 -0
  164. rustfava/translations/ru/LC_MESSAGES/messages.po +617 -0
  165. rustfava/translations/sk/LC_MESSAGES/messages.mo +0 -0
  166. rustfava/translations/sk/LC_MESSAGES/messages.po +623 -0
  167. rustfava/translations/sv/LC_MESSAGES/messages.mo +0 -0
  168. rustfava/translations/sv/LC_MESSAGES/messages.po +618 -0
  169. rustfava/translations/uk/LC_MESSAGES/messages.mo +0 -0
  170. rustfava/translations/uk/LC_MESSAGES/messages.po +618 -0
  171. rustfava/translations/zh/LC_MESSAGES/messages.mo +0 -0
  172. rustfava/translations/zh/LC_MESSAGES/messages.po +618 -0
  173. rustfava/translations/zh_Hant_TW/LC_MESSAGES/messages.mo +0 -0
  174. rustfava/translations/zh_Hant_TW/LC_MESSAGES/messages.po +618 -0
  175. rustfava/util/__init__.py +157 -0
  176. rustfava/util/date.py +576 -0
  177. rustfava/util/excel.py +118 -0
  178. rustfava/util/ranking.py +79 -0
  179. rustfava/util/sets.py +18 -0
  180. rustfava/util/unreachable.py +20 -0
  181. rustfava-0.1.0.dist-info/METADATA +102 -0
  182. rustfava-0.1.0.dist-info/RECORD +187 -0
  183. rustfava-0.1.0.dist-info/WHEEL +5 -0
  184. rustfava-0.1.0.dist-info/entry_points.txt +2 -0
  185. rustfava-0.1.0.dist-info/licenses/AUTHORS +11 -0
  186. rustfava-0.1.0.dist-info/licenses/LICENSE +21 -0
  187. rustfava-0.1.0.dist-info/top_level.txt +1 -0
rustfava/beans/abc.py ADDED
@@ -0,0 +1,327 @@
1
+ """Abstract base classes for Beancount types."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from abc import ABC
6
+ from abc import abstractmethod
7
+ from typing import Any
8
+ from typing import TYPE_CHECKING
9
+
10
+ # Try to import beancount types for backwards compatibility
11
+ # These are only needed to register beancount types with the ABCs
12
+ _HAS_BEANCOUNT = False
13
+ try:
14
+ from beancount.core import data as _bc_data
15
+ from beancount.core import position as _bc_position
16
+ _HAS_BEANCOUNT = True
17
+ except ImportError: # pragma: no cover
18
+ _bc_data = None # type: ignore[assignment]
19
+ _bc_position = None # type: ignore[assignment]
20
+
21
+ if TYPE_CHECKING: # pragma: no cover
22
+ import datetime
23
+ from collections.abc import Mapping
24
+ from collections.abc import Sequence
25
+ from decimal import Decimal
26
+ from typing import TypeAlias
27
+
28
+ from rustfava.beans import protocols
29
+
30
+ MetaValue: TypeAlias = (
31
+ str | int | bool | Decimal | datetime.date | protocols.Amount
32
+ )
33
+ Meta: TypeAlias = Mapping[str, MetaValue]
34
+ TagsOrLinks: TypeAlias = set[str] | frozenset[str]
35
+ Account = str
36
+
37
+
38
+ class Position(ABC):
39
+ """A Beancount position - just cost and units."""
40
+
41
+ @property
42
+ @abstractmethod
43
+ def units(self) -> protocols.Amount:
44
+ """Units of the posting."""
45
+
46
+ @property
47
+ @abstractmethod
48
+ def cost(self) -> protocols.Cost | None:
49
+ """Units of the position."""
50
+
51
+
52
+ if _HAS_BEANCOUNT:
53
+ Position.register(_bc_position.Position)
54
+
55
+
56
+ class Posting(Position):
57
+ """A Beancount posting."""
58
+
59
+ @property
60
+ @abstractmethod
61
+ def account(self) -> str:
62
+ """Account of the posting."""
63
+
64
+ @property
65
+ @abstractmethod
66
+ def units(self) -> protocols.Amount:
67
+ """Units of the posting."""
68
+
69
+ @property
70
+ @abstractmethod
71
+ def cost(self) -> protocols.Cost | None:
72
+ """Units of the posting."""
73
+
74
+ @property
75
+ @abstractmethod
76
+ def price(self) -> protocols.Amount | None:
77
+ """Price of the posting."""
78
+
79
+ @property
80
+ @abstractmethod
81
+ def meta(self) -> Meta | None:
82
+ """Metadata of the posting."""
83
+
84
+ @property
85
+ @abstractmethod
86
+ def flag(self) -> str | None:
87
+ """Flag of the posting."""
88
+
89
+
90
+ if _HAS_BEANCOUNT:
91
+ Posting.register(_bc_data.Posting)
92
+
93
+
94
+ class Directive(ABC):
95
+ """A Beancount directive."""
96
+
97
+ @property
98
+ @abstractmethod
99
+ def date(self) -> datetime.date:
100
+ """Metadata of the directive."""
101
+
102
+ @property
103
+ @abstractmethod
104
+ def meta(self) -> Meta:
105
+ """Metadata of the directive."""
106
+
107
+
108
+ class Transaction(Directive):
109
+ """A Beancount Transaction directive."""
110
+
111
+ @property
112
+ @abstractmethod
113
+ def flag(self) -> str:
114
+ """Flag of the transaction."""
115
+
116
+ @property
117
+ @abstractmethod
118
+ def payee(self) -> str:
119
+ """Payee of the transaction."""
120
+
121
+ @property
122
+ @abstractmethod
123
+ def narration(self) -> str:
124
+ """Narration of the transaction."""
125
+
126
+ @property
127
+ @abstractmethod
128
+ def postings(self) -> Sequence[Posting]:
129
+ """Payee of the transaction."""
130
+
131
+ @property
132
+ @abstractmethod
133
+ def tags(self) -> frozenset[str]:
134
+ """Entry tags."""
135
+
136
+ @property
137
+ @abstractmethod
138
+ def links(self) -> frozenset[str]:
139
+ """Entry links."""
140
+
141
+
142
+ class Balance(Directive):
143
+ """A Beancount Balance directive."""
144
+
145
+ @property
146
+ @abstractmethod
147
+ def account(self) -> str:
148
+ """Account of the directive."""
149
+
150
+ @property
151
+ @abstractmethod
152
+ def amount(self) -> protocols.Amount:
153
+ """Balance amount."""
154
+
155
+ @property
156
+ @abstractmethod
157
+ def diff_amount(self) -> protocols.Amount | None:
158
+ """Difference amount if balance failed."""
159
+
160
+
161
+ class Commodity(Directive):
162
+ """A Beancount Commodity directive."""
163
+
164
+ @property
165
+ @abstractmethod
166
+ def currency(self) -> str:
167
+ """Currency."""
168
+
169
+
170
+ class Close(Directive):
171
+ """A Beancount Close directive."""
172
+
173
+ @property
174
+ @abstractmethod
175
+ def account(self) -> str:
176
+ """Account of the directive."""
177
+
178
+
179
+ class Custom(Directive):
180
+ """A Beancount Custom directive."""
181
+
182
+ @property
183
+ @abstractmethod
184
+ def type(self) -> str:
185
+ """Directive type."""
186
+
187
+ @property
188
+ @abstractmethod
189
+ def values(self) -> Sequence[Any]:
190
+ """Custom values."""
191
+
192
+
193
+ class Document(Directive):
194
+ """A Beancount Document directive."""
195
+
196
+ @property
197
+ @abstractmethod
198
+ def filename(self) -> str:
199
+ """Filename of the document."""
200
+
201
+ @property
202
+ @abstractmethod
203
+ def account(self) -> str:
204
+ """Account of the directive."""
205
+
206
+ @property
207
+ @abstractmethod
208
+ def tags(self) -> frozenset[str]:
209
+ """Entry tags."""
210
+
211
+ @property
212
+ @abstractmethod
213
+ def links(self) -> frozenset[str]:
214
+ """Entry links."""
215
+
216
+
217
+ class Event(Directive):
218
+ """A Beancount Event directive."""
219
+
220
+ @property
221
+ @abstractmethod
222
+ def account(self) -> str:
223
+ """Account of the directive."""
224
+
225
+
226
+ class Note(Directive):
227
+ """A Beancount Note directive."""
228
+
229
+ @property
230
+ @abstractmethod
231
+ def account(self) -> str:
232
+ """Account of the directive."""
233
+
234
+ @property
235
+ @abstractmethod
236
+ def comment(self) -> str:
237
+ """Note comment."""
238
+
239
+
240
+ class Open(Directive):
241
+ """A Beancount Open directive."""
242
+
243
+ @property
244
+ @abstractmethod
245
+ def account(self) -> str:
246
+ """Account of the directive."""
247
+
248
+ @property
249
+ @abstractmethod
250
+ def currencies(self) -> Sequence[str]:
251
+ """Valid currencies for the account."""
252
+
253
+ @property
254
+ @abstractmethod
255
+ def booking(self) -> str | None:
256
+ """Booking method for the account."""
257
+
258
+
259
+ class Pad(Directive):
260
+ """A Beancount Pad directive."""
261
+
262
+ @property
263
+ @abstractmethod
264
+ def account(self) -> str:
265
+ """Account of the directive."""
266
+
267
+ @property
268
+ @abstractmethod
269
+ def source_account(self) -> str:
270
+ """Source account of the pad."""
271
+
272
+
273
+ class Price(Directive):
274
+ """A Beancount Price directive."""
275
+
276
+ @property
277
+ @abstractmethod
278
+ def currency(self) -> str:
279
+ """Currency for which this is a price."""
280
+
281
+ @property
282
+ @abstractmethod
283
+ def amount(self) -> protocols.Amount:
284
+ """Price amount."""
285
+
286
+
287
+ class Query(Directive):
288
+ """A Beancount Query directive."""
289
+
290
+ @property
291
+ @abstractmethod
292
+ def name(self) -> str:
293
+ """Name of this query."""
294
+
295
+ @property
296
+ @abstractmethod
297
+ def query_string(self) -> str:
298
+ """BQL query."""
299
+
300
+
301
+ class TxnPosting(ABC):
302
+ """A transaction and a posting."""
303
+
304
+ @property
305
+ @abstractmethod
306
+ def txn(self) -> Transaction:
307
+ """Transaction."""
308
+
309
+ @property
310
+ @abstractmethod
311
+ def posting(self) -> Posting:
312
+ """Posting."""
313
+
314
+
315
+ if _HAS_BEANCOUNT:
316
+ Balance.register(_bc_data.Balance)
317
+ Commodity.register(_bc_data.Commodity)
318
+ Close.register(_bc_data.Close)
319
+ Custom.register(_bc_data.Custom)
320
+ Document.register(_bc_data.Document)
321
+ Event.register(_bc_data.Event)
322
+ Note.register(_bc_data.Note)
323
+ Open.register(_bc_data.Open)
324
+ Pad.register(_bc_data.Pad)
325
+ Price.register(_bc_data.Price)
326
+ Transaction.register(_bc_data.Transaction)
327
+ Query.register(_bc_data.Query)
@@ -0,0 +1,79 @@
1
+ """Account name helpers."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING
6
+
7
+ from rustfava.rustledger.constants import ACCOUNT_TYPE
8
+
9
+ from rustfava.beans.abc import Custom
10
+ from rustfava.beans.abc import Pad
11
+ from rustfava.beans.abc import Transaction
12
+
13
+ if TYPE_CHECKING: # pragma: no cover
14
+ from collections.abc import Callable
15
+ from collections.abc import Sequence
16
+
17
+ from rustfava.beans.abc import Directive
18
+
19
+
20
+ def parent(account: str) -> str | None:
21
+ """Get the name of the parent of the given account."""
22
+ parts = account.rsplit(":", maxsplit=1)
23
+ return parts[0] if len(parts) == 2 else None
24
+
25
+
26
+ def root(account: str) -> str:
27
+ """Get root account of the given account."""
28
+ parts = account.split(":", maxsplit=1)
29
+ return parts[0]
30
+
31
+
32
+ def child_account_tester(account: str) -> Callable[[str], bool]:
33
+ """Get a function to check if an account is a descendant of the account."""
34
+ account_as_parent = account + ":"
35
+
36
+ def is_child_account(other: str) -> bool:
37
+ return other == account or other.startswith(account_as_parent)
38
+
39
+ return is_child_account
40
+
41
+
42
+ def account_tester(
43
+ account: str, *, with_children: bool
44
+ ) -> Callable[[str], bool]:
45
+ """Get a function to check if an account is equal to the account.
46
+
47
+ Arguments:
48
+ account: An account name to check.
49
+ with_children: Whether to include all child accounts.
50
+ """
51
+ if with_children:
52
+ return child_account_tester(account)
53
+
54
+ def is_account(other: str) -> bool:
55
+ return other == account
56
+
57
+ return is_account
58
+
59
+
60
+ def get_entry_accounts(entry: Directive) -> Sequence[str]:
61
+ """Accounts for an entry.
62
+
63
+ Args:
64
+ entry: An entry.
65
+
66
+ Returns:
67
+ A list with the entry's accounts ordered by priority: For
68
+ transactions the posting accounts are listed in reverse order.
69
+ """
70
+ if isinstance(entry, Transaction):
71
+ return list(reversed([p.account for p in entry.postings]))
72
+ if isinstance(entry, Custom):
73
+ return [val.value for val in entry.values if val.dtype == ACCOUNT_TYPE]
74
+ if isinstance(entry, Pad):
75
+ return [entry.account, entry.source_account]
76
+ account_ = getattr(entry, "account", None)
77
+ if account_ is not None:
78
+ return [account_]
79
+ return []