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

noarch: python packages do not install in site-packages if python is not a run requirement #497

Closed
2 tasks done
sdebionne opened this issue Jul 1, 2024 · 16 comments · Fixed by #457
Closed
2 tasks done
Labels
pending::discussion contains some ongoing discussion that needs to be resolved prior to proceeding source::community catch-all for issues filed by community members type::bug describes erroneous operation, use severity::* to classify the type

Comments

@sdebionne
Copy link

sdebionne commented Jul 1, 2024

Checklist

  • I added a descriptive title
  • I searched open reports and couldn't find a duplicate

What happened?

We have packages that are actually plugins of another package. Up to conda < 24, installing the main project and the plugin worked fine. With conda >=24, we have the feeling that there is a race condition and that the plugin folder get recreated/overwritten by the main project

With two package containing:

  • package project: site-packages/project/plugins/__init__.py
  • package project-bar-plugin: site-packages/project/plugins/bar.py

Running conda install project project-bar-plugin reports not error but the site-packages/project/plugins/ does not contains bar.py.

I'll attach a repro ASAP.

Conda Info

active environment : test
    active env location : /home/debionne/miniconda3/envs/test
            shell level : 2
       user config file : /home/debionne/.condarc
 populated config files : /home/debionne/.condarc
          conda version : 24.4.0
    conda-build version : not installed
         python version : 3.10.8.final.0
                 solver : libmamba (default)
       virtual packages : __archspec=1=broadwell
                          __conda=24.4.0=0
                          __glibc=2.28=0
                          __linux=4.4.0=0
                          __unix=0=0
       base environment : /home/debionne/miniconda3  (writable)
      conda av data dir : /home/debionne/miniconda3/etc/conda
  conda av metadata url : None
           channel URLs : https://conda.anaconda.org/conda-forge/linux-64
                          https://conda.anaconda.org/conda-forge/noarch
          package cache : /home/debionne/miniconda3/pkgs
                          /home/debionne/.conda/pkgs
       envs directories : /home/debionne/miniconda3/envs
                          /home/debionne/.conda/envs
               platform : linux-64
             user-agent : conda/24.4.0 requests/2.28.1 CPython/3.10.8 Linux/4.4.0-19041-Microsoft debian/10.3 glibc/2.28 solver/libmamba conda-libmamba-solver/23.12.0 libmambapy/1.5.8
                UID:GID : 1000:1000
             netrc file : None
           offline mode : False

Conda Config

==> /home/debionne/.condarc <==
channels:
  - conda-forge

Conda list

# packages in environment at /home/debionne/miniconda3:
#
# Name                    Version                   Build  Channel
_libgcc_mutex             0.1                 conda_forge    conda-forge
_openmp_mutex             4.5                       2_gnu    conda-forge
archspec                  0.2.3              pyhd8ed1ab_0    conda-forge
asttokens                 2.1.0              pyhd8ed1ab_0    conda-forge
backcall                  0.2.0              pyh9f0ad1d_0    conda-forge
backports                 1.0                pyhd8ed1ab_3    conda-forge
backports.functools_lru_cache 1.6.4              pyhd8ed1ab_0    conda-forge
bash-completion           2.11                 ha770c72_1    conda-forge
boltons                   23.0.0             pyhd8ed1ab_0    conda-forge
brotlipy                  0.7.0           py310h5764c6d_1005    conda-forge
bzip2                     1.0.8                h7f98852_4    conda-forge
c-ares                    1.25.0               hd590300_0    conda-forge
ca-certificates           2024.6.2             hbcca054_0    conda-forge
certifi                   2024.6.2           pyhd8ed1ab_0    conda-forge
cffi                      1.15.1          py310h255011f_2    conda-forge
charset-normalizer        2.1.1              pyhd8ed1ab_0    conda-forge
colorama                  0.4.6              pyhd8ed1ab_0    conda-forge
conda                     24.4.0          py310hff52083_0    conda-forge
conda-bash-completion     1.5                           1    tartansandal
conda-libmamba-solver     23.12.0            pyhd8ed1ab_0    conda-forge
conda-package-handling    2.2.0              pyh38be061_0    conda-forge
conda-package-streaming   0.9.0              pyhd8ed1ab_0    conda-forge
cryptography              38.0.3          py310h600f1e7_0    conda-forge
curl                      8.7.1                hca28451_0    conda-forge
decorator                 5.1.1              pyhd8ed1ab_0    conda-forge
distro                    1.9.0              pyhd8ed1ab_0    conda-forge
doxygen                   1.9.5                h583eb01_0    conda-forge
executing                 1.2.0              pyhd8ed1ab_0    conda-forge
expat                     2.5.0                h27087fc_0    conda-forge
fmt                       10.2.1               h00ab1b0_0    conda-forge
gettext                   0.21.1               h27087fc_0    conda-forge
git                       2.39.2          pl5321h693f4a3_0    conda-forge
icu                       73.2                 h59595ed_0    conda-forge
idna                      3.4                pyhd8ed1ab_0    conda-forge
ipython                   8.6.0              pyh41d4057_1    conda-forge
jedi                      0.18.2             pyhd8ed1ab_0    conda-forge
jsonpatch                 1.32               pyhd8ed1ab_0    conda-forge
jsonpointer               2.0                        py_0    conda-forge
keyutils                  1.6.1                h166bdaf_0    conda-forge
krb5                      1.21.2               h659d440_0    conda-forge
ld_impl_linux-64          2.39                 hcc3a1bd_1    conda-forge
libarchive                3.7.2                h039dbb9_0    conda-forge
libcurl                   8.7.1                hca28451_0    conda-forge
libedit                   3.1.20191231         he28a2e2_2    conda-forge
libev                     4.33                 h516909a_1    conda-forge
libffi                    3.4.2                h7f98852_5    conda-forge
libgcc-ng                 12.2.0              h65d4601_19    conda-forge
libgomp                   12.2.0              h65d4601_19    conda-forge
libiconv                  1.17                 h166bdaf_0    conda-forge
libmamba                  1.5.8                had39da4_0    conda-forge
libmambapy                1.5.8           py310h39ff949_0    conda-forge
libnghttp2                1.58.0               h47da74e_1    conda-forge
libnsl                    2.0.0                h7f98852_0    conda-forge
libsolv                   0.7.24               hfc55251_4    conda-forge
libsqlite                 3.40.0               h753d276_0    conda-forge
libssh2                   1.11.0               h0841786_0    conda-forge
libstdcxx-ng              12.2.0              h46fd767_19    conda-forge
libuuid                   2.32.1            h7f98852_1000    conda-forge
libxml2                   2.11.5               h232c23b_1    conda-forge
libzlib                   1.2.13               h166bdaf_4    conda-forge
lz4-c                     1.9.3                h9c3ff4c_1    conda-forge
lzo                       2.10              h516909a_1000    conda-forge
mamba                     1.5.8           py310h51d5547_0    conda-forge
matplotlib-inline         0.1.6              pyhd8ed1ab_0    conda-forge
menuinst                  2.0.2           py310hff52083_0    conda-forge
ncurses                   6.3                  h27087fc_1    conda-forge
openssl                   3.3.1                h4ab18f5_1    conda-forge
packaging                 23.1               pyhd8ed1ab_0    conda-forge
parso                     0.8.3              pyhd8ed1ab_0    conda-forge
pcre2                     10.40                hc3806b6_0    conda-forge
perl                      5.32.1          2_h7f98852_perl5    conda-forge
pexpect                   4.8.0              pyh1a96a4e_2    conda-forge
pickleshare               0.7.5                   py_1003    conda-forge
pip                       22.3.1             pyhd8ed1ab_0    conda-forge
platformdirs              4.1.0              pyhd8ed1ab_0    conda-forge
pluggy                    1.0.0              pyhd8ed1ab_5    conda-forge
ply                       3.11                       py_1    conda-forge
prompt-toolkit            3.0.33             pyha770c72_0    conda-forge
prompt_toolkit            3.0.33               hd8ed1ab_0    conda-forge
ptyprocess                0.7.0              pyhd3deb0d_0    conda-forge
pure_eval                 0.2.2              pyhd8ed1ab_0    conda-forge
pybind11-abi              4                    hd8ed1ab_3    conda-forge
pycosat                   0.6.4           py310h5764c6d_1    conda-forge
pycparser                 2.21               pyhd8ed1ab_0    conda-forge
pygments                  2.13.0             pyhd8ed1ab_0    conda-forge
pyopenssl                 22.1.0             pyhd8ed1ab_0    conda-forge
pyparsing                 3.0.9              pyhd8ed1ab_0    conda-forge
pysocks                   1.7.1              pyha2e5f31_6    conda-forge
python                    3.10.8          h4a9ceb5_0_cpython    conda-forge
python_abi                3.10                    3_cp310    conda-forge
readline                  8.1.2                h0f457ee_0    conda-forge
reproc                    14.2.3               h7f98852_0    conda-forge
reproc-cpp                14.2.3               h9c3ff4c_0    conda-forge
requests                  2.28.1             pyhd8ed1ab_1    conda-forge
ruamel.yaml               0.17.21         py310h5764c6d_2    conda-forge
ruamel.yaml.clib          0.2.7           py310h1fa729e_1    conda-forge
ruamel_yaml               0.15.80         py310h5764c6d_1008    conda-forge
setuptools                65.5.1             pyhd8ed1ab_0    conda-forge
sip                       6.7.5           py310hd8f1fbe_0    conda-forge
six                       1.16.0             pyh6c4a22f_0    conda-forge
sqlite                    3.40.0               h4ff8645_0    conda-forge
stack_data                0.6.1              pyhd8ed1ab_0    conda-forge
tk                        8.6.12               h27826a3_0    conda-forge
toml                      0.10.2             pyhd8ed1ab_0    conda-forge
toolz                     0.12.0             pyhd8ed1ab_0    conda-forge
tqdm                      4.64.1             pyhd8ed1ab_0    conda-forge
traitlets                 5.5.0              pyhd8ed1ab_0    conda-forge
truststore                0.8.0              pyhd8ed1ab_0    conda-forge
tzdata                    2022f                h191b570_0    conda-forge
urllib3                   1.26.13            pyhd8ed1ab_0    conda-forge
wcwidth                   0.2.5              pyh9f0ad1d_2    conda-forge
wheel                     0.38.4             pyhd8ed1ab_0    conda-forge
xz                        5.2.6                h166bdaf_0    conda-forge
yaml                      0.2.5                h7f98852_2    conda-forge
yaml-cpp                  0.8.0                h59595ed_0    conda-forge
zstandard                 0.21.0          py310h1275a96_1    conda-forge
zstd                      1.5.5                hfc55251_0    conda-forge

