-
-
Notifications
You must be signed in to change notification settings - Fork 690
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
Load Image from bytes #1588
Load Image from bytes #1588
Conversation
Signed-off-by: Bruno Rino <[email protected]>
Signed-off-by: Bruno Rino <[email protected]>
Signed-off-by: Bruno Rino <[email protected]>
Signed-off-by: Bruno Rino <[email protected]>
Signed-off-by: Bruno Rino <[email protected]>
Signed-off-by: Bruno Rino <[email protected]>
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.
General direction looks good; one comment inline about the change to the API for Image()
.
One other suggestion relates to the example. The example test case works to demonstrate the implemented behavior, but isn't a very realistic "real world" case.
I'd like to see an example that is closer to "reality" - e.g., generating a new image with Pillow, storing it as bytes, then showing that image. In addition to proving that the "real world" use case has been satisfied, it serves as useful documentation-by-example to anyone wondering how to use the API.
src/core/toga/images.py
Outdated
self.path = path | ||
def __init__(self, value=None, path=None): | ||
if path is not None: | ||
value = path # TODO: code to deprecate path |
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.
I can see what you're doing here, but the error handling on this is incomplete. It allows specifying both value
and path
, and doesn't catch the Image()
case (at least, not before crashing later).
I'd also suggest changing the function prototype to:
def __init__(self, value=None, *, path=None, data=None):
If you specify value
, you get full "autodetection" behavior; if you specify path
, you get the existing "path or url" conversion; and if you specify data
, it's assumed to be in the right format. Specifying more than one argument would be an error. This doesn't have to be a deprecation path, either - it doesn't seem unreasonable as an ongoing API.
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.
I'd never encountered that lonely star in the args before. Powerful stuff.
If your preference is to preserve separate path
and data
arguments, I personally would prefer this function prototype:
def __init__(self, path=None, data=None):
Simpler, more obvious. One way of doing things. More Zen.
But you're the BDFL. Let me know.
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.
That's a good point - I got so focussed on the change introducing value
that I missed the obvious option. Let's go with (path=None, data=None)
.
FYI - there's an analogous /
that matches *
in args. *
forces all subsequent arguments to be kwargs; /
forces all prior arguments to be positional. The full form of a function is effectively:
def name(positional_only_parameters, /, positional_or_keyword_parameters, *, keyword_only_parameters):
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.
In that case, data
should probably be a keyword-only argument, while path
can continue to be either keyword or positional, for backward compatibility. In other words:
def __init__(self, path=None, *, data=None):
Signed-off-by: Bruno Rino <[email protected]>
Signed-off-by: Bruno Rino <[email protected]>
Signed-off-by: Bruno Rino <[email protected]>
Codecov Report
|
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.
I've made a couple of small tweaks to the example, but otherwise: This is great - thanks!
Currently Image loads files by file path or URL. This PR adds a
bytes
object as an option.Refs #1348
I'd like feedback on whether overloading the positional argument for the Image constructor is well received. Its name,
path
, makes no sense anymore. I changed it to value.Implemented on all backends, but only tested on macOS.
PR Checklist: