-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Add custom formatter for Fire result #345
Changes from all commits
ceda820
ffc8077
8a4963d
e837db2
2783342
1b29766
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 |
---|---|---|
|
@@ -194,6 +194,30 @@ def testClassMethod(self): | |
7, | ||
) | ||
|
||
def testCustomSerialize(self): | ||
def serialize(x): | ||
if isinstance(x, list): | ||
return ', '.join(str(xi) for xi in x) | ||
if isinstance(x, dict): | ||
return ', '.join('{}={!r}'.format(k, v) for k, v in x.items()) | ||
if x == 'special': | ||
return ['SURPRISE!!', "I'm a list!"] | ||
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. The name "serialize" implies that the output of serialize is either bytes or a string. 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. Maybe "process" or "finalize"... 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. Forgive my unpolished thinking aloud: Maybe "serialize" is fine, and the logic is: "if you don't finish serializing it, we'll continue serializing it for you using the default serializer." 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. Hmm I mean I personally like
I'm not sure I understand the motivation behind this. Do you mean that you'd want the display mode to have its own default serializer to fall back on? If that's the case, then maybe there could be another mode of serializer override tied to the display object. # could also be defined as a class if you want
def mydisplay(x):
print(x)
def serialize(x):
return x
mydisplay.serialize = serialize
# then internally _Fire(..., display=mydisplay)
default_serialize = getattr(display, 'serialize', None)
if default_serialize:
result = default_serialize(result) 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. side note: one thing that would be nice is if we could have some sort of override via the CLI where the user could do 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. Some notes about the naming - I like I can't think of any other words better than those two tho.
I think this is fine because even if the user doesn't realize that they can't return a string from it, it's not going to break anything, it might just make a little more work for them. |
||
return x | ||
|
||
ident = lambda x: x | ||
|
||
with self.assertOutputMatches(stdout='a, b', stderr=None): | ||
result = core.Fire(ident, command=['[a,b]'], serialize=serialize) | ||
with self.assertOutputMatches(stdout='a=5, b=6', stderr=None): | ||
result = core.Fire(ident, command=['{a:5,b:6}'], serialize=serialize) | ||
with self.assertOutputMatches(stdout='asdf', stderr=None): | ||
result = core.Fire(ident, command=['asdf'], serialize=serialize) | ||
with self.assertOutputMatches(stdout="SURPRISE!!\nI'm a list!\n", stderr=None): | ||
result = core.Fire(ident, command=['special'], serialize=serialize) | ||
with self.assertRaises(core.FireError): | ||
core.Fire(ident, command=['asdf'], serialize=55) | ||
|
||
|
||
@testutils.skipIf(six.PY2, 'lru_cache is Python 3 only.') | ||
def testLruCacheDecoratorBoundArg(self): | ||
self.assertEqual( | ||
|
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.
We'll want to handle the not-callable case too.
I think if we cannot call serialize, we raise a FireError.
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.
Maybe we just do:
which will just raise whatever error the object would raise if tried to be called (probably typeerror)
And this would allow any falsey value to disable serialize (None, False, etc)
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.
addressed - it will now raise
FireError("serialize argument {} must be empty or callable.".format(serialize))