Additional Context

No response

@sdebionne sdebionne added the type::bug describes erroneous operation, use severity::* to classify the type label Jul 1, 2024
@sdebionne
Copy link
Author

sdebionne commented Jul 1, 2024

Here is the repro that I had in mind, but unfortunately it does not repro. The real project that shows the issue depends on many third party dependencies so the dynamic of the installation is different.

conda-bug-14012.tar.gz

@sdebionne
Copy link
Author

sdebionne commented Jul 1, 2024

Since I cannot provide a repro easily (but it still shows the structure of the project), I can provide a real world repro:

$ conda --version
conda 23.11.0
$ conda create -n test lima-camera-simulator-tango
...
$  ll $CONDA_PREFIX/lib/python3.10/site-packages/Lima/Server/camera
total 32
-rw-rw-r-- 2 Jul  1 08:42 __init__.py
-rw-rw-r-- 2 Oct 19  2022 Simulator.py <------ PLUGIN OK
$ conda --version
conda 24.4.0
$ conda create -n test lima-camera-simulator-tango
...
$  ll $CONDA_PREFIX/lib/python3.10/site-packages/Lima/Server/camera
total 32
-rw-rw-r-- 2 1676 Jul  1 08:42 __init__.py
                               <------ MISSING PLUGIN

Environments are identicals with both versions of Conda.

