Skip to content

ENH: Make skops.io.dump and load work with TextIOWrapper#234

Merged
adrinjalali merged 5 commits intoskops-dev:mainfrom
BenjaminBossan:allow-with-dump-and-load
Dec 2, 2022
Merged

ENH: Make skops.io.dump and load work with TextIOWrapper#234
adrinjalali merged 5 commits intoskops-dev:mainfrom
BenjaminBossan:allow-with-dump-and-load

Conversation

@BenjaminBossan
Copy link
Copy Markdown
Collaborator

(note: load already worked, only dump needed change)

The idea here is to make it possible to use skops.io.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.io.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.

(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.
@BenjaminBossan BenjaminBossan added the persistence Secure persistence feature label Dec 1, 2022
@BenjaminBossan
Copy link
Copy Markdown
Collaborator Author

@skops-dev/maintainers ready for review

Copy link
Copy Markdown
Member

@adrinjalali adrinjalali left a 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.

Comment thread skops/io/_persist.py Outdated


def dump(obj: Any, file: str) -> None:
def dump(obj: Any, file: str | io.TextIOWrapper) -> None:
Copy link
Copy Markdown
Member

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?

Copy link
Copy Markdown
Collaborator Author

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Or not have it typed? 👻

We also accept a Path.

What we really accept here, is a file-like object, or a path like object. And that's best explained in the docstring w/o any types.

image

Copy link
Copy Markdown
Collaborator Author

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.

Copy link
Copy Markdown
Member

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.

Copy link
Copy Markdown
Collaborator Author

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.

@BenjaminBossan BenjaminBossan changed the title Make skops.io.dump and load work with TextWrapper Make skops.io.dump and load work with TextIOWrapper Dec 2, 2022
@BenjaminBossan BenjaminBossan changed the title Make skops.io.dump and load work with TextIOWrapper ENH: Make skops.io.dump and load work with TextIOWrapper Dec 2, 2022
@BenjaminBossan
Copy link
Copy Markdown
Collaborator Author

Shouldn't load follow the same pattern?

load already works because ZipFile takes care of correctly dealing with the file argument.

Also needs a changelog.

Done, can be reviewed again.

Copy link
Copy Markdown
Collaborator

@E-Aho E-Aho left a comment

Choose a reason for hiding this comment

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

LGTM

Comment thread docs/changes.rst Outdated
Co-authored-by: Adrin Jalali <adrin.jalali@gmail.com>
@adrinjalali adrinjalali merged commit ec8df2f into skops-dev:main Dec 2, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

persistence Secure persistence feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants