GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Replace legacy API implementation with files() by FFY00 · Pull Request #221 · python/importlib_resources

Conversation

@FFY00

@FFY00 FFY00 commented May 12, 2021

Copy link
Copy Markdown
Member

No description provided.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@FFY00
FFY00 force-pushed the use-files-in-leacy-api branch 3 times, most recently from e3e681a to f68da1c Compare May 12, 2021 16:47
@FFY00

FFY00 commented May 12, 2021 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member Author

@jaraco the first commit is bad, but I wonder if is something that we actually want to do? The Path class is clearly designed to not be used, but it needs to be working because the files() will use it. I think we have two options here.

  1. Replace DegenerateFiles.Path with pathlib.Path and force ResourceReader.contents() to iterate valid paths.

  2. Make DegenerateFiles.Path try to emulate the normal behavior with non-existent ResourceReader.contents() files.

I would greatly prefeer 1), which actually seems like the correct behavior, if I understand wrap_spec correctly. 2) is a bit tricky to implement, and I am having some issues.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@jaraco

jaraco commented May 12, 2021

Copy link
Copy Markdown
Member

@FFY00: Can we back up a bit? What expectation is missed that led you to draft the first commit (193ede9)? I see the commit message says "fix DegenerateFiles not exposing loader contents", but I'm unsure why that's needed. Would it be possible to simply deprecate contents altogether?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@FFY00

FFY00 commented May 12, 2021 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member Author

Currently, tests are failing if I switch the contents implementation to the files API.

importlib_resources/importlib_resources/tests/test_resource.py

Line 56 in 9822338

class ResourceLoaderTests(unittest.TestCase):

The current contents implementation will work fine if we create a module manually as done in tests.util.create_package, the files API will not. It will return an empty iterable because that is what the DegenerateFiles.Path implementation does.

importlib_resources/importlib_resources/tests/util.py

Line 54 in e3b5f8d

def create_package(file, path, is_package=True, contents=()):

We could simply deprecate contents, but as discussed in #80, I am reimplementing the legacy API with files to make sure there is no edge case where it doesn't work, and as discovered here, there is.
I guess the question now is, do we care about this case? If we do, do we handle it in the files API, or do we come up with other solution?
To me, it seems wrong that DegenerateFiles will return a traversable that does not correctly represent the spec contents.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@jaraco

jaraco commented May 12, 2021

Copy link
Copy Markdown
Member

If DegenerateFiles.Path implements this behavior, then it betrays its namesake. That is, it's no longer degenerate if it's passing through to some underlying implementation (i.e. ResourceReader.contents).

Maybe the right thing to do here is to rename DegenerateFiles to CompatibilityFiles or FallbackFiles and then allow it to grow this functionality.

An important thing to remember regarding the ResourceReader is that it's an abstract concept. The tests here are capturing an abstract concept that other loaders may be implementing. So option (1) isn't viable (you can't assume the contents of a module could be represented by a pathlib.Path object).

As I see it, the question is - what should happen for a loader that implements 'contents' but not 'files' - should we wrap that implementation and create a files-like interface? My instinct is no... but that will break compatibility, and it's not even be possible in the general case (files implements features that the other APIs were incapable of supporting).

I think you're struggling with a lot of the challenges I've struggled with while trying to adapt everything to run on files().

I don't have a good recommendation at this time, but I'll try to loop back on it again later... and I welcome you to continue to explore it.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@FFY00

FFY00 commented May 12, 2021 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member Author

Maybe the right thing to do here is to rename DegenerateFiles to CompatibilityFiles or FallbackFiles and then allow it to grow this functionality.

I agree.

As I see it, the question is - what should happen for a loader that implements 'contents' but not 'files' - should we wrap that implementation and create a files-like interface? My instinct is no... but that will break compatibility, and it's not even be possible in the general case (files implements features that the other APIs were incapable of supporting).

The thing is, this is already supported by the legacy API. I gave it another try and the issue I am running into is a lack of means to implement is_file, exists, is_dir -- they would need to be supported by the resource reader. Which is essentially the issue you described.

We could support these cases in the files API by making the returned traversable raise an unsupported operation error on such scenarios, which I feel is not a particularly bad idea.
The legacy contents API returns strings, so in files we could return traversables that would still hold that string value but have limited value besides that, we could still support open where ResourceReader can do it, but not is_file and friends.

This proposal makes it possible to easily replace contents usages with files, the possible issue here would be this somehow damaging expectations of the files API. But IMO this should not really be a big issue, as it is an edge case, and we could possibly add support to ResourceReader to optionally implement the missing functionality.
What do you think?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@FFY00
FFY00 force-pushed the use-files-in-leacy-api branch 3 times, most recently from 7055ce1 to 1a2ce97 Compare May 13, 2021 00:50
@FFY00

FFY00 commented May 13, 2021

Copy link
Copy Markdown
Member Author

I have a successful implementation that uses the approach I described.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@jaraco

jaraco commented May 20, 2021

Copy link
Copy Markdown
Member

we could possibly add support to ResourceReader to optionally implement the missing functionality

Since other resource providers implement the the concrete ResourceReader subclasses, any change would need to be compatible with the existing interface, so I suspect this approach is not worthwhile.

I notice the diffcov tests are failing with:

importlib_resources/_adapters.py (52.2%): Missing lines 28,40,56,61-62,65-66,69,76-77,80

Not a hard requirement, but I'd prefer if we had tests covering those code paths.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@FFY00 FFY00 mentioned this pull request May 20, 2021
Replace DegenerateFiles with CompatibilityFiles #226
Closed
@FFY00

FFY00 commented May 21, 2021

Copy link
Copy Markdown
Member Author

Since other resource providers implement the the concrete ResourceReader subclasses, any change would need to be compatible with the existing interface, so I suspect this approach is not worthwhile.

Yes, makes sense, we want people moving away from ResourceReader to TraversableReader so extending ResourceReader does not make that much sense.

Discussion moved to #226.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@FFY00
FFY00 force-pushed the use-files-in-leacy-api branch 2 times, most recently from ba63f38 to 84658bc Compare May 21, 2021 00:16
@FFY00 FFY00 mentioned this pull request May 21, 2021
Deprecate legacy API in favor of traversable API (files) #80
Closed
8 tasks done
@FFY00
FFY00 force-pushed the use-files-in-leacy-api branch 5 times, most recently from 69d19dd to 7cb935e Compare May 21, 2021 00:36
@FFY00 FFY00 mentioned this pull request May 21, 2021
Duplicated TraversableResourcesLoader and wrap_spec #227
Closed
@FFY00
use files() API in contents()
bd4d6ff
Signed-off-by: Filipe Laíns <[email protected]>
@FFY00
FFY00 force-pushed the use-files-in-leacy-api branch 4 times, most recently from 979870a to a1b319c Compare May 29, 2021 18:22
@FFY00

FFY00 commented May 29, 2021

Copy link
Copy Markdown
Member Author

This is still missing tests for CompatibilityFiles, but is ready for review.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@FFY00
FFY00 marked this pull request as ready for review May 29, 2021 18:33
@FFY00
FFY00 requested a review from jaraco May 29, 2021 19:34
FFY00 added 9 commits May 29, 2021 20:47
@FFY00
_adapters: replace DegenerateFiles with CompatibilityFiles
4ff68cf
Signed-off-by: Filipe Laíns <[email protected]>
@FFY00
use files() api in open_* and read_*
53fc1c6
Signed-off-by: Filipe Laíns <[email protected]>
@FFY00
use files() api in is_resource()
30cf1a9
The files() api makes the identification of resources blury. Here we
re-implement is_resource() by mirroring the previous logic to the best
extent we can. This is not fully correct, as the files() api is not
fully compatible with the legacy api, but it is pretty close and as
correct as we can get. The semantics for what constitutes resources have
always been blurry in the first place.

Signed-off-by: Filipe Laíns <[email protected]>
@FFY00
compat: fix selecting the correct reader if the spec is None
b1c38ab
Signed-off-by: Filipe Laíns <[email protected]>
@FFY00
use files() api in path()
62e905c
Signed-off-by: Filipe Laíns <[email protected]>
@FFY00
remove _py3 implementation
c2d85c9
Signed-off-by: Filipe Laíns <[email protected]>
@FFY00
common: ignore PermissionError in _tempfile
5e8c1d2
Signed-off-by: Filipe Laíns <[email protected]>
@FFY00
tests: add tests for CompatibiltyFiles
97083d2
Signed-off-by: Filipe Laíns <[email protected]>
@FFY00
tests: add test for CompatibilityFiles wrap_spec
ef2f7c2
Signed-off-by: Filipe Laíns <[email protected]>
@FFY00
FFY00 force-pushed the use-files-in-leacy-api branch from 870c844 to ef2f7c2 Compare May 29, 2021 19:47
@FFY00

FFY00 commented Jun 7, 2021

Copy link
Copy Markdown
Member Author

@jaraco friendly ping. Please have a look when you have time, I know it's a pretty big, and involved, change so don't feel pressured 😅

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@FFY00

FFY00 commented Jun 21, 2021

Copy link
Copy Markdown
Member Author

@jaraco friendly ping.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@jaraco

jaraco commented Jun 22, 2021 via email

Copy link
Copy Markdown
Member
I haven’t forgotten, but I’ve had quite a lot on my plate. Will get to it soon. Thanks for the patience and reminder.
FFY00 reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

jaraco
jaraco approved these changes Jun 26, 2021
View reviewed changes

@jaraco jaraco left a comment

Copy link
Copy Markdown
Member

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 work is excellent. It's clean, makes some smart decisions, but most importantly sets us up to be able to deprecate the legacy API. I have only the one serious reservation, and even that isn't a blocker to move forward, so I'll defer to your preference on whether to pursue those changes in this PR or a subsequent one.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread importlib_resources/_compat.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread importlib_resources/_common.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

@FFY00
legacy: move legacy API to separate module
e016e66
Signed-off-by: Filipe Laíns <[email protected]>
@jaraco
jaraco merged commit 5b2a675 into python:main Jun 28, 2021
jaraco added a commit that referenced this pull request Jun 28, 2021
@jaraco
Update changelog. Ref #221.
fc2bce9
@jaraco

jaraco commented Jun 28, 2021

Copy link
Copy Markdown
Member

Big thanks Filipe. Releasing as v5.2.0.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@chaen chaen mentioned this pull request Jun 29, 2021
[v7r2]Client: protect documentation generation against py3 DIRACGrid/DIRAC#5233
Merged
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@jaraco jaraco jaraco approved these changes

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

2 participants

@FFY00 @jaraco
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.