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

[BUG] lists in pyproject.toml dependencies not handled #463

Open
xylar opened this issue Apr 29, 2023 · 15 comments
Open

[BUG] lists in pyproject.toml dependencies not handled #463

xylar opened this issue Apr 29, 2023 · 15 comments
Labels
bug Something isn't working

Comments

@xylar
Copy link
Contributor

xylar commented Apr 29, 2023

Describe the bug
Dependencies like the following in a pyproject.toml raise a grayskull.strategy.py_toml.InvalidPoetryDependency error:

pyarrow = [
    {version = ">=6.0.0", python = ">=3.7,<3.11"},
    {version = ">=10.0.1", python = ">=3.11"}
]

To Reproduce
Steps to reproduce the behavior:

$ grayskull pypi databricks-sql-connector

#### Initializing recipe for databricks-sql-connector (pypi) ####

Recovering metadata from pypi...
Starting the download of the sdist package databricks-sql-connector
databricks-sql-connector 100% Time:  0:00:00 664.7 KiB/s|#####################|
Checking for pyproject.toml
pyproject.toml found in /tmp/grayskull-databricks-sql-connector-tdnkdt4v/databricks_sql_connector-2.5.1/pyproject.toml
Traceback (most recent call last):
  File "/home/xylar/mambaforge/bin/grayskull", line 10, in <module>
    sys.exit(main())
  File "/home/xylar/mambaforge/lib/python3.10/site-packages/grayskull/__main__.py", line 276, in main
    generate_recipes_from_list(args.pypi_packages, args)
  File "/home/xylar/mambaforge/lib/python3.10/site-packages/grayskull/__main__.py", line 299, in generate_recipes_from_list
    recipe, config = create_python_recipe(
  File "/home/xylar/mambaforge/lib/python3.10/site-packages/grayskull/__main__.py", line 334, in create_python_recipe
    GrayskullFactory.create_recipe(
  File "/home/xylar/mambaforge/lib/python3.10/site-packages/grayskull/base/factory.py", line 46, in create_recipe
    GrayskullFactory.REGISTERED_STRATEGY[repo_type.lower()].fetch_data(
  File "/home/xylar/mambaforge/lib/python3.10/site-packages/grayskull/strategy/pypi.py", line 60, in fetch_data
    update_recipe(recipe, config, sections or ALL_SECTIONS)
  File "/home/xylar/mambaforge/lib/python3.10/site-packages/grayskull/strategy/pypi.py", line 485, in update_recipe
    metadata = get_metadata(recipe, config)
  File "/home/xylar/mambaforge/lib/python3.10/site-packages/grayskull/strategy/pypi.py", line 347, in get_metadata
    sdist_metadata, pypi_metadata = get_origin_wise_metadata(config)
  File "/home/xylar/mambaforge/lib/python3.10/site-packages/grayskull/strategy/pypi.py", line 232, in get_origin_wise_metadata
    sdist_metadata = get_sdist_metadata(
  File "/home/xylar/mambaforge/lib/python3.10/site-packages/grayskull/strategy/py_base.py", line 771, in get_sdist_metadata
    pyproject_metadata = get_all_toml_info(pyproject_toml)
  File "/home/xylar/mambaforge/lib/python3.10/site-packages/grayskull/strategy/py_toml.py", line 263, in get_all_toml_info
    add_poetry_metadata(metadata, toml_metadata)
  File "/home/xylar/mambaforge/lib/python3.10/site-packages/grayskull/strategy/py_toml.py", line 195, in add_poetry_metadata
    req_run, req_run_constrained = encode_poetry_deps(poetry_deps)
  File "/home/xylar/mambaforge/lib/python3.10/site-packages/grayskull/strategy/py_toml.py", line 180, in encode_poetry_deps
    constrained_dep = get_constrained_dep(dep_spec, dep_name)
  File "/home/xylar/mambaforge/lib/python3.10/functools.py", line 889, in wrapper
    return dispatch(args[0].__class__)(*args, **kw)
  File "/home/xylar/mambaforge/lib/python3.10/site-packages/grayskull/strategy/py_toml.py", line 158, in get_constrained_dep
    raise InvalidPoetryDependency(
grayskull.strategy.py_toml.InvalidPoetryDependency: Expected Poetry dependency specification to be of type str or dict, received list

Expected behavior
In this case, there should be a selector:

   - pyarrow >=6.0.0  # py>=37,<311
   - pyarrow >=10.0.1  # py>=311

Environment:

  • conda list
$ conda list
# packages in environment at /home/xylar/mambaforge:
#
# Name                    Version                   Build  Channel
_libgcc_mutex             0.1                 conda_forge    conda-forge
_openmp_mutex             4.5                       2_gnu    conda-forge
anaconda-client           1.11.2             pyhd8ed1ab_0    conda-forge
anaconda-project          0.11.1             pyhd8ed1ab_0    conda-forge
anyio                     3.6.2              pyhd8ed1ab_0    conda-forge
attrs                     22.2.0             pyh71513ae_0    conda-forge
backports                 1.0                pyhd8ed1ab_3    conda-forge
backports.functools_lru_cache 1.6.4              pyhd8ed1ab_0    conda-forge
beautifulsoup4            4.12.2             pyha770c72_0    conda-forge
blinker                   1.6.2              pyhd8ed1ab_0    conda-forge
boltons                   23.0.0             pyhd8ed1ab_0    conda-forge
boolean.py                3.7                        py_0    conda-forge
brotlipy                  0.7.0           py310h5764c6d_1005    conda-forge
bzip2                     1.0.8                h7f98852_4    conda-forge
c-ares                    1.18.1               h7f98852_0    conda-forge
ca-certificates           2022.12.7            ha878542_0    conda-forge
certifi                   2022.12.7          pyhd8ed1ab_0    conda-forge
cffi                      1.15.1          py310h255011f_3    conda-forge
chardet                   5.1.0           py310hff52083_0    conda-forge
charset-normalizer        3.1.0              pyhd8ed1ab_0    conda-forge
clyent                    1.2.2                      py_1    conda-forge
colorama                  0.4.6              pyhd8ed1ab_0    conda-forge
conda                     23.3.1          py310hff52083_0    conda-forge
conda-build               3.24.0          py310hff52083_1    conda-forge
conda-forge-pinning       2023.04.26.18.42.43      hd8ed1ab_0    conda-forge
conda-pack                0.7.0              pyh6c4a22f_0    conda-forge
conda-package-handling    2.0.2              pyh38be061_0    conda-forge
conda-package-streaming   0.7.0              pyhd8ed1ab_1    conda-forge
conda-smithy              3.23.1             pyhd8ed1ab_0    conda-forge
conda-souschef            2.2.3              pyhd8ed1ab_0    conda-forge
cryptography              40.0.2          py310h34c0648_0    conda-forge
curl                      8.0.1                h588be90_0    conda-forge
dataclasses               0.8                pyhc8e2a94_3    conda-forge
defusedxml                0.7.1              pyhd8ed1ab_0    conda-forge
deprecated                1.2.13             pyh6c4a22f_0    conda-forge
expat                     2.5.0                hcb278e6_1    conda-forge
filelock                  3.12.0             pyhd8ed1ab_0    conda-forge
fmt                       9.1.0                h924138e_0    conda-forge
freetype                  2.12.1               hca18f0e_1    conda-forge
gettext                   0.21.1               h27087fc_0    conda-forge
gh                        2.25.1               ha8f183a_0    conda-forge
git                       2.40.1          pl5321h86e50cf_0    conda-forge
gitdb                     4.0.10             pyhd8ed1ab_0    conda-forge
gitpython                 3.1.31             pyhd8ed1ab_0    conda-forge
glob2                     0.7                        py_0    conda-forge
gmp                       6.2.1                h58526e2_0    conda-forge
grayskull                 2.3.0              pyhd8ed1ab_1    conda-forge
icu                       72.1                 hcb278e6_0    conda-forge
idna                      3.4                pyhd8ed1ab_0    conda-forge
importlib-metadata        6.6.0              pyha770c72_0    conda-forge
importlib_resources       5.12.0             pyhd8ed1ab_0    conda-forge
isodate                   0.6.1              pyhd8ed1ab_0    conda-forge
jinja2                    3.1.2              pyhd8ed1ab_1    conda-forge
joblib                    1.2.0              pyhd8ed1ab_0    conda-forge
jpeg                      9e                   h0b41bf4_3    conda-forge
json5                     0.9.5              pyh9f0ad1d_0    conda-forge
jsonpatch                 1.32               pyhd8ed1ab_0    conda-forge
jsonpointer               2.0                        py_0    conda-forge
jsonschema                4.17.3             pyhd8ed1ab_0    conda-forge
jupyter_core              5.3.0           py310hff52083_0    conda-forge
keyutils                  1.6.1                h166bdaf_0    conda-forge
krb5                      1.20.1               h81ceb04_0    conda-forge
lcms2                     2.15                 hfd0df8a_0    conda-forge
ld_impl_linux-64          2.40                 h41732ed_0    conda-forge
lerc                      4.0.0                h27087fc_0    conda-forge
libarchive                3.6.2                h3d51595_0    conda-forge
libblas                   3.9.0           16_linux64_openblas    conda-forge
libcblas                  3.9.0           16_linux64_openblas    conda-forge
libcurl                   8.0.1                h588be90_0    conda-forge
libdeflate                1.17                 h0b41bf4_0    conda-forge
libedit                   3.1.20191231         he28a2e2_2    conda-forge
libev                     4.33                 h516909a_1    conda-forge
libexpat                  2.5.0                hcb278e6_1    conda-forge
libffi                    3.4.2                h7f98852_5    conda-forge
libgcc-ng                 12.2.0              h65d4601_19    conda-forge
libgfortran-ng            12.2.0              h69a702a_19    conda-forge
libgfortran5              12.2.0              h337968e_19    conda-forge
libgomp                   12.2.0              h65d4601_19    conda-forge
libiconv                  1.17                 h166bdaf_0    conda-forge
liblapack                 3.9.0           16_linux64_openblas    conda-forge
liblief                   0.12.3               h27087fc_0    conda-forge
libmamba                  1.4.2                hcea66bb_0    conda-forge
libmambapy                1.4.2           py310h1428755_0    conda-forge
libnghttp2                1.52.0               h61bc06f_0    conda-forge
libnsl                    2.0.0                h7f98852_0    conda-forge
libopenblas               0.3.21          pthreads_h78a6416_3    conda-forge
libpng                    1.6.39               h753d276_0    conda-forge
libsodium                 1.0.18               h36c2ea0_1    conda-forge
libsolv                   0.7.23               h3eb15da_0    conda-forge
libsqlite                 3.40.0               h753d276_1    conda-forge
libssh2                   1.10.0               hf14f497_3    conda-forge
libstdcxx-ng              12.2.0              h46fd767_19    conda-forge
libtiff                   4.5.0                h6adf6a1_2    conda-forge
libuuid                   2.38.1               h0b41bf4_0    conda-forge
libwebp-base              1.3.0                h0b41bf4_0    conda-forge
libxcb                    1.13              h7f98852_1004    conda-forge
libxml2                   2.10.4               hfdac1af_0    conda-forge
libzlib                   1.2.13               h166bdaf_4    conda-forge
license-expression        1.2                        py_0    conda-forge
lz4-c                     1.9.4                hcb278e6_0    conda-forge
lzo                       2.10              h516909a_1000    conda-forge
mamba                     1.4.2           py310h51d5547_0    conda-forge
markdown-it-py            2.2.0              pyhd8ed1ab_0    conda-forge
markupsafe                2.1.2           py310h1fa729e_0    conda-forge
mdurl                     0.1.0              pyhd8ed1ab_0    conda-forge
msrest                    0.6.21             pyh44b312d_0    conda-forge
nbformat                  5.8.0              pyhd8ed1ab_0    conda-forge
ncurses                   6.3                  h27087fc_1    conda-forge
numpy                     1.24.3          py310ha4c1d20_0    conda-forge
oauthlib                  3.2.2              pyhd8ed1ab_0    conda-forge
openjpeg                  2.5.0                hfec8fc6_2    conda-forge
openssl                   3.1.0                hd590300_2    conda-forge
packaging                 23.1               pyhd8ed1ab_0    conda-forge
patch                     2.7.6             h7f98852_1002    conda-forge
patchelf                  0.17.2               h58526e2_0    conda-forge
pcre2                     10.40                hc3806b6_0    conda-forge
perl                      5.32.1          2_h7f98852_perl5    conda-forge
pillow                    9.4.0           py310h023d228_1    conda-forge
pip                       23.1.2             pyhd8ed1ab_0    conda-forge
pkginfo                   1.9.6              pyhd8ed1ab_0    conda-forge
pkgutil-resolve-name      1.3.10             pyhd8ed1ab_0    conda-forge
platformdirs              3.3.0              pyhd8ed1ab_0    conda-forge
pluggy                    1.0.0              pyhd8ed1ab_5    conda-forge
progressbar2              4.2.0              pyhd8ed1ab_0    conda-forge
prompt-toolkit            3.0.38             pyha770c72_0    conda-forge
prompt_toolkit            3.0.38               hd8ed1ab_0    conda-forge
psutil                    5.9.5           py310h1fa729e_0    conda-forge
pthread-stubs             0.4               h36c2ea0_1001    conda-forge
py-lief                   0.12.3          py310hd8f1fbe_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
pycryptodome              3.16.0          py310h1419917_0    conda-forge
pygithub                  1.58.0             pyh1a96a4e_0    conda-forge
pygments                  2.15.1             pyhd8ed1ab_0    conda-forge
pyjwt                     2.6.0              pyhd8ed1ab_0    conda-forge
pynacl                    1.5.0           py310h5764c6d_2    conda-forge
pyopenssl                 23.1.1             pyhd8ed1ab_0    conda-forge
pyrsistent                0.19.3          py310h1fa729e_0    conda-forge
pysocks                   1.7.1              pyha2e5f31_6    conda-forge
python                    3.10.10         he550d4f_0_cpython    conda-forge
python-dateutil           2.8.2              pyhd8ed1ab_0    conda-forge
python-fastjsonschema     2.16.3             pyhd8ed1ab_0    conda-forge
python-libarchive-c       4.0             py310hff52083_2    conda-forge
python-utils              3.5.2              pyhd8ed1ab_0    conda-forge
python_abi                3.10                    3_cp310    conda-forge
pytz                      2023.3             pyhd8ed1ab_0    conda-forge
pyyaml                    6.0             py310h5764c6d_5    conda-forge
rapidfuzz                 3.0.0           py310heca2aa9_0    conda-forge
readline                  8.2                  h8228510_1    conda-forge
reproc                    14.2.4               h0b41bf4_0    conda-forge
reproc-cpp                14.2.4               hcb278e6_0    conda-forge
requests                  2.29.0             pyhd8ed1ab_0    conda-forge
requests-oauthlib         1.3.1              pyhd8ed1ab_0    conda-forge
requests-toolbelt         0.10.1             pyhd8ed1ab_0    conda-forge
rich                      13.3.4             pyhd8ed1ab_0    conda-forge
ripgrep                   13.0.0               h2f28480_2    conda-forge
ruamel.yaml               0.17.21         py310h1fa729e_3    conda-forge
ruamel.yaml.clib          0.2.7           py310h1fa729e_1    conda-forge
ruamel.yaml.jinja2        0.2.4                      py_1    conda-forge
ruamel_yaml               0.15.80         py310h5764c6d_1008    conda-forge
scrypt                    0.8.18          py310ha302636_4    conda-forge
semver                    2.13.0             pyh9f0ad1d_0    conda-forge
setuptools                67.7.2             pyhd8ed1ab_0    conda-forge
six                       1.16.0             pyh6c4a22f_0    conda-forge
smmap                     3.0.5              pyh44b312d_0    conda-forge
sniffio                   1.3.0              pyhd8ed1ab_0    conda-forge
soupsieve                 2.3.2.post1        pyhd8ed1ab_0    conda-forge
stdlib-list               0.8.0              pyhd8ed1ab_0    conda-forge
tk                        8.6.12               h27826a3_0    conda-forge
toml                      0.10.2             pyhd8ed1ab_0    conda-forge
tomli                     2.0.1              pyhd8ed1ab_0    conda-forge
tomli-w                   1.0.0              pyhd8ed1ab_0    conda-forge
toolz                     0.12.0             pyhd8ed1ab_0    conda-forge
tornado                   6.3             py310h1fa729e_0    conda-forge
tqdm                      4.65.0             pyhd8ed1ab_1    conda-forge
traitlets                 5.9.0              pyhd8ed1ab_0    conda-forge
typing-extensions         4.5.0                hd8ed1ab_0    conda-forge
typing_extensions         4.5.0              pyha770c72_0    conda-forge
tzdata                    2023c                h71feb2d_0    conda-forge
urllib3                   1.26.15            pyhd8ed1ab_0    conda-forge
vsts-python-api           0.1.25             pyhd8ed1ab_1    conda-forge
watchgod                  0.8.2              pyhd8ed1ab_0    conda-forge
wcwidth                   0.2.6              pyhd8ed1ab_0    conda-forge
wheel                     0.40.0             pyhd8ed1ab_0    conda-forge
wrapt                     1.15.0          py310h1fa729e_0    conda-forge
xorg-libxau               1.0.9                h7f98852_0    conda-forge
xorg-libxdmcp             1.1.3                h7f98852_0    conda-forge
xz                        5.2.6                h166bdaf_0    conda-forge
yaml                      0.2.5                h7f98852_2    conda-forge
yaml-cpp                  0.7.0                h27087fc_2    conda-forge
zipp                      3.15.0             pyhd8ed1ab_0    conda-forge
zstandard                 0.19.0          py310hdeb6495_1    conda-forge
zstd                      1.5.2                h3eb15da_6    conda-forge
  • grayskull --version
$ grayskull --version
2.3.0
@xylar xylar added the bug Something isn't working label Apr 29, 2023
@xylar
Copy link
Contributor Author

xylar commented Apr 29, 2023

@dlqqq, is this one you could have a look at?

@darynwhite
Copy link

I'm receiving the same error sequence:

#### Initializing recipe for plotly-resampler (pypi) ####

Recovering metadata from pypi...
Starting the download of the sdist package plotly-resampler
plotly-resampler 100% Time:  0:00:00 1022.4 KiB/s|#############################################################################################################################################|
Checking for pyproject.toml
pyproject.toml found in /var/folders/n1/82bp3xw12y50t8kgdv3bj17h0000ng/T/grayskull-plotly-resampler-ok03_0ki/plotly_resampler-0.9.1/pyproject.toml
Traceback (most recent call last):
  File "/Users/white/conda/envs/smithy/bin/grayskull", line 10, in <module>
    sys.exit(main())
             ^^^^^^
  File "/Users/white/conda/envs/smithy/lib/python3.11/site-packages/grayskull/__main__.py", line 276, in main
    generate_recipes_from_list(args.pypi_packages, args)
  File "/Users/white/conda/envs/smithy/lib/python3.11/site-packages/grayskull/__main__.py", line 299, in generate_recipes_from_list
    recipe, config = create_python_recipe(
                     ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/white/conda/envs/smithy/lib/python3.11/site-packages/grayskull/__main__.py", line 334, in create_python_recipe
    GrayskullFactory.create_recipe(
  File "/Users/white/conda/envs/smithy/lib/python3.11/site-packages/grayskull/base/factory.py", line 46, in create_recipe
    GrayskullFactory.REGISTERED_STRATEGY[repo_type.lower()].fetch_data(
  File "/Users/white/conda/envs/smithy/lib/python3.11/site-packages/grayskull/strategy/pypi.py", line 60, in fetch_data
    update_recipe(recipe, config, sections or ALL_SECTIONS)
  File "/Users/white/conda/envs/smithy/lib/python3.11/site-packages/grayskull/strategy/pypi.py", line 485, in update_recipe
    metadata = get_metadata(recipe, config)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/white/conda/envs/smithy/lib/python3.11/site-packages/grayskull/strategy/pypi.py", line 347, in get_metadata
    sdist_metadata, pypi_metadata = get_origin_wise_metadata(config)
                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/white/conda/envs/smithy/lib/python3.11/site-packages/grayskull/strategy/pypi.py", line 232, in get_origin_wise_metadata
    sdist_metadata = get_sdist_metadata(
                     ^^^^^^^^^^^^^^^^^^^
  File "/Users/white/conda/envs/smithy/lib/python3.11/site-packages/grayskull/strategy/py_base.py", line 771, in get_sdist_metadata
    pyproject_metadata = get_all_toml_info(pyproject_toml)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/white/conda/envs/smithy/lib/python3.11/site-packages/grayskull/strategy/py_toml.py", line 263, in get_all_toml_info
    add_poetry_metadata(metadata, toml_metadata)
  File "/Users/white/conda/envs/smithy/lib/python3.11/site-packages/grayskull/strategy/py_toml.py", line 195, in add_poetry_metadata
    req_run, req_run_constrained = encode_poetry_deps(poetry_deps)
                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/white/conda/envs/smithy/lib/python3.11/site-packages/grayskull/strategy/py_toml.py", line 180, in encode_poetry_deps
    constrained_dep = get_constrained_dep(dep_spec, dep_name)
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/white/conda/envs/smithy/lib/python3.11/functools.py", line 909, in wrapper
    return dispatch(args[0].__class__)(*args, **kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/white/conda/envs/smithy/lib/python3.11/site-packages/grayskull/strategy/py_toml.py", line 158, in get_constrained_dep
    raise InvalidPoetryDependency(
grayskull.strategy.py_toml.InvalidPoetryDependency: Expected Poetry dependency specification to be of type str or dict, received list

@darynwhite
Copy link

Digging a little further, I think the error arises from how the numpy dependency is in the file:

[tool.poetry.dependencies]
python = "^3.7.1"
jupyter-dash = { version = ">=0.4.2", optional = true }
plotly = "^5.5.0"
dash = "^2.11.0"
pandas = ">=1"
trace-updater = ">=0.0.8"
numpy = [
    { version = ">=1.14", python = "<3.11" },
    { version = ">=1.24", python = ">=3.11" }
]
orjson = "^3.8.0"  # Faster json serialization
# Optional dependencies
Flask-Cors = { version = "^3.0.10", optional = true }
# Lock kaleido dependency until https://github.com/plotly/Kaleido/issues/156 is resolved
kaleido = {version = "0.2.1", optional = true}
tsdownsample = "0.1.2"

@darynwhite
Copy link

In learning what Poetry's definitions are, I found this reference that is specific to this bug.

Poetry Multiple Constraints

@kcpevey
Copy link

kcpevey commented Nov 29, 2023

I dont think its possible can handle it the same way via conda, but it seems like grayskull should make some assumption and move on instead of failing.

It looks like we need some enhancement here . I started to think through a fix, something like this:

        if isinstance(dep_spec, list):
            for dep in dep_spec:
                constrained_dep = get_constrained_dep(dep, dep_name)

but that would only just use the last constraint specified. I think a proper solution would be to make an assumption like "always use the later python version" (and tell the user about it). And then go back and adjust the minimum python version for the recipe.

I dont know anything about this codebase, but it seems like there might be some functions in here that could help with version comparisons?

For example, I have python="^3.8" and then a dep_spec that looks like

scikit-image = [
    # Hinge because minimum support 0.20.0 for py3.11
    { version = ">=0.18.1", python = "<3.11" },
    { version = ">=0.20.0", python = ">=3.11" }
]

So I need to compare the two python versions in the dep spec and find the later one, then ensure that the overall python version is compatible or adjusted. Is there a tool in greyskull that can help with those comparisons?

@xylar
Copy link
Contributor Author

xylar commented Nov 29, 2023

I don't agree that conda can't handle this. It should be possible to do:

scikit-image >=0.18.1  # py<311
scikit-image >=0.20.0  # py>=311

This obviously doesn't allow you to be noarch: python but that is something the feedstock maintainers should intervene on if they want to make that call. grayskull needs to default to not doing noarch: python in these circumstances.

@kcpevey
Copy link

kcpevey commented Nov 29, 2023

I'm not sure I understand what you mean @xylar . I meant that conda can't handle that same level of detail in a single environment file (or meta.yml spec?).

For example if I have an environment.yml file like this:

channels:
- conda-forge
dependencies:
- python=3.10
- scikit-image >=0.18.1  # py<311
- scikit-image >=0.20.0  # py>=311

This will solve to python=3.10.13 and scikit-image=0.22.0 which is in disagreement with what the poetry spec was attempting to specify.

@darynwhite
Copy link

I've discovered that conda can handle a set of requirements, see this example I have working in conda-forge/willow-feedstock/recipe/meta.yaml:

pyproject.toml

heif = [
    "pillow-heif>=0.10.0,<1.0.0; python_version < '3.12'",
    "pillow-heif>=0.13.0,<1.0.0; python_version >= '3.12'",
]

recipe.yaml

  - pillow-heif >=0.10.0,<1.0.0<py312|>=0.13.0,<1.0.0>=py312

I adapted the list based on the documentation here: Conda Package Match Specs

@xylar
Copy link
Contributor Author

xylar commented Nov 30, 2023

@kcpevey, yeah, I get that this can be a bit confusing. What grayskull produces is a meta.yaml that is used for a recipe for building a conda package. That's different from a yaml file that is used to produce an environment. In a meta.yaml, you would be very unlikely to have a spec like:

- python=3.10

Instead, you would have something like:

...
requirements:
  host:
    - python >=3.8
    - pip
  run:
    - python >=3.8
    - scikit-image >=0.18.1  # py<311
    - scikit-image >=0.20.0  # py>=311

The recipe will be build with various python versions (currently, 3.8 to 3.12) and the # py<311 and # py>=311 selectors will determine which to use. for the python version currently being used for the package build.

I think this shouldn't be too hard to fix in grayskull but I haven't had time to look into it myself.

@xylar
Copy link
Contributor Author

xylar commented Nov 30, 2023

@darynwhite, I don't think we want something as complex as:

  - pillow-heif >=0.10.0,<1.0.0<py312|>=0.13.0,<1.0.0>=py312

That isn't how this kind of case is handled in meta.yaml files across conda-forge. I think this would be better:

  - pillow-heif >=0.10.0,<1.0.0  # py>312
  - pillow-heif >=0.13.0,<1.0.0  # py>=312

I don't think conda-smithy is going to be able to handle the syntax you suggested correctly.

@kcpevey
Copy link

kcpevey commented Nov 30, 2023

Thanks for the explanation! I didn't know about that!

I'm working on a solution. I have both deps added to the requirements list but then when I get here, that one liner grabs only the FIRST dep in the list.

If I fix that, then I hit this reduction of package names to a set, thereby preventing duplicates.

I'll keep pressing on, but I'm wondering exactly how many things I'll break down the line since there seems to be a strong assumption that there will only be ONE spec per package?

@darynwhite
Copy link

@xylar I was successful in building the latest willow-feedstock update with that complex string, albeit a complicated package spec. Here's the latest PR

Quoting from the conda-build docs Requirements section

Specifies the build and runtime requirements. Dependencies of these requirements are included automatically.

Versions for requirements must follow the conda match specification. See Package match specifications.

And the Package match specifications say:

...
The build string constraint "numpy=1.11.2=nomkl" matches the NumPy 1.11.2 packages without MKL but not the normal MKL NumPy 1.11.2 packages.

The build string constraint "numpy=1.11.1|1.11.3=py36_0" matches NumPy 1.11.1 or 1.11.3 built for Python 3.6 but not any versions of NumPy built for Python 3.5 or Python 2.7.
...

That said...

I am unable to find a reference for breaking the package spec into two lines, so I don't know what the behavior could be if that is done. I only have the above mentioned Package match specifications documentation to go off of.

@xylar
Copy link
Contributor Author

xylar commented Dec 1, 2023

@darynwhite, the multi-line approach uses processing selectors, see:
https://docs.conda.io/projects/conda-build/en/stable/resources/define-metadata.html#preprocessing-selectors

Your approach might work fine with conda-build. My concerns are:

  • it's pretty hard to read
  • it might not work with conda-smithy, which is the tool used by conda-forge to render its recipes.

The latter is my bigger concern since conda-forge uses grayskull extensively and has tens of thousands of package. I this would be a problem. I don't know for certain that the syntax you are proposing wouldn't work but I have never seen it before, where as the processing selector syntax is ubiquitous throughout conda-forge. So I would strongly prefer a solution that uses that syntax if one can be devised.

@darynwhite
Copy link

@xylar Thanks for the terminology! I hadn't stumbled my way into that FAQ yet.

If I'm understanding this correctly, then these are equivalent:

  - pillow-heif >=0.10.0,<1.0.0<py312|>=0.13.0,<1.0.0>=py312
  - pillow-heif >=0.10.0,<1.0.0 # py<312
  - pillow-heif >=0.13.0,<1.0.0 # py>=312

And...

I say they are equivalent because I've seen the single-line approach pass the linter and build properly now. The multi-line approach should pass the linter and build properly, based on the documentation I have read and you just shared.

So...

Based on the original issue here, I agree that the multi-line approach is the best. Thus I believe this:

numpy = [
    { version = ">=1.14", python = "<3.11" },
    { version = ">=1.24", python = ">=3.11" }
]

would translate to:

  - numpy >=1.14 # py<311
  - numpy >=1.24 # py>=311

Thanks for the conversation and resources!

@DhanshreeA
Copy link

Hey @xylar, why is it that grayskull has no complaints with a multi constraint dependency specification when they're not from a pyproject.toml using a poetry backend.

So something like this makes grayskull raise an error:

numpy = [
    { version = ">=1.14", python = "<3.11" },
    { version = ">=1.24", python = ">=3.11" }
]

but this does not:

heif = [
    "pillow-heif>=0.10.0,<1.0.0; python_version < '3.12'",
    "pillow-heif>=0.13.0,<1.0.0; python_version >= '3.12'",
]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants