-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
pass through attributes when creating metrics, dimensions, identifiers #18
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -380,7 +380,9 @@ def __init__(self, name, unit_type=None, via=None, external=False, private=False | |
if self.ALLOW_ALL_ATTRIBUTES or attr in self.EXTRA_ATTRIBUTES: | ||
setattr(self, attr, value) | ||
else: | ||
raise KeyError("No such attribute {}.".format(attr)) | ||
raise AttributeError( | ||
"Cannot initialize {}<{}> with attribute '{}'.".format(self.__class__.__name__, self.name, attr) | ||
) | ||
|
||
def __getattr__(self, name): | ||
if name.startswith('_'): | ||
|
@@ -446,10 +448,7 @@ def transforms(self): | |
@transforms.setter | ||
def transforms(self, transforms): | ||
# TODO: Check structure of transforms dict | ||
if not transforms: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nonsubstantive, but I do like oneliners There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Aye... I like this better too. I think I left it uncollapsed because I was expecting to do more logic than would be elegant in a one-liner. For now, this works well. |
||
self._transforms = {} | ||
else: | ||
self._transforms = transforms | ||
self._transforms = {} if not transforms else transforms | ||
|
||
@property | ||
def as_external(self): | ||
|
@@ -692,8 +691,8 @@ def desc(self): | |
|
||
class _Dimension(_ProvidedFeature): | ||
|
||
def __init__(self, name, expr=None, default=None, desc=None, shared=False, partition=False, requires_constraint=False, provider=None): | ||
_ProvidedFeature.__init__(self, name, expr=expr, default=default, desc=desc, shared=shared, provider=provider) | ||
def __init__(self, name, expr=None, default=None, desc=None, shared=False, partition=False, requires_constraint=False, provider=None, **attrs): | ||
_ProvidedFeature.__init__(self, name, expr=expr, default=default, desc=desc, shared=shared, provider=provider, **attrs) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. as discussed, perhaps we should be more explicit with which attrs get sent through There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
if not shared and partition: | ||
raise ValueError("Partitions must be shared.") | ||
self.partition = partition | ||
|
@@ -777,20 +776,25 @@ def matches(self, unit_type, reverse=False): | |
class _Measure(_ProvidedFeature): | ||
|
||
def __init__(self, name, expr=None, default=None, desc=None, | ||
distribution='normal', shared=False, provider=None): | ||
_ProvidedFeature.__init__(self, name, expr=expr, default=default, desc=desc, shared=shared, provider=provider) | ||
distribution='normal', shared=False, provider=None, **attrs): | ||
_ProvidedFeature.__init__( | ||
self, name, expr=expr, default=default, desc=desc, shared=shared, provider=provider, | ||
**attrs | ||
) | ||
self.distribution = distribution | ||
|
||
def transforms_for_unit_type(self, unit_type, stats_registry=None): | ||
transforms = { | ||
transforms = { # defaults | ||
'pre_agg': None, | ||
'agg': 'sum', | ||
'post_agg': None, | ||
'pre_rebase_agg': None, | ||
'rebase_agg': 'sum', | ||
'post_rebase_agg': None | ||
} | ||
|
||
if isinstance(self.transforms, dict): | ||
transforms.update(self.transforms.get('_default', {})) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. default transforms for all unit types? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I remain unconvinced, I'm afraid, that this is a good idea, as it leads to confusing (and usually wrong) behaviour :/. Suppose we chose |
||
transforms.update(self.transforms.get(unit_type, {})) | ||
|
||
backend_aggs = stats_registry.aggregations.for_provider(self.provider) | ||
|
@@ -828,14 +832,15 @@ def get_fields(self, unit_type=None, stats=True, rebase_agg=False, stats_registr | |
""" | ||
assert stats_registry is not None | ||
assert not (rebase_agg and stats) | ||
|
||
if for_pandas: | ||
from mensor.backends.pandas import PandasMeasureProvider | ||
provider = PandasMeasureProvider | ||
else: | ||
provider = self.provider | ||
|
||
transforms = self.transforms_for_unit_type(unit_type, stats_registry=stats_registry) | ||
if stats: | ||
transforms = self.transforms_for_unit_type(unit_type, stats_registry=stats_registry) | ||
return OrderedDict([ | ||
( | ||
( | ||
|
@@ -850,18 +855,17 @@ def get_fields(self, unit_type=None, stats=True, rebase_agg=False, stats_registr | |
) | ||
for field_name, agg_method in stats_registry.distribution_for_provider(self.distribution, provider).items() | ||
]) | ||
else: | ||
transforms = self.transforms_for_unit_type(unit_type, stats_registry=stats_registry) | ||
return OrderedDict([ | ||
( | ||
'{fieldname}|raw'.format(fieldname=self.fieldname(role=None, unit_type=unit_type if not rebase_agg else None)), | ||
{ | ||
'agg': transforms['rebase_agg'] if rebase_agg else transforms['agg'], | ||
'pre_agg': transforms['pre_rebase_agg'] if rebase_agg else transforms['pre_agg'], | ||
'post_agg': transforms['post_rebase_agg'] if rebase_agg else transforms['post_agg'], | ||
} | ||
) | ||
]) | ||
|
||
return OrderedDict([ | ||
( | ||
'{fieldname}|raw'.format(fieldname=self.fieldname(role=None, unit_type=unit_type if not rebase_agg else None)), | ||
{ | ||
'agg': transforms['rebase_agg'] if rebase_agg else transforms['agg'], | ||
'pre_agg': transforms['pre_rebase_agg'] if rebase_agg else transforms['pre_agg'], | ||
'post_agg': transforms['post_rebase_agg'] if rebase_agg else transforms['post_agg'], | ||
} | ||
) | ||
]) | ||
|
||
@classmethod | ||
def get_all_fields(self, measures, unit_type=None, stats=True, rebase_agg=False, stats_registry=None, for_pandas=False): | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perhaps rename to "any"?