Skip to content
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

Improve the install cache with symlinks method #822

Merged
merged 6 commits into from
Dec 30, 2021
Merged

Conversation

frostming
Copy link
Collaborator

Pull Request Check List

  • A news fragment is added in news/ describing what is new.
  • Test cases added for changed code.

Describe what you have changed in this PR.

Close #820

@codecov-commenter
Copy link

codecov-commenter commented Dec 29, 2021

Codecov Report

Merging #822 (48a2160) into main (9ffa600) will increase coverage by 0.29%.
The diff coverage is 67.34%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #822      +/-   ##
==========================================
+ Coverage   83.34%   83.64%   +0.29%     
==========================================
  Files          74       74              
  Lines        6305     6347      +42     
  Branches     1132     1147      +15     
==========================================
+ Hits         5255     5309      +54     
+ Misses        751      722      -29     
- Partials      299      316      +17     
Flag Coverage Δ
unittests 83.44% <67.34%> (+0.30%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
pdm/project/config.py 96.11% <ø> (ø)
pdm/installers/installers.py 84.52% <67.34%> (-7.54%) ⬇️
pdm/models/repositories.py 77.33% <0.00%> (+0.88%) ⬆️
pdm/models/setup.py 52.56% <0.00%> (+10.27%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b16fbf1...48a2160. Read the comment docs.

Comment on lines +93 to +94
# Otherwise, the directory is likely a namespace package,
# mkdir and create links for all files inside.
Copy link
Contributor

@pawamoy pawamoy Dec 29, 2021

Choose a reason for hiding this comment

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

Very nice! From glancing at the code, it seems you support nested namespace packages (symlinking files only)?
I also see that you remove previous symlinks if they exist: I think it means the order in which you iterate on files matters. I believe CPython usually just sorts such dirs and files list when searching for a module/package, so in our case we'd need to reverse-sort since the last processed file wins?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah, but I guess it won't work if the namespace packages are nested in more than 2 levels:

a   # <- this will be detected as normal directory and create link for it
    b
        c
           __init__.py

But I think it is enough.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah I see. Too bad, I actually have a doubly nested namespace package 😅
But it's OK, pth files work fine, and I'm planning to change that to a level-1 namespace package later anyway.
Thanks!

Copy link
Collaborator Author

@frostming frostming Dec 29, 2021

Choose a reason for hiding this comment

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

it is easy for a recursive detection, but i am not sure if a deeply nested package can still be called a 'package'(think of a/b/c/d/e.py and there is no py file under any level of parents). However, if you agree every py files inside a wheel must belong to a package, the answer would be Yes.

Copy link
Contributor

Choose a reason for hiding this comment

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

Well, that's how PEP420 packages work, so I'd say yes, with a/b/c/d/e.py, a is a (namespace) package (and b, c, and d are sub-namespace packages, or namespace sub-packages haha).

@frostming frostming merged commit b961237 into main Dec 30, 2021
@frostming frostming deleted the fix/symlink-cache branch December 30, 2021 00:43
for child in Path(root).iterdir():
if (
child.is_file()
and child.suffix in (".py", ".pyc", ".pyo", ".pyd")
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if .so files should be checked as well.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I've thought of that, but it was not that easy to tell a .so is a python extension module or not. So this case can be ignored given how rare it is to put a .so inside a PEP 420 namespace package.

Copy link
Contributor

@pawamoy pawamoy Dec 30, 2021

Choose a reason for hiding this comment

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

I've just encountered that case 😂 That's actually why I'm commenting this 😂
But yeah, more than the extension, the whole file name would need to be checked against some regular expression like ^(?P<module_name>\w+)\.(?P<build_info>.+)\.so$ (from my limited knowledge)😕
But you're certainly right and this is unnecessary for PDM (at least for now).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

File exists error when symlinking (namespace packages)
3 participants