@ForgottenProgramme ForgottenProgramme added the source::community catch-all for issues filed by community members label Jul 1, 2024
@sdebionne
Copy link
Author

sdebionne commented Jul 1, 2024

Investigating further, with Conda >= 24, the plugin file (here Simulator.py) is actually installed in the wrong folder:

$CONDA_PREFIX/site-packages/Lima/Server/camera/Simulator.py

while it should be

$CONDA_PREFIX/lib/python3.10/site-packages/Lima/Server/camera/Simulator.py

e.g. the site-packages folder is not properly prefixed.

@travishathaway
Copy link
Contributor

travishathaway commented Jul 4, 2024

@sdebionne,

Is there anyway you could link to the project you are having difficulties with? This would help us debug what is currently happening.

From what I have read so far, I think that this is less of a problem with conda and more of a problem with the way this program is being packaged. For example, it's bad practice for one package to modify the contents of another like this. Each individual package, even if they are plugins, should be contained to themselves.

The reason for this is that it helps ensure package integrity. This can be important for security reasons because you would want to know when a package has been tampered with. For example, after adding new files to a package, the checksum value of the package at the time it was built would no longer match.

Regardless, it would really help to see the recipes for these packages to see exactly what's going on.

@travishathaway travishathaway added the pending::feedback indicates we are waiting on feedback from the user label Jul 4, 2024
@sdebionne
Copy link
Author

Thank you for your feedback @travishathaway,

You are right, we should improve our plugin discovery mechanism, so that plugin should not need to be installed in the tree of the main project. In the other hand there is clearly a change of behavior from conda 23 to 24, where our packages stopped to install properly.

While investigating, I found out that the same package does not install the same way with conda 24: it misses the site-packages prefix so that site-packages get copied directly in $CONDA_PREFIX and not in lib\python<version>

While trying to find a workaround, I noticed that switching from a CMake install (that would basically copy a single python file to the proper folder in site-packages) to a pip/setuptools install, fixed the issue. The main difference I see is a direct (build) dependency to python but maybe setuptools generates metadata that are now mandatory to get a "true" noarch python package.

The old package was plugin-project-1.10.0-0.tar.bz2 while the new one is (mind the py) plugin-project-1.10.0-py_1.tar.bz2. So I wonder if, while both recipes use noarch: python, the one without python as direct dependency, did not actually build correctly.

@conda-bot conda-bot added pending::support indicates user is waiting on support from triage engineers and removed pending::feedback indicates we are waiting on feedback from the user labels Jul 4, 2024
@sdebionne
Copy link
Author

The plugin project and recipe is in https://github.com/esrf-bliss/Lima-camera-simulator/blob/develop/conda/tango , but I am afraid it is a bit "opaque"...

@travishathaway travishathaway added pending::discussion contains some ongoing discussion that needs to be resolved prior to proceeding and removed pending::support indicates user is waiting on support from triage engineers labels Jul 8, 2024
@travishathaway
Copy link
Contributor

Thanks for the link to your project.

At this point, I am open to the possibility that a regression may have been introduced in the 24.1.0 release. But, considering that you have found a work around, I will not make this issue a priority.

One change that could come out of this though is to improve the conda-build documentation to warn against the method you were initially using.

Let's leave this discussion open though in case others in the community are facing similar issues.

@jaimergp
Copy link
Contributor

jaimergp commented Jul 15, 2024

Looking at the recipe, you definitely need python in that meta.yaml requirements. It's good practice to be explicit about the direct dependencies. I'd add a host section with python and pip (and lower bounds >=x.y as required by your project), and also add python >=x.y to run.

Shared namespace packages are supported and you can see some examples by examining the backports family, but that CMake config is maybe a bit non standard to follow the assumptions conda-build makes to support them?

@jaimergp
Copy link
Contributor

Do you have a link to the artifacts themselves? Maybe there's something wrong with their "noarchness", because the plugin is being extracted its "noarch path" (starts with site-packages) instead of the "expanded path" (lib/pythonx.y/site-packages).

@sdebionne
Copy link
Author

