GeneralManager 0.19.2__py3-none-any.whl → 0.20.1__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.
Potentially problematic release.
This version of GeneralManager might be problematic. Click here for more details.
- general_manager/_types/general_manager.py +2 -0
- general_manager/api/graphql.py +90 -4
- general_manager/apps.py +89 -34
- general_manager/cache/cache_decorator.py +23 -2
- general_manager/cache/dependency_index.py +23 -7
- general_manager/interface/base_interface.py +1 -1
- general_manager/interface/database_interface.py +6 -6
- general_manager/interface/read_only_interface.py +52 -26
- general_manager/logging.py +133 -0
- general_manager/manager/general_manager.py +65 -7
- general_manager/manager/meta.py +47 -1
- general_manager/permission/base_permission.py +36 -13
- general_manager/public_api_registry.py +1 -0
- general_manager/rule/rule.py +85 -0
- general_manager/utils/public_api.py +19 -0
- {generalmanager-0.19.2.dist-info → generalmanager-0.20.1.dist-info}/METADATA +1 -1
- {generalmanager-0.19.2.dist-info → generalmanager-0.20.1.dist-info}/RECORD +20 -19
- {generalmanager-0.19.2.dist-info → generalmanager-0.20.1.dist-info}/WHEEL +0 -0
- {generalmanager-0.19.2.dist-info → generalmanager-0.20.1.dist-info}/licenses/LICENSE +0 -0
- {generalmanager-0.19.2.dist-info → generalmanager-0.20.1.dist-info}/top_level.txt +0 -0
general_manager/rule/rule.py
CHANGED
|
@@ -19,10 +19,12 @@ from general_manager.rule.handler import (
|
|
|
19
19
|
SumHandler,
|
|
20
20
|
)
|
|
21
21
|
from general_manager.manager.general_manager import GeneralManager
|
|
22
|
+
from general_manager.logging import get_logger
|
|
22
23
|
|
|
23
24
|
GeneralManagerType = TypeVar("GeneralManagerType", bound=GeneralManager)
|
|
24
25
|
|
|
25
26
|
NOTEXISTENT = object()
|
|
27
|
+
logger = get_logger("rule.engine")
|
|
26
28
|
|
|
27
29
|
|
|
28
30
|
class NonexistentAttributeError(AttributeError):
|
|
@@ -131,6 +133,13 @@ class Rule(Generic[GeneralManagerType]):
|
|
|
131
133
|
handler_cls: type[BaseRuleHandler] = import_string(path)
|
|
132
134
|
inst = handler_cls()
|
|
133
135
|
self._handlers[inst.function_name] = inst
|
|
136
|
+
logger.debug(
|
|
137
|
+
"initialised rule",
|
|
138
|
+
context={
|
|
139
|
+
"rule": self._func.__qualname__,
|
|
140
|
+
"variables": self._variables,
|
|
141
|
+
},
|
|
142
|
+
)
|
|
134
143
|
|
|
135
144
|
@property
|
|
136
145
|
def func(self) -> Callable[[GeneralManagerType], bool]:
|
|
@@ -173,12 +182,47 @@ class Rule(Generic[GeneralManagerType]):
|
|
|
173
182
|
if self._primary_param is not None:
|
|
174
183
|
self._last_args[self._primary_param] = x
|
|
175
184
|
|
|
185
|
+
logger.debug(
|
|
186
|
+
"evaluating rule",
|
|
187
|
+
context={
|
|
188
|
+
"rule": self._func.__qualname__,
|
|
189
|
+
"manager": type(x).__name__,
|
|
190
|
+
},
|
|
191
|
+
)
|
|
192
|
+
|
|
176
193
|
vals = self._extract_variable_values(x)
|
|
177
194
|
if self._ignore_if_none and any(v is None for v in vals.values()):
|
|
178
195
|
self._last_result = None
|
|
196
|
+
logger.debug(
|
|
197
|
+
"skipped rule evaluation due to missing values",
|
|
198
|
+
context={
|
|
199
|
+
"rule": self._func.__qualname__,
|
|
200
|
+
"manager": type(x).__name__,
|
|
201
|
+
"null_variables": [
|
|
202
|
+
name for name, value in vals.items() if value is None
|
|
203
|
+
],
|
|
204
|
+
},
|
|
205
|
+
)
|
|
179
206
|
return None
|
|
180
207
|
|
|
181
208
|
self._last_result = self._func(x)
|
|
209
|
+
if self._last_result:
|
|
210
|
+
logger.debug(
|
|
211
|
+
"rule evaluation passed",
|
|
212
|
+
context={
|
|
213
|
+
"rule": self._func.__qualname__,
|
|
214
|
+
"manager": type(x).__name__,
|
|
215
|
+
},
|
|
216
|
+
)
|
|
217
|
+
else:
|
|
218
|
+
logger.info(
|
|
219
|
+
"rule evaluation failed",
|
|
220
|
+
context={
|
|
221
|
+
"rule": self._func.__qualname__,
|
|
222
|
+
"manager": type(x).__name__,
|
|
223
|
+
"variables": self._variables,
|
|
224
|
+
},
|
|
225
|
+
)
|
|
182
226
|
return self._last_result
|
|
183
227
|
|
|
184
228
|
def validate_custom_error_message(self) -> None:
|
|
@@ -214,6 +258,14 @@ class Rule(Generic[GeneralManagerType]):
|
|
|
214
258
|
# Validate and substitute template placeholders
|
|
215
259
|
self.validate_custom_error_message()
|
|
216
260
|
vals = self._extract_variable_values(self._last_input)
|
|
261
|
+
manager_class = type(self._last_input).__name__
|
|
262
|
+
logger.debug(
|
|
263
|
+
"generating rule error messages",
|
|
264
|
+
context={
|
|
265
|
+
"rule": self._func.__qualname__,
|
|
266
|
+
"manager": manager_class,
|
|
267
|
+
},
|
|
268
|
+
)
|
|
217
269
|
|
|
218
270
|
if self._custom_error_message:
|
|
219
271
|
formatted = re.sub(
|
|
@@ -221,9 +273,34 @@ class Rule(Generic[GeneralManagerType]):
|
|
|
221
273
|
lambda m: str(vals.get(m.group(1), m.group(0))),
|
|
222
274
|
self._custom_error_message,
|
|
223
275
|
)
|
|
276
|
+
logger.info(
|
|
277
|
+
"rule produced custom error message",
|
|
278
|
+
context={
|
|
279
|
+
"rule": self._func.__qualname__,
|
|
280
|
+
"manager": manager_class,
|
|
281
|
+
"variables": self._variables,
|
|
282
|
+
},
|
|
283
|
+
)
|
|
224
284
|
return {v: formatted for v in self._variables}
|
|
225
285
|
|
|
226
286
|
errors = self._generate_error_messages(vals)
|
|
287
|
+
if errors:
|
|
288
|
+
logger.info(
|
|
289
|
+
"rule produced error messages",
|
|
290
|
+
context={
|
|
291
|
+
"rule": self._func.__qualname__,
|
|
292
|
+
"manager": manager_class,
|
|
293
|
+
"variables": list(errors.keys()),
|
|
294
|
+
},
|
|
295
|
+
)
|
|
296
|
+
else:
|
|
297
|
+
logger.debug(
|
|
298
|
+
"rule generated no error messages",
|
|
299
|
+
context={
|
|
300
|
+
"rule": self._func.__qualname__,
|
|
301
|
+
"manager": manager_class,
|
|
302
|
+
},
|
|
303
|
+
)
|
|
227
304
|
return errors or None
|
|
228
305
|
|
|
229
306
|
def _extract_variables(self) -> List[str]:
|
|
@@ -355,6 +432,14 @@ class Rule(Generic[GeneralManagerType]):
|
|
|
355
432
|
fn = self._get_node_name(left.func)
|
|
356
433
|
handler = self._handlers.get(fn)
|
|
357
434
|
if handler:
|
|
435
|
+
logger.debug(
|
|
436
|
+
"rule handler invoked",
|
|
437
|
+
context={
|
|
438
|
+
"rule": self._func.__qualname__,
|
|
439
|
+
"handler": handler.__class__.__name__,
|
|
440
|
+
"function": fn,
|
|
441
|
+
},
|
|
442
|
+
)
|
|
358
443
|
errors.update(
|
|
359
444
|
handler.handle(cmp, left, right, op, var_values, self)
|
|
360
445
|
)
|
|
@@ -5,6 +5,8 @@ from __future__ import annotations
|
|
|
5
5
|
from importlib import import_module
|
|
6
6
|
from typing import Any, Iterable, Mapping, MutableMapping, overload
|
|
7
7
|
|
|
8
|
+
from general_manager.logging import get_logger
|
|
9
|
+
|
|
8
10
|
|
|
9
11
|
class MissingExportError(AttributeError):
|
|
10
12
|
"""Raised when a requested export is not defined in the public API."""
|
|
@@ -24,6 +26,7 @@ class MissingExportError(AttributeError):
|
|
|
24
26
|
|
|
25
27
|
ModuleTarget = tuple[str, str]
|
|
26
28
|
ModuleMap = Mapping[str, str | ModuleTarget]
|
|
29
|
+
logger = get_logger("utils.public_api")
|
|
27
30
|
|
|
28
31
|
|
|
29
32
|
@overload
|
|
@@ -63,11 +66,27 @@ def resolve_export(
|
|
|
63
66
|
MissingExportError: If `name` is not present in `module_all`.
|
|
64
67
|
"""
|
|
65
68
|
if name not in module_all:
|
|
69
|
+
logger.warning(
|
|
70
|
+
"missing public api export",
|
|
71
|
+
context={
|
|
72
|
+
"module": module_globals["__name__"],
|
|
73
|
+
"export": name,
|
|
74
|
+
},
|
|
75
|
+
)
|
|
66
76
|
raise MissingExportError(module_globals["__name__"], name)
|
|
67
77
|
module_path, attr_name = _normalize_target(name, module_map[name])
|
|
68
78
|
module = import_module(module_path)
|
|
69
79
|
value = getattr(module, attr_name)
|
|
70
80
|
module_globals[name] = value
|
|
81
|
+
logger.debug(
|
|
82
|
+
"resolved public api export",
|
|
83
|
+
context={
|
|
84
|
+
"module": module_globals["__name__"],
|
|
85
|
+
"export": name,
|
|
86
|
+
"target_module": module_path,
|
|
87
|
+
"target_attribute": attr_name,
|
|
88
|
+
},
|
|
89
|
+
)
|
|
71
90
|
return value
|
|
72
91
|
|
|
73
92
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: GeneralManager
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.20.1
|
|
4
4
|
Summary: Modular Django-based data management framework with ORM, GraphQL, fine-grained permissions, rule validation, calculations and caching.
|
|
5
5
|
Author-email: Tim Kleindick <tkleindick@yahoo.de>
|
|
6
6
|
License: MIT License
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
general_manager/__init__.py,sha256=Xy4_fFjChIYtlBPDv7K3JEHOulq9_IFXkCc4CElS32Q,1035
|
|
2
|
-
general_manager/apps.py,sha256=
|
|
3
|
-
general_manager/
|
|
2
|
+
general_manager/apps.py,sha256=bz_A2IfgVba2b8lZC5aeQqe40IH7GaavpTEg828Ltm4,27343
|
|
3
|
+
general_manager/logging.py,sha256=bL2dEdNnxo74qRmhOCG06lbPtVCOozfF3GS133T9HH8,4250
|
|
4
|
+
general_manager/public_api_registry.py,sha256=mDpKIE3fmFAMTbQnQdLAZGc_CKNNA6p22Jrql9R6Y4w,7817
|
|
4
5
|
general_manager/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
6
|
general_manager/_types/__init__.py,sha256=RmS0Ok-1-CwWOZL_socLWksEk9MfsshL9eQx879I4mU,60
|
|
6
7
|
general_manager/_types/api.py,sha256=i5fi7O3C3frI74oqPT-tAoztDplgNDOShyvPNxhw7CY,496
|
|
7
8
|
general_manager/_types/bucket.py,sha256=DZ3GC-1iR4RiNBKydsMhp_R4GTaYMfsonwe7MCADVP4,435
|
|
8
9
|
general_manager/_types/cache.py,sha256=jMbIEXDq1pUvVxTN8hvD8rSH7QRjE3ewrMx2gEhYP3w,660
|
|
9
10
|
general_manager/_types/factory.py,sha256=cPG_td05KCWv2j6_h_vYCKETPol3k_nXkEMWCcUdNHM,1726
|
|
10
|
-
general_manager/_types/general_manager.py,sha256=
|
|
11
|
+
general_manager/_types/general_manager.py,sha256=Izs47-pOnYJqPmMF7m5DRodSISEztXKSxtBGIHgN8sA,1031
|
|
11
12
|
general_manager/_types/interface.py,sha256=JlPn3G3ompn1PRfFQfsrIJv2Pf0I3n1RL2ki5_fDX54,605
|
|
12
13
|
general_manager/_types/manager.py,sha256=rXM6NrQaPdfE9CQoRV_jhbI3SK23rvdpvyBpybVgWi8,506
|
|
13
14
|
general_manager/_types/measurement.py,sha256=Unkpf3H7TGaUKfkjmFDR7QWBU4lPp5I2A4GlK8pps-Y,443
|
|
@@ -15,7 +16,7 @@ general_manager/_types/permission.py,sha256=HJBEOIDYbkYSZkEbT4_6qRDyUk2Ek153K_Rc
|
|
|
15
16
|
general_manager/_types/rule.py,sha256=aNbx3jlVinAYQGJlmFwW8rOwTjf19F6khq5xbGTdD3U,238
|
|
16
17
|
general_manager/_types/utils.py,sha256=8VyD6EKkcRIzdVs6FANP5Ri71eT4BT4c3dTUeyjDr40,1043
|
|
17
18
|
general_manager/api/__init__.py,sha256=ChV1UPCUjW1Lci0BajmXVtE-3C-WLQTvjO058BMu1Bs,1020
|
|
18
|
-
general_manager/api/graphql.py,sha256=
|
|
19
|
+
general_manager/api/graphql.py,sha256=MqNvIWAlHpnRy4WYf6I4bjFLkL29rWWyQls2oS3b1b0,83122
|
|
19
20
|
general_manager/api/graphql_subscription_consumer.py,sha256=cA-pQNjeF4o92yc2IHtNob6z1CNhHoGxIw2Fgoj24-U,17492
|
|
20
21
|
general_manager/api/mutation.py,sha256=-zZ_zdyCQW46ihP0kC9BiNGRMPyLYVimxqOKNvP_s48,10155
|
|
21
22
|
general_manager/api/property.py,sha256=dWRTg8CECSYkIqTBwSbM8CCDEqB_-Zfbtfhxzag7qJI,5690
|
|
@@ -25,9 +26,9 @@ general_manager/bucket/calculation_bucket.py,sha256=TpZOJP42CFwsqeQWOrltouClA9Xl
|
|
|
25
26
|
general_manager/bucket/database_bucket.py,sha256=Hh__H3E-7tFaUvA5WiKbHmyafyFTzc72HgCvsTgawfU,23008
|
|
26
27
|
general_manager/bucket/group_bucket.py,sha256=nr2_3rJizOhhbtF5WPiLtZn8lnP2JQ40ehPgYKpwR1M,16369
|
|
27
28
|
general_manager/cache/__init__.py,sha256=1qLNRTHScsXDoIXKdwvHwyoi7pIb5phv7ASS1AP4Xc8,1014
|
|
28
|
-
general_manager/cache/cache_decorator.py,sha256=
|
|
29
|
+
general_manager/cache/cache_decorator.py,sha256=SpXZE89lRqI2jD4iWKbdkvGXp3BBWULvRbG9jM0e4Fs,4203
|
|
29
30
|
general_manager/cache/cache_tracker.py,sha256=AyDgc_PbxvfE3AJZilKaFCh9Dgg883pMRCXqZxWiILU,2992
|
|
30
|
-
general_manager/cache/dependency_index.py,sha256
|
|
31
|
+
general_manager/cache/dependency_index.py,sha256=-1NM13y6OIakw52bvXtWQOz55Mbq4EGq28aXvfpKxO8,26248
|
|
31
32
|
general_manager/cache/model_dependency_collector.py,sha256=T0g1-0KaEKE8xRNBJj3qsEWKIVlaDZq_MoDn1mCpXv0,2649
|
|
32
33
|
general_manager/cache/signals.py,sha256=FP_axmdeoJh9ZxjriNgz5zCEQRrVT__KvsHO4eAqdFg,2553
|
|
33
34
|
general_manager/factory/__init__.py,sha256=A-if6AxDHIejg9S2ObJXGolBfD5xfG9P1aUqT-KEGf0,943
|
|
@@ -35,22 +36,22 @@ general_manager/factory/auto_factory.py,sha256=UcX0mxqLyeccuIhjnE8uHYEJ24bMRCZjz
|
|
|
35
36
|
general_manager/factory/factories.py,sha256=yVqLSFWuFFTEE9mQGMA9uTRETIruKv0vj6DrUlRoasU,12092
|
|
36
37
|
general_manager/factory/factory_methods.py,sha256=ZwUQwuLbs1NgVxkjK6idzmWAZY3-9F8wah05bSf14bQ,8407
|
|
37
38
|
general_manager/interface/__init__.py,sha256=L0IQUHOJehJbX6hzX9nomMhT8f1tqrPtLDgINIpe5-w,1010
|
|
38
|
-
general_manager/interface/base_interface.py,sha256=
|
|
39
|
+
general_manager/interface/base_interface.py,sha256=TREetLDX_BAtqrnsvZ9qHUkxl86JCCPzI_eky2bTLwg,16194
|
|
39
40
|
general_manager/interface/calculation_interface.py,sha256=dsu2pjFgaOv-Kif5YbrsbEvH8Q1n_XfUabPv3CusbtE,5965
|
|
40
41
|
general_manager/interface/database_based_interface.py,sha256=1L0Q22nEWiO_i--3AtuseAytiXMEkIUF4HL5rTB0s0M,25623
|
|
41
|
-
general_manager/interface/database_interface.py,sha256=
|
|
42
|
+
general_manager/interface/database_interface.py,sha256=ALFQKl7jXNQMHegmUkNKyDGJruMmAmprDiiyYsfZZ_A,11825
|
|
42
43
|
general_manager/interface/models.py,sha256=MWCgr-Qzauu7jq-15_iEdI0C9B99MsRONV9jUcjkkMU,3699
|
|
43
|
-
general_manager/interface/read_only_interface.py,sha256=
|
|
44
|
+
general_manager/interface/read_only_interface.py,sha256=w1XrTeOyf3T7lDfC7ponAMhfNw5LTM46lTOEsocE244,16000
|
|
44
45
|
general_manager/manager/__init__.py,sha256=Dbka86jtcS2NIxKXA0mohqnLZwLb6NDRX-HeD1_R6UQ,933
|
|
45
|
-
general_manager/manager/general_manager.py,sha256=
|
|
46
|
+
general_manager/manager/general_manager.py,sha256=GperYpkoTg_CZlwYBsqGhnaMFENR6jyxanKYdHsvZjg,12083
|
|
46
47
|
general_manager/manager/group_manager.py,sha256=EhiW2cEnr7J4Ft-FBfuW4hCT5mYg_RCD_-mYF4an9dw,7320
|
|
47
48
|
general_manager/manager/input.py,sha256=e2M7TSZgNwQz0P1pD_rOpm6-wDUUTjga6kb3nJBR9js,3032
|
|
48
|
-
general_manager/manager/meta.py,sha256=
|
|
49
|
+
general_manager/manager/meta.py,sha256=kkuwKJlbahUMAkh3Gqefbzdm0rnwhD-jbeR2XhveLLs,11391
|
|
49
50
|
general_manager/measurement/__init__.py,sha256=38-6kTERbw7EeOQAw3eZ9DDEu6hwwqkGJIfJy1D5fx0,993
|
|
50
51
|
general_manager/measurement/measurement.py,sha256=ArEnntLu3ffHID71uFbXwiB5e5tpsBT2_TbBPJfCWJI,26070
|
|
51
52
|
general_manager/measurement/measurement_field.py,sha256=zQbyLZT7E9Lx4f3u_wQ-rEoLPqH0FWhfWyOd1BaW--M,13950
|
|
52
53
|
general_manager/permission/__init__.py,sha256=s4Ka11uYBrymM5O-n5kIxOjwUprZ394jTuzGf5prO_8,981
|
|
53
|
-
general_manager/permission/base_permission.py,sha256=
|
|
54
|
+
general_manager/permission/base_permission.py,sha256=IKi5n8t1sKUP_F2eZnzTC8lg7HI8OVo5p1jxCBpyCgw,11961
|
|
54
55
|
general_manager/permission/file_based_permission.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
55
56
|
general_manager/permission/manager_based_permission.py,sha256=OdDGKwutkHTT13bhSeGGycd3xr7wGhuRXsYym3Z9j2A,10613
|
|
56
57
|
general_manager/permission/mutation_permission.py,sha256=5JV6pluIFPGzJPQ_pr-44zwFg_TgzNwDTHcdpwHettU,4606
|
|
@@ -59,7 +60,7 @@ general_manager/permission/permission_data_manager.py,sha256=vNWbPrcw1NUZ-oTRjc3
|
|
|
59
60
|
general_manager/permission/utils.py,sha256=yojrcF1kD6KjKugrGyiaf8XOyS_tUA4yB5_RideKJeg,2905
|
|
60
61
|
general_manager/rule/__init__.py,sha256=dFQLJNr0qpkpuzuBbMY-74jz_Y033YyB9X_OfeJYhSs,1026
|
|
61
62
|
general_manager/rule/handler.py,sha256=qSBXmXvl7fRgjxUo4wyUOzdZm14a8Umd2Jec4zPXJQc,16309
|
|
62
|
-
general_manager/rule/rule.py,sha256=
|
|
63
|
+
general_manager/rule/rule.py,sha256=41VXFTSWkBEOj8045vZTezm38VEGimjrk22J4YRl144,22691
|
|
63
64
|
general_manager/utils/__init__.py,sha256=a72hkiV4_c3wQN-NK-q3Dw25irbzoTTfyKm173WtjwQ,1003
|
|
64
65
|
general_manager/utils/args_to_kwargs.py,sha256=uvc0YkfeKvny4SGWNVqFioIxajBHrSkzoqrzonu7jeU,2128
|
|
65
66
|
general_manager/utils/filter_parser.py,sha256=qVkCM5M-gtVrQ3kbHApHjChwSm6Soz60hj41jJdvMvE,5676
|
|
@@ -68,10 +69,10 @@ general_manager/utils/json_encoder.py,sha256=0jyjBsZNYGl54hQRkig_5_a20bIN2mV0jlh
|
|
|
68
69
|
general_manager/utils/make_cache_key.py,sha256=Uvf7duph8FkqmWWuc4vVdB5Dztur490hPGIFtlkVuT4,1253
|
|
69
70
|
general_manager/utils/none_to_zero.py,sha256=Z2KVXBKCz02V2ZBs-7tIs_32n7YDxiXyoodW8JbXTDY,667
|
|
70
71
|
general_manager/utils/path_mapping.py,sha256=f3sd3OFh9aJgyF-ayqr22mHnCo-uoIXqio5DRQmziGM,9931
|
|
71
|
-
general_manager/utils/public_api.py,sha256=
|
|
72
|
+
general_manager/utils/public_api.py,sha256=bas4SKchJUg2dI2SLRQwkF_CoXJKKwkzQx_JOjMJ2VY,3272
|
|
72
73
|
general_manager/utils/testing.py,sha256=_V4Y5SXvu-ocoq-AntPFPd140igclUJUT2xVXxhRrSs,14954
|
|
73
|
-
generalmanager-0.
|
|
74
|
-
generalmanager-0.
|
|
75
|
-
generalmanager-0.
|
|
76
|
-
generalmanager-0.
|
|
77
|
-
generalmanager-0.
|
|
74
|
+
generalmanager-0.20.1.dist-info/licenses/LICENSE,sha256=OcRwUgM4iiESN1oNELgyuwuah39XX-EPZiPDDHndNVI,1070
|
|
75
|
+
generalmanager-0.20.1.dist-info/METADATA,sha256=aZ08I7nii3gn6zicyZnhavmaZlbQHZIlb8PEaYuT5is,8266
|
|
76
|
+
generalmanager-0.20.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
77
|
+
generalmanager-0.20.1.dist-info/top_level.txt,sha256=sTDtExP9ga-YP3h3h42yivUY-A2Q23C2nw6LNKOho4I,16
|
|
78
|
+
generalmanager-0.20.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|