-
Notifications
You must be signed in to change notification settings - Fork 54
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
ENH: Make skops.io.dump and load work with TextIOWrapper #234
ENH: Make skops.io.dump and load work with TextIOWrapper #234
Conversation
(note: load already worked, only dump needed change) The idea here is to make it possible to use dump and load with a file wrapper, i.e. using 'with open(...)'. This makes it easier to search and replace pickle dump and load by skops dump and load. Implementation To decide how to check the way to treat the file argument, I went with hasattr(file, "write"), as this is what np.save does. I assume this is more robust than checking the type. Unfortunately, mypy doesn't understand this, so I had to tell it to shut up. I didn't update the docstring or any examples because I don't think we need to 'advertise' this usage.
@skops-dev/maintainers ready for review |
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.
This sounds pretty good to me.
Shouldn't load follow the same pattern?
Also needs a changelog.
skops/io/_persist.py
Outdated
@@ -39,7 +39,7 @@ def _save(obj: Any) -> io.BytesIO: | |||
return buffer | |||
|
|||
|
|||
def dump(obj: Any, file: str) -> None: | |||
def dump(obj: Any, file: str | io.TextIOWrapper) -> None: |
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.
is it a textiowrapper or anything which has write
?
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.
It's the latter, if you prefer I can create a protocol for objects with write attributes, just thought TextIOWrapper
is the most common case by far.
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.
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 dug a bit further, it seems that typing.BinaryIO
would be the correct type:
https://docs.python.org/3/library/typing.html#typing.BinaryIO
This allows mypy to flag code like the one below which uses the wrong mode:
with open(file, 'w') as f: # <= should be 'wb' mode
dump(f)
WDYT?
Regarding Path
: Yeah, that's supported, I originally didn't add it because it's not related to this PR, but I can still add it here.
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.
Ok, I could live with BinaryIO
then.
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.
Okay, I changed it accordingly. I also changed to if isinstance(file, (str, Path))
, which is now correctly type-checked by mypy.
Done, can be reviewed again. |
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.
LGTM
Co-authored-by: Adrin Jalali <adrin.jalali@gmail.com>
(note:
load
already worked, onlydump
needed change)The idea here is to make it possible to use
skops.io.dump
andload
with a file wrapper, i.e. usingwith open(...)
. This makes it easier to search and replacepickle.dump
andload
byskops.io.dump
andload
.Implementation
To decide how to check the way to treat the file argument, I went with
hasattr(file, "write")
, as this is whatnp.save
does. I assume this is more robust than checking the type. Unfortunately, mypy doesn't understand this, so I had to tell it to shut up.I didn't update the docstring or any examples because I don't think we need to "advertise" this usage.