Sorry for the late answer, here is a link to the artifacts. I am trying to add the python as direct dependency to check whether that helps with the "noarch-pythoness".

@jaimergp
Copy link
Contributor

I took a look and these are my findings. I can't reproduce your issue with latest conda.

This is what I did, assuming the artifacts have been downloaded to a local lima-channel directory.

$ conda create -n lima python=3.10 --platform=linux-64
$ conda activate lima
$ conda install lima-channel/linux-64/lima-camera-simulator-1.10.0-py310h2bc3f7f_0.tar.bz2 lima-channel/noarch/lima-camera-simulator-tango-1.10.0-0.tar.bz2 
$ tree $CONDA_PREFIX/lib/python3.10/site-packages/Lima/
/opt/conda/envs/lima/lib/python3.10/site-packages/Lima/
├── Server
│   └── camera
│       └── Simulator.py  # <------- this is the file we are after, right?
└── Simulator
    ├── Simulator.py
    ├── __init__.py
    └── __pycache__
        ├── Simulator.cpython-310.pyc
        └── __init__.cpython-310.pyc

4 directories, 5 files

@sdebionne
Copy link
Author

This looks good indeed. With the same artifact uploaded on Anaconda, why would I get a different results:

$ conda --version
conda 24.4.0
$ conda create -n lima-tmp
$ conda activate lima-tmp
$ conda install -c esrf-bcu lima-camera-simulator-tango=1.10.0=0
$ tree $CONDA_PREFIX/lib/python3.10/site-packages/Lima/    # edited output for better readability
/miniconda3/envs/lima-tmp/lib/python3.10/site-packages/Lima
├── Server
│   ├── camera
│   │   ├── __init__.py   # <------- file is missing
│   │   └── __pycache__
│   │       └── __init__.cpython-310.pyc

$ tree $CONDA_PREFIX/site-packages/
/miniconda3/envs/lima-tmp/site-packages/
└── Lima
    └── Server
        └── camera
            ├── __pycache__
            │   └── Simulator.cpython-310.pyc
            └── Simulator.py    # <------- found it but not in expended path

I intentionally did not install python in the env as it is an (indirect) dependency of the package.

@sdebionne
Copy link
Author

Same result with conda 24.5.0

@jaimergp
Copy link
Contributor

Yes, I understand why now.

The direct path/URL works because the solver doesn't have to be involved and conda parses the internal JSON metadata directly, which correctly points out that it's noarch: python.

With conda-libmamba-solver and libmamba v1, we lose the noarch information on they way out from the solver, and have to infer it from the subdir. But there are two types of noarch: python and generic. We rely on python being present in the run dependencies (as it should) to identify noarch: python. But since your package doesn't have it, it misses that, and considers it generic. See code here.

This won't be a problem with libmamba v2, because we do get the full noarch information without having to infer anything, but for now we need to be a bit more strict with the run requirements.

Sorry it took so long for me to realize it was about that!

@sdebionne
Copy link
Author

Sorry it took so long for me to realize it was about that!

Awesome support, thank you!

@sdebionne sdebionne changed the title With conda >24 overlapping packages do not install properly With conda >24 noarch: python packages do not install in site-packages if python is not a run requirement Jul 18, 2024
@jaimergp
Copy link
Contributor

I'll move this to conda-libmamba-solver because it's a "bug" there, not in conda. --solver=classic should work, btw.

@jaimergp jaimergp transferred this issue from conda/conda Jul 18, 2024
@jaimergp jaimergp changed the title With conda >24 noarch: python packages do not install in site-packages if python is not a run requirement noarch: python packages do not install in site-packages if python is not a run requirement Jul 18, 2024
@jaimergp jaimergp linked a pull request Jul 18, 2024 that will close this issue
9 tasks
@github-project-automation github-project-automation bot moved this from 🆕 New to 🏁 Done in 🧭 Planning Oct 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pending::discussion contains some ongoing discussion that needs to be resolved prior to proceeding source::community catch-all for issues filed by community members type::bug describes erroneous operation, use severity::* to classify the type
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

5 participants