-
Notifications
You must be signed in to change notification settings - Fork 52
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
Editable installs can set __package__
wrong for an extension submodule of a package
#893
Comments
CC @pablogsal who originally noticed this issue. |
As a quick fix for this very specific case, you could filter the source files from the wheel (wheel.exclude). Is |
FYI, your example run code can be written as a one-liner: $ nox -s downstream -- https://github.com/godlygeek/scikit-build-core-bug-reproducer --editable -c "import demo"
nox > Running session downstream
nox > Creating virtual environment (uv) using python in .nox/downstream
nox > uv pip install build hatch-vcs hatchling
nox > uv pip install . --no-build-isolation
nox > git clone https://github.com/godlygeek/scikit-build-core-bug-reproducer .nox/downstream/tmp/https:__github.com_godlygeek_scikit-build-core-bug-reproducer --recurse-submodules
Cloning into '.nox/downstream/tmp/https:__github.com_godlygeek_scikit-build-core-bug-reproducer'...
remote: Enumerating objects: 10, done.
remote: Counting objects: 100% (10/10), done.
remote: Compressing objects: 100% (8/8), done.
remote: Total 10 (delta 0), reused 10 (delta 0), pack-reused 0 (from 0)
Receiving objects: 100% (10/10), done.
nox > cd .nox/downstream/tmp/https:__github.com_godlygeek_scikit-build-core-bug-reproducer
nox > uv pip install -e.
nox > python -c 'import demo'
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/Users/henryschreiner/git/scikit-build/scikit-build-core/.nox/downstream/tmp/https:__github.com_godlygeek_scikit-build-core-bug-reproducer/src/demo/__init__.py", line 3, in <module>
assert _demo.__package__ == "demo"
^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError
nox > Command python -c 'import demo' failed with exit code 1
nox > Session downstream failed. This also uses the current source for scikit-build-core so it's easy to iterate on a solution. :) I'll try to look into this tomorrow. |
$ .nox/downstream/bin/python >>> import sys
>>> import pprint
>>> sk = sys.meta_path[2]
>>> pprint.pprint(sk.__dict__)
{'build_options': [],
'dir': '/Users/henryschreiner/git/scikit-build/scikit-build-core/.nox/downstream/lib/python3.12/site-packages',
'install_dir': '/Users/henryschreiner/git/scikit-build/scikit-build-core/.nox/downstream/lib/python3.12/site-packages/',
'install_options': [],
'known_source_files': {'demo': '/Users/henryschreiner/git/scikit-build/scikit-build-core/.nox/downstream/tmp/https:__github.com_godlygeek_scikit-build-core-bug-reproducer/src/demo/__init__.py',
'demo._demo._demo': '/Users/henryschreiner/git/scikit-build/scikit-build-core/.nox/downstream/tmp/https:__github.com_godlygeek_scikit-build-core-bug-reproducer/src/demo/_demo/_demo.c'},
'known_wheel_files': {'demo._demo': 'demo/_demo.cpython-312-darwin.so'},
'path': None,
'pkgs': ['demo'],
'rebuild_flag': False,
'submodule_search_locations': {'demo': {'/Users/henryschreiner/git/scikit-build/scikit-build-core/.nox/downstream/lib/python3.12/site-packages/demo',
'/Users/henryschreiner/git/scikit-build/scikit-build-core/.nox/downstream/tmp/https:__github.com_godlygeek_scikit-build-core-bug-reproducer/src/demo'},
'demo._demo': {'/Users/henryschreiner/git/scikit-build/scikit-build-core/.nox/downstream/tmp/https:__github.com_godlygeek_scikit-build-core-bug-reproducer/src/demo/_demo'}},
'verbose': True} It's adding --- a/src/scikit_build_core/resources/_editable_redirect.py
+++ b/src/scikit_build_core/resources/_editable_redirect.py
@@ -94,14 +95,18 @@ class ScikitBuildRedirectingFinder(importlib.abc.MetaPathFinder):
return importlib.util.spec_from_file_location(
fullname,
os.path.join(self.dir, redir),
- submodule_search_locations=submodule_search_locations,
+ submodule_search_locations=submodule_search_locations
+ if redir.endswith("__init__.py")
+ else None,
)
if fullname in self.known_source_files:
redir = self.known_source_files[fullname]
return importlib.util.spec_from_file_location(
fullname,
redir,
- submodule_search_locations=submodule_search_locations,
+ submodule_search_locations=submodule_search_locations
+ if redir.endswith("__init__.py")
+ else None,
)
return None |
I think it makes sense, But isn't it suspicious that |
You can load via |
Though in that case it should contain the extension. |
And I don't think we need to handle |
🤔 but wouldn't it be lying about what the source and python module are represented there since the file is in
Right but then there would be a huge ambiguity when trying to resolve it There is also the functionality of queering the source-code which could be related, but then you would have again more ambiguity with cython, would it be |
Is it possible to recognize that the module being loaded is an extension module and set |
That's what this does as well, since submodules won't be named |
Proposed fix for #893. - **fix: nox + uv downstream improvements** - **fix: editable subpackage issue** --------- Signed-off-by: Henry Schreiner <[email protected]>
For what it's worth, I've tested and this doesn't seem to be the case. I see the same behavior even if I add:
I can confirm with a |
Ahh, yes, editable installs ignore the ignore lists. The idea was that the files will still physically be there, didn't realize that removing these entries would help. Might be worth implementing. 0.10.6 should fix your initial problem directly, though. |
Can you verify 0.10.6 fixed this? |
Yes, I confirm that 0.10.6 fixes things for Memray. Thanks for the quick turnaround! |
Apologies for the delayed response, I was out on vacation. Yes, the proposed fix looks correct to me, and I agree that we can ignore pyi files since they aren't relevant for importing. |
Editable installs can set
__package__
to the wrong value for an extension submodule within a package.Steps to reproduce:
The
demo
package's__init__.py
contains an assertion that the extension submodule has__package__
set correctly (todemo
, the name of the package containing the extension module). When you do a regularpip install
, it does, but when you do an editablepip install
the assertion fails because__package__
has been incorrectly set todemo._demo
instead of todemo
.The problem goes away if you edit the
_demo_editable.py
in the virtualenv and change:to
though I assume that change would break other things. The problem is definitely caused by the
submodule_search_locations
being passed toimportlib.util.spec_from_file_location
though, and it seems to be triggered by the fact that the module's pathdemo._demo
matches the name of a folder in the repodemo/_demo
. Note that this is a common naming convention for extension modules though, including in CPython itself (e.g.Modules/_decimal/_decimal.c
in CPython).This was found in a real world codebase, in bloomberg/memray#673
The text was updated successfully, but these errors were encountered: