Skip to content
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

parser: ensure samples are of type Sample #358

Merged
merged 1 commit into from
Jan 7, 2019

Conversation

crepererum
Copy link
Contributor

No description provided.

@brian-brazil
Copy link
Contributor

Why does assertEqual not work?

@crepererum
Copy link
Contributor Author

@brian-brazil because Sample is a subtype of tuple and therefore the equality treats them as equal. But named attributes (like sample.value) do not work for tuples so I think it's important to be consistent here.

@brian-brazil
Copy link
Contributor

If you want to test for the named attributes, then I suggest testing for them as that's more in line with Python's duck typing.

@crepererum
Copy link
Contributor Author

I have 3 arguments against "testing the ducktype" here:

Maintainability

Well, then we have to keep the tests and the Sample definition in-sync. Possible, but not nice.

Robustness / Clean Code

Not sure how sane that would be. As a user, I basically expect:

  • a tuple
  • named attributes

which is exactly the definition of Sample. Sure, somebody could in theory come up w/ another type that fulfills this, but since we're testing our own library here. I would say we follow ducktyping in the following way:

Be conservative in what you do, be liberal in what you accept from others (often reworded as "Be conservative in what you send, be liberal in what you accept").

(Robustness principle)

Type Zoo

We have a single library here and I think this single library should use a single type for that dedicated purpose (= representing samples). This partly contradicts ducktyping (in the provider/return part) but is nice for contributors to understand the library and for users to grasp the concepts. Also, it would make type annotations way easier in the future (in case we want to walk that path). Notice that consistent types make downstream libraries also simpler (since they can use type annotations) and enables proper IDE support.

If this doesn't convince you, I can change the tests. Just let me know and thank you for your time and effort.

@brian-brazil
Copy link
Contributor

I'd prefer to keep the tests simple.

@crepererum
Copy link
Contributor Author

Then I don't understand. Your proposed solution to just test (all) named attributes is not simpler than the isinstance test. It's more code and more maintenance burden.

@brian-brazil
Copy link
Contributor

I'm suggesting using assertEquals, and you want to check specific types are right verify that they have one of the named attributes.

@crepererum
Copy link
Contributor Author

Alright then. Even though I very much disagree with you, I'll change the test when I'm back in the office (Monday).

@crepererum
Copy link
Contributor Author

done

@brian-brazil
Copy link
Contributor

In one or two tests is enough.

@crepererum
Copy link
Contributor Author

Not sure this is enough. The problem is that the return type was Sample (aka a name tuple) for some and a normal tuple for others. Or in other words: the parser returned inconsistent types. That depends on whether the fixed code path was taken or not. And the code path is taken iff the metric type is counter and the name does not end with _total. As a user, this is pretty much confusing. To prevent this behavior in the future, I've added consistence checks to all tests.

assert type(first) == type(second)
for a, b in zip(first, second):
for sa, sb in zip(a.samples, b.samples):
assert sa.name == sb.name
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a comment as to why you're doing this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a bit lengthy, you only need to say that you're checking the type is correct.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@nichenke
Copy link

nichenke commented Jan 2, 2019

I wanted to chime in with a 'nice catch' on this and add my vote for moving this to a release as soon as reasonable.
FWIW: our case is parsing metrics sent by other libraries (java, scala) that don't add _total by default to Counters. We detected this as generate_latest blew up on AttributeError: 'tuple' object has no attribute 'labels' etc.

Signed-off-by: Marco Neumann <marco.neumann@blue-yonder.com>
@crepererum crepererum force-pushed the improve_parser_types branch from 30a38f4 to e180e1d Compare January 7, 2019 12:10
@brian-brazil brian-brazil merged commit f5e818a into prometheus:master Jan 7, 2019
@brian-brazil
Copy link
Contributor

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants