GeneralManager 0.10.5__tar.gz → 0.10.6__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.
- {generalmanager-0.10.5 → generalmanager-0.10.6}/GeneralManager.egg-info/PKG-INFO +1 -1
- {generalmanager-0.10.5 → generalmanager-0.10.6}/PKG-INFO +1 -1
- {generalmanager-0.10.5 → generalmanager-0.10.6}/pyproject.toml +1 -1
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/api/graphql.py +80 -40
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/measurement/measurement.py +8 -8
- {generalmanager-0.10.5 → generalmanager-0.10.6}/GeneralManager.egg-info/SOURCES.txt +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/GeneralManager.egg-info/dependency_links.txt +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/GeneralManager.egg-info/requires.txt +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/GeneralManager.egg-info/top_level.txt +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/LICENSE +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/README.md +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/setup.cfg +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/__init__.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/api/mutation.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/api/property.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/apps.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/bucket/baseBucket.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/bucket/calculationBucket.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/bucket/databaseBucket.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/bucket/groupBucket.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/cache/cacheDecorator.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/cache/cacheTracker.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/cache/dependencyIndex.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/cache/modelDependencyCollector.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/cache/signals.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/factory/__init__.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/factory/autoFactory.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/factory/factories.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/factory/factoryMethods.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/interface/__init__.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/interface/baseInterface.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/interface/calculationInterface.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/interface/databaseBasedInterface.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/interface/databaseInterface.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/interface/models.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/interface/readOnlyInterface.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/manager/__init__.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/manager/generalManager.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/manager/groupManager.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/manager/input.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/manager/meta.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/measurement/__init__.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/measurement/measurementField.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/permission/__init__.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/permission/basePermission.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/permission/fileBasedPermission.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/permission/managerBasedPermission.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/permission/permissionChecks.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/permission/permissionDataManager.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/rule/__init__.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/rule/handler.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/rule/rule.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/utils/__init__.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/utils/argsToKwargs.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/utils/filterParser.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/utils/formatString.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/utils/jsonEncoder.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/utils/makeCacheKey.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/utils/noneToZero.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/utils/pathMapping.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/utils/testing.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/tests/test_settings.py +0 -0
- {generalmanager-0.10.5 → generalmanager-0.10.6}/tests/test_urls.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: GeneralManager
|
3
|
-
Version: 0.10.
|
3
|
+
Version: 0.10.6
|
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-Expression: MIT
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: GeneralManager
|
3
|
-
Version: 0.10.
|
3
|
+
Version: 0.10.6
|
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-Expression: MIT
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "GeneralManager"
|
7
|
-
version = "0.10.
|
7
|
+
version = "0.10.6"
|
8
8
|
description = "Modular Django-based data management framework with ORM, GraphQL, fine-grained permissions, rule validation, calculations and caching."
|
9
9
|
readme = "README.md"
|
10
10
|
authors = [{ name = "Tim Kleindick", email = "tkleindick@yahoo.de" }]
|
@@ -102,9 +102,9 @@ class GraphQL:
|
|
102
102
|
@classmethod
|
103
103
|
def createGraphqlInterface(cls, generalManagerClass: GeneralManagerMeta) -> None:
|
104
104
|
"""
|
105
|
-
Generates and registers a GraphQL ObjectType for
|
105
|
+
Generates and registers a GraphQL ObjectType for the specified GeneralManager class.
|
106
106
|
|
107
|
-
This method maps interface and GraphQLProperty
|
107
|
+
This method maps interface attributes and GraphQLProperty fields to Graphene fields, creates appropriate resolvers, registers the resulting type in the internal registry, and adds related query fields to the schema.
|
108
108
|
"""
|
109
109
|
interface_cls: InterfaceBase | None = getattr(
|
110
110
|
generalManagerClass, "Interface", None
|
@@ -143,10 +143,12 @@ class GraphQL:
|
|
143
143
|
@staticmethod
|
144
144
|
def _sortByOptions(
|
145
145
|
generalManagerClass: GeneralManagerMeta,
|
146
|
-
) -> type[graphene.Enum]:
|
146
|
+
) -> type[graphene.Enum] | None:
|
147
147
|
"""
|
148
|
-
|
149
|
-
|
148
|
+
Creates a Graphene Enum type representing sortable fields for a given GeneralManager class.
|
149
|
+
|
150
|
+
Returns:
|
151
|
+
A Graphene Enum type with options for each sortable attribute, or None if no sortable fields exist.
|
150
152
|
"""
|
151
153
|
sort_options = []
|
152
154
|
for (
|
@@ -162,6 +164,9 @@ class GraphQL:
|
|
162
164
|
else:
|
163
165
|
sort_options.append(field_name)
|
164
166
|
|
167
|
+
if not sort_options:
|
168
|
+
return None
|
169
|
+
|
165
170
|
return type(
|
166
171
|
f"{generalManagerClass.__name__}SortByOptions",
|
167
172
|
(graphene.Enum,),
|
@@ -169,9 +174,13 @@ class GraphQL:
|
|
169
174
|
)
|
170
175
|
|
171
176
|
@staticmethod
|
172
|
-
def _createFilterOptions(
|
177
|
+
def _createFilterOptions(
|
178
|
+
field_name: str, field_type: GeneralManagerMeta
|
179
|
+
) -> type[graphene.InputObjectType] | None:
|
173
180
|
"""
|
174
|
-
|
181
|
+
Dynamically generates a Graphene InputObjectType for filtering fields of a GeneralManager subclass.
|
182
|
+
|
183
|
+
Creates filter fields for each attribute based on its type, supporting numeric and string filter options, as well as specialized handling for Measurement attributes. Returns the generated InputObjectType or None if no filter fields are applicable.
|
175
184
|
"""
|
176
185
|
number_options = ["exact", "gt", "gte", "lt", "lte"]
|
177
186
|
string_options = [
|
@@ -212,6 +221,8 @@ class GraphQL:
|
|
212
221
|
filter_fields[f"{attr_name}__{option}"] = (
|
213
222
|
GraphQL._mapFieldToGrapheneRead(attr_type, attr_name)
|
214
223
|
)
|
224
|
+
if not filter_fields:
|
225
|
+
return None
|
215
226
|
|
216
227
|
filter_class = type(
|
217
228
|
graphene_filter_type_name,
|
@@ -223,21 +234,32 @@ class GraphQL:
|
|
223
234
|
|
224
235
|
@staticmethod
|
225
236
|
def _mapFieldToGrapheneRead(field_type: type, field_name: str) -> Any:
|
237
|
+
"""
|
238
|
+
Maps a Python field type and name to the appropriate Graphene field for GraphQL schema generation.
|
239
|
+
|
240
|
+
For `Measurement` types, returns a field with an optional `target_unit` argument. For `GeneralManager` subclasses, returns either a list field (with optional filtering, exclusion, sorting, pagination, and grouping arguments if available) or a single field, depending on the field name. For other types, returns the corresponding Graphene scalar field.
|
241
|
+
"""
|
226
242
|
if issubclass(field_type, Measurement):
|
227
243
|
return graphene.Field(MeasurementType, target_unit=graphene.String())
|
228
244
|
elif issubclass(field_type, GeneralManager):
|
229
245
|
if field_name.endswith("_list"):
|
246
|
+
attributes = {
|
247
|
+
"reverse": graphene.Boolean(),
|
248
|
+
"page": graphene.Int(),
|
249
|
+
"page_size": graphene.Int(),
|
250
|
+
"group_by": graphene.List(graphene.String),
|
251
|
+
}
|
230
252
|
filter_options = GraphQL._createFilterOptions(field_name, field_type)
|
253
|
+
if filter_options:
|
254
|
+
attributes["filter"] = filter_options()
|
255
|
+
attributes["exclude"] = filter_options()
|
256
|
+
|
231
257
|
sort_by_options = GraphQL._sortByOptions(field_type)
|
258
|
+
if sort_by_options:
|
259
|
+
attributes["sort_by"] = sort_by_options()
|
232
260
|
return graphene.List(
|
233
261
|
lambda: GraphQL.graphql_type_registry[field_type.__name__],
|
234
|
-
|
235
|
-
exclude=filter_options(),
|
236
|
-
sort_by=sort_by_options(),
|
237
|
-
reverse=graphene.Boolean(),
|
238
|
-
page=graphene.Int(),
|
239
|
-
page_size=graphene.Int(),
|
240
|
-
group_by=graphene.List(graphene.String),
|
262
|
+
**attributes,
|
241
263
|
)
|
242
264
|
return graphene.Field(
|
243
265
|
lambda: GraphQL.graphql_type_registry[field_type.__name__]
|
@@ -348,7 +370,14 @@ class GraphQL:
|
|
348
370
|
base_getter: Callable[[Any], Any], fallback_manager_class: type[GeneralManager]
|
349
371
|
) -> Callable[..., Any]:
|
350
372
|
"""
|
351
|
-
|
373
|
+
Create a resolver function for GraphQL list fields that retrieves and returns a queryset with permission filters, query filters, sorting, pagination, and optional grouping applied.
|
374
|
+
|
375
|
+
Parameters:
|
376
|
+
base_getter: Function to obtain the base queryset from the parent instance.
|
377
|
+
fallback_manager_class: Manager class to use if the queryset does not specify one.
|
378
|
+
|
379
|
+
Returns:
|
380
|
+
A resolver function that processes list queries with filtering, sorting, pagination, and grouping.
|
352
381
|
"""
|
353
382
|
|
354
383
|
def resolver(
|
@@ -363,7 +392,7 @@ class GraphQL:
|
|
363
392
|
group_by: list[str] | None = None,
|
364
393
|
) -> Any:
|
365
394
|
"""
|
366
|
-
Resolves a list field by returning a queryset
|
395
|
+
Resolves a list field by returning a queryset with permission filters, query filters, sorting, pagination, and optional grouping applied.
|
367
396
|
|
368
397
|
Parameters:
|
369
398
|
filter: Filter criteria as a dictionary or JSON string.
|
@@ -375,7 +404,7 @@ class GraphQL:
|
|
375
404
|
group_by: List of field names to group results by.
|
376
405
|
|
377
406
|
Returns:
|
378
|
-
|
407
|
+
The resulting queryset after applying permissions, filters, sorting, pagination, and grouping.
|
379
408
|
"""
|
380
409
|
base_queryset = base_getter(self)
|
381
410
|
# use _manager_class from the attribute if available, otherwise fallback
|
@@ -451,9 +480,9 @@ class GraphQL:
|
|
451
480
|
cls, graphene_type: type, generalManagerClass: GeneralManagerMeta
|
452
481
|
) -> None:
|
453
482
|
"""
|
454
|
-
|
483
|
+
Add list and single-item query fields for a GeneralManager subclass to the GraphQL schema.
|
455
484
|
|
456
|
-
Registers a list query
|
485
|
+
Registers a list query field with optional filtering, exclusion, sorting, pagination, and grouping arguments, as well as a single-item query field using identification fields from the manager's interface. Attaches the corresponding resolvers for both queries to the schema.
|
457
486
|
"""
|
458
487
|
if not issubclass(generalManagerClass, GeneralManager):
|
459
488
|
raise TypeError(
|
@@ -465,19 +494,24 @@ class GraphQL:
|
|
465
494
|
|
466
495
|
# resolver and field for the list query
|
467
496
|
list_field_name = f"{generalManagerClass.__name__.lower()}_list"
|
497
|
+
attributes = {
|
498
|
+
"reverse": graphene.Boolean(),
|
499
|
+
"page": graphene.Int(),
|
500
|
+
"page_size": graphene.Int(),
|
501
|
+
"group_by": graphene.List(graphene.String),
|
502
|
+
}
|
468
503
|
filter_options = cls._createFilterOptions(
|
469
504
|
generalManagerClass.__name__.lower(), generalManagerClass
|
470
505
|
)
|
506
|
+
if filter_options:
|
507
|
+
attributes["filter"] = filter_options()
|
508
|
+
attributes["exclude"] = filter_options()
|
471
509
|
sort_by_options = cls._sortByOptions(generalManagerClass)
|
510
|
+
if sort_by_options:
|
511
|
+
attributes["sort_by"] = sort_by_options()
|
472
512
|
list_field = graphene.List(
|
473
513
|
graphene_type,
|
474
|
-
|
475
|
-
exclude=filter_options(),
|
476
|
-
sort_by=sort_by_options(),
|
477
|
-
reverse=graphene.Boolean(),
|
478
|
-
page=graphene.Int(),
|
479
|
-
page_size=graphene.Int(),
|
480
|
-
group_by=graphene.List(graphene.String),
|
514
|
+
**attributes,
|
481
515
|
)
|
482
516
|
|
483
517
|
list_resolver = cls._createListResolver(
|
@@ -519,7 +553,7 @@ class GraphQL:
|
|
519
553
|
"""
|
520
554
|
Generate a dictionary of Graphene input fields for mutations based on the attributes of the provided interface class.
|
521
555
|
|
522
|
-
Skips system-managed
|
556
|
+
Skips system-managed and derived attributes. For attributes referencing `GeneralManager` subclasses, uses an ID or list of IDs as appropriate. Other types are mapped to their corresponding Graphene scalar types. Each field is annotated with an `editable` attribute. An optional `history_comment` field, also marked as editable, is always included.
|
523
557
|
|
524
558
|
Returns:
|
525
559
|
dict[str, Any]: Mapping of attribute names to Graphene input fields for mutation arguments.
|
@@ -572,12 +606,12 @@ class GraphQL:
|
|
572
606
|
default_return_values: dict[str, Any],
|
573
607
|
) -> type[graphene.Mutation] | None:
|
574
608
|
"""
|
575
|
-
Dynamically generates a Graphene mutation class for creating an instance of
|
609
|
+
Dynamically generates a Graphene mutation class for creating an instance of a specified GeneralManager subclass.
|
576
610
|
|
577
|
-
The generated mutation class
|
611
|
+
The generated mutation class filters out fields with `NOT_PROVIDED` values, calls the manager's `create` method with the provided arguments and the current user's ID, and returns a dictionary containing a success flag, any errors, and the created instance. Returns None if the manager class does not define an interface.
|
578
612
|
|
579
613
|
Returns:
|
580
|
-
The generated Graphene mutation class, or None if
|
614
|
+
The generated Graphene mutation class, or None if the manager class does not define an interface.
|
581
615
|
"""
|
582
616
|
interface_cls: InterfaceBase | None = getattr(
|
583
617
|
generalManagerClass, "Interface", None
|
@@ -591,9 +625,9 @@ class GraphQL:
|
|
591
625
|
**kwargs: Any,
|
592
626
|
) -> dict:
|
593
627
|
"""
|
594
|
-
|
628
|
+
Create a new instance of the manager class using the provided arguments.
|
595
629
|
|
596
|
-
Filters out fields with values
|
630
|
+
Filters out any fields with values set to `NOT_PROVIDED` before invoking the creation method. Returns a dictionary with a success flag, a list of errors if creation fails, and the created instance keyed by the manager class name.
|
597
631
|
"""
|
598
632
|
try:
|
599
633
|
kwargs = {
|
@@ -644,9 +678,9 @@ class GraphQL:
|
|
644
678
|
default_return_values: dict[str, Any],
|
645
679
|
) -> type[graphene.Mutation] | None:
|
646
680
|
"""
|
647
|
-
Generates a GraphQL mutation class for updating
|
681
|
+
Generates a GraphQL mutation class for updating an instance of a GeneralManager subclass.
|
648
682
|
|
649
|
-
The generated mutation accepts editable fields as arguments,
|
683
|
+
The generated mutation accepts editable fields as arguments, calls the manager's `update` method with the provided values and the current user's ID, and returns a dictionary containing the operation's success status, any error messages, and the updated instance. Returns None if the manager class does not define an `Interface`.
|
650
684
|
|
651
685
|
Returns:
|
652
686
|
The generated Graphene mutation class, or None if no interface is defined.
|
@@ -663,14 +697,14 @@ class GraphQL:
|
|
663
697
|
**kwargs: Any,
|
664
698
|
) -> dict:
|
665
699
|
"""
|
666
|
-
|
700
|
+
Updates a GeneralManager instance with the provided fields.
|
667
701
|
|
668
702
|
Parameters:
|
669
703
|
info (GraphQLResolveInfo): The GraphQL resolver context, typically containing user and request information.
|
670
704
|
**kwargs: Fields to update, including the required 'id' of the instance.
|
671
705
|
|
672
706
|
Returns:
|
673
|
-
dict:
|
707
|
+
dict: A dictionary with keys 'success' (bool), 'errors' (list of str), and the updated instance keyed by its class name.
|
674
708
|
"""
|
675
709
|
try:
|
676
710
|
manager_id = kwargs.pop("id", None)
|
@@ -716,9 +750,12 @@ class GraphQL:
|
|
716
750
|
default_return_values: dict[str, Any],
|
717
751
|
) -> type[graphene.Mutation] | None:
|
718
752
|
"""
|
719
|
-
Generates a GraphQL mutation class for
|
753
|
+
Generates a GraphQL mutation class for deactivating (soft-deleting) an instance of a GeneralManager subclass.
|
754
|
+
|
755
|
+
The generated mutation accepts input fields defined by the manager's interface, deactivates the specified instance using its ID, and returns a dictionary containing the operation's success status, any error messages, and the deactivated instance keyed by the class name.
|
720
756
|
|
721
|
-
|
757
|
+
Returns:
|
758
|
+
The generated Graphene mutation class, or None if the manager class does not define an interface.
|
722
759
|
"""
|
723
760
|
interface_cls: InterfaceBase | None = getattr(
|
724
761
|
generalManagerClass, "Interface", None
|
@@ -732,10 +769,13 @@ class GraphQL:
|
|
732
769
|
**kwargs: Any,
|
733
770
|
) -> dict:
|
734
771
|
"""
|
735
|
-
Deactivates an instance of the specified GeneralManager class and returns the result.
|
772
|
+
Deactivates an instance of the specified GeneralManager class and returns the operation result.
|
736
773
|
|
737
774
|
Returns:
|
738
|
-
dict:
|
775
|
+
dict: A dictionary with keys:
|
776
|
+
- "success": Boolean indicating if the operation was successful.
|
777
|
+
- "errors": List of error messages, empty if successful.
|
778
|
+
- <ClassName>: The deactivated instance, keyed by the class name.
|
739
779
|
"""
|
740
780
|
try:
|
741
781
|
manager_id = kwargs.pop("id", None)
|
{generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/measurement/measurement.py
RENAMED
@@ -228,18 +228,18 @@ class Measurement:
|
|
228
228
|
|
229
229
|
def __mul__(self, other: Any) -> Measurement:
|
230
230
|
"""
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
231
|
+
Multiply this measurement by another measurement or a numeric value.
|
232
|
+
|
233
|
+
Multiplying two currency measurements is not allowed. When multiplying by another measurement, the resulting measurement combines their units. When multiplying by a numeric value, only the magnitude is scaled.
|
234
|
+
|
235
235
|
Returns:
|
236
|
-
Measurement:
|
237
|
-
|
236
|
+
Measurement: The result of the multiplication.
|
237
|
+
|
238
238
|
Raises:
|
239
|
-
TypeError: If
|
239
|
+
TypeError: If both operands are currency measurements, or if the operand is not a Measurement or numeric value.
|
240
240
|
"""
|
241
241
|
if isinstance(other, Measurement):
|
242
|
-
if self.is_currency()
|
242
|
+
if self.is_currency() and other.is_currency():
|
243
243
|
raise TypeError(
|
244
244
|
"Multiplication between two currency amounts is not allowed."
|
245
245
|
)
|
File without changes
|
{generalmanager-0.10.5 → generalmanager-0.10.6}/GeneralManager.egg-info/dependency_links.txt
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/bucket/calculationBucket.py
RENAMED
File without changes
|
{generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/bucket/databaseBucket.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/cache/dependencyIndex.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/factory/factoryMethods.py
RENAMED
File without changes
|
File without changes
|
{generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/interface/baseInterface.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/interface/databaseInterface.py
RENAMED
File without changes
|
File without changes
|
{generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/interface/readOnlyInterface.py
RENAMED
File without changes
|
File without changes
|
{generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/manager/generalManager.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/measurement/measurementField.py
RENAMED
File without changes
|
File without changes
|
{generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/permission/basePermission.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{generalmanager-0.10.5 → generalmanager-0.10.6}/src/general_manager/permission/permissionChecks.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|