Repository: conda-forge/conda-smithy

Issue:
`AttributeError: 'CommentedMap' object has no attribute 'startswith'` in v2 recipe with conditions in `run` requirements
### Solution to issue cannot be found in the documentation.

- [x] I checked the documentation.

### Issue

When trying to lint my WIP `torchvision-feedstock` port to rattler-build, `conda smithy lint --conda-forge recipe/` crashes:

```pytb
Traceback (most recent call last):
  File "/home/mgorny/miniforge3/bin/conda-smithy", line 10, in <module>
    sys.exit(main())
             ^^^^^^
  File "/home/mgorny/miniforge3/lib/python3.12/site-packages/conda_smithy/cli.py", line 767, in main
    args.subcommand_func(args)
  File "/home/mgorny/miniforge3/lib/python3.12/site-packages/conda_smithy/cli.py", line 645, in __call__
    lints, hints = linter.main(
                   ^^^^^^^^^^^^
  File "/home/mgorny/miniforge3/lib/python3.12/site-packages/conda_smithy/lint_recipe.py", line 727, in main
    results, hints = lintify_meta_yaml(
                     ^^^^^^^^^^^^^^^^^^
  File "/home/mgorny/miniforge3/lib/python3.12/site-packages/conda_smithy/lint_recipe.py", line 385, in lintify_meta_yaml
    lint_stdlib(
  File "/home/mgorny/miniforge3/lib/python3.12/site-packages/conda_smithy/linter/lints.py", line 854, in lint_stdlib
    if any(req.startswith("__osx >") for req in to_check):
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mgorny/miniforge3/lib/python3.12/site-packages/conda_smithy/linter/lints.py", line 854, in <genexpr>
    if any(req.startswith("__osx >") for req in to_check):
           ^^^^^^^^^^^^^^
AttributeError: 'CommentedMap' object has no attribute 'startswith'
```

It seems to crash on the following part of requirements:

```yaml
outputs:
  - package:
      name: torchvision
    requirements:
      run:
        - python
        - pytorch ${{ compatible_pytorch }}.* [build=${{ torch_proc_type }}*]
        - if: cuda_compiler_version != "None"
          then:
            - ${{ pin_compatible('cudnn') }}
```

https://github.com/conda-forge/torchvision-feedstock/blob/39add14ded9c979a012a643c2b6fa7c2230177f6/recipe/recipe.yaml#L154-L156

If I remove the condition at the bottom, it passes.

CC @wolfv 

### Installed packages

```shell
# packages in environment at /home/mgorny/miniforge3:
#
# Name                    Version                   Build  Channel
_libgcc_mutex             0.1                 conda_forge    conda-forge
_openmp_mutex             4.5                       2_gnu    conda-forge
anyio                     4.7.0              pyhd8ed1ab_0    conda-forge
archspec                  0.2.3              pyhd8ed1ab_0    conda-forge
attrs                     24.3.0             pyh71513ae_0    conda-forge
backports                 1.0                pyhd8ed1ab_5    conda-forge
backports.strenum         1.2.8              pyhd8ed1ab_0    conda-forge
backports.tarfile         1.2.0              pyhd8ed1ab_1    conda-forge
beautifulsoup4            4.12.3             pyha770c72_1    conda-forge
blinker                   1.9.0              pyhff2d567_0    conda-forge
boltons                   24.0.0             pyhd8ed1ab_1    conda-forge
boolean.py                4.0                pyhd8ed1ab_1    conda-forge
brotli-python             1.1.0           py312h2ec8cdc_2    conda-forge
bzip2                     1.0.8                h4bc722e_7    conda-forge
c-ares                    1.34.4               hb9d3cd8_0    conda-forge
ca-certificates           2024.12.14           hbcca054_0    conda-forge
certifi                   2024.12.14         pyhd8ed1ab_0    conda-forge
cffi                      1.17.1          py312h06ac9bb_0    conda-forge
chardet                   5.2.0           py312h7900ff3_2    conda-forge
charset-normalizer        3.4.0              pyhd8ed1ab_1    conda-forge
cirun                     0.30               pyhd8ed1ab_0    conda-forge
click                     8.1.8              pyh707e725_0    conda-forge
colorama                  0.4.6              pyhd8ed1ab_1    conda-forge
conda                     24.11.2         py312h7900ff3_0    conda-forge
conda-build               24.11.2         py312h7900ff3_1    conda-forge
conda-forge-pinning       2024.12.24.08.00.50      hd8ed1ab_0    conda-forge
conda-index               0.5.0              pyhd8ed1ab_0    conda-forge
conda-libmamba-solver     24.11.1            pyhd8ed1ab_0    conda-forge
conda-package-handling    2.4.0              pyha770c72_1    conda-forge
conda-package-streaming   0.11.0             pyhd8ed1ab_0    conda-forge
conda-smithy              3.45.1          unix_pyhd81877a_0    conda-forge
conda-souschef            2.2.3              pyhd8ed1ab_0    conda-forge
cpp-expected              1.1.0                hf52228f_0    conda-forge
cryptography              44.0.0          py312hda17c39_0    conda-forge
dbus                      1.13.6               h5008d03_3    conda-forge
deprecated                1.2.15             pyhd8ed1ab_1    conda-forge
distlib                   0.3.9              pyhd8ed1ab_1    conda-forge
distro                    1.9.0              pyhd8ed1ab_1    conda-forge
editables                 0.5                pyhd8ed1ab_1    conda-forge
exceptiongroup            1.2.2              pyhd8ed1ab_1    conda-forge
expat                     2.6.4                h5888daf_0    conda-forge
filelock                  3.16.1             pyhd8ed1ab_1    conda-forge
fmt                       11.0.2               h434a139_0    conda-forge
frozendict                2.4.6           py312h66e93f0_0    conda-forge
git                       2.47.1          pl5321h59d505e_0    conda-forge
gitdb                     4.0.11             pyhd8ed1ab_1    conda-forge
gitpython                 3.1.43             pyhff2d567_1    conda-forge
gmp                       6.3.0                hac33072_2    conda-forge
h11                       0.14.0             pyhd8ed1ab_1    conda-forge
h2                        4.1.0              pyhd8ed1ab_1    conda-forge
hatch                     1.14.0             pyhd8ed1ab_1    conda-forge
hatchling                 1.27.0           pypyhd8ed1ab_0    conda-forge
hpack                     4.0.0              pyhd8ed1ab_1    conda-forge
httpcore                  1.0.7              pyh29332c3_1    conda-forge
httpx                     0.28.1             pyhd8ed1ab_0    conda-forge
hyperframe                6.0.1              pyhd8ed1ab_1    conda-forge
hyperlink                 21.0.0             pyh29332c3_1    conda-forge
idna                      3.10               pyhd8ed1ab_1    conda-forge
importlib-metadata        8.5.0              pyha770c72_1    conda-forge
importlib_resources       6.4.5              pyhd8ed1ab_1    conda-forge
isodate                   0.7.2              pyhd8ed1ab_1    conda-forge
jaraco.classes            3.4.0              pyhd8ed1ab_2    conda-forge
jaraco.context            6.0.1              pyhd8ed1ab_0    conda-forge
jaraco.functools          4.1.0              pyhd8ed1ab_0    conda-forge
jeepney                   0.8.0              pyhd8ed1ab_0    conda-forge
jinja2                    3.1.5              pyhd8ed1ab_0    conda-forge
jsonpatch                 1.33               pyhd8ed1ab_1    conda-forge
jsonpointer               3.0.0           py312h7900ff3_1    conda-forge
jsonschema                4.23.0             pyhd8ed1ab_1    conda-forge
jsonschema-specifications 2024.10.1          pyhd8ed1ab_1    conda-forge
keyring                   25.5.0             pyha804496_1    conda-forge
keyutils                  1.6.1                h166bdaf_0    conda-forge
krb5                      1.21.3               h659f571_0    conda-forge
ld_impl_linux-64          2.43                 h712a8e2_2    conda-forge
libarchive                3.7.7                h4585015_3    conda-forge
libcurl                   8.11.1               h332b0f4_0    conda-forge
libedit                   3.1.20191231         he28a2e2_2    conda-forge
libev                     4.33                 hd590300_2    conda-forge
libexpat                  2.6.4                h5888daf_0    conda-forge
libffi                    3.4.2                h7f98852_5    conda-forge
libgcc                    14.2.0               h77fa898_1    conda-forge
libgcc-ng                 14.2.0               h69a702a_1    conda-forge
libgit2                   1.8.4                hd24f944_1    conda-forge
libglib                   2.82.2               h2ff4ddf_0    conda-forge
libgomp                   14.2.0               h77fa898_1    conda-forge
libiconv                  1.17                 hd590300_2    conda-forge
liblief                   0.14.1               h5888daf_2    conda-forge
liblzma                   5.6.3                hb9d3cd8_1    conda-forge
libmamba                  2.0.5                hf72d635_0    conda-forge
libmambapy                2.0.5           py312hf3f0a4e_0    conda-forge
libnghttp2                1.64.0               h161d5f1_0    conda-forge
libnsl                    2.0.1                hd590300_0    conda-forge
libsodium                 1.0.20               h4ab18f5_0    conda-forge
libsolv                   0.7.30               h3509ff9_0    conda-forge
libsqlite                 3.47.2               hee588c1_0    conda-forge
libssh2                   1.11.1               hf672d98_0    conda-forge
libstdcxx                 14.2.0               hc0a3c3a_1    conda-forge
libstdcxx-ng              14.2.0               h4852527_1    conda-forge
libuuid                   2.38.1               h0b41bf4_0    conda-forge
libxcrypt                 4.4.36               hd590300_1    conda-forge
libxml2                   2.13.5               h0d44e9d_1    conda-forge
libzlib                   1.3.1                hb9d3cd8_2    conda-forge
license-expression        30.3.1             pyhd8ed1ab_0    conda-forge
lz4-c                     1.10.0               h5888daf_1    conda-forge
lzo                       2.10              hd590300_1001    conda-forge
mamba                     2.0.5                hfdd0a45_0    conda-forge
markdown-it-py            3.0.0              pyhd8ed1ab_1    conda-forge
markupsafe                3.0.2           py312h178313f_1    conda-forge
mdurl                     0.1.2              pyhd8ed1ab_1    conda-forge
menuinst                  2.2.0           py312h7900ff3_0    conda-forge
more-itertools            10.5.0             pyhd8ed1ab_1    conda-forge
msrest                    0.6.21             pyh44b312d_0    conda-forge
ncurses                   6.5                  he02047a_1    conda-forge
nlohmann_json             3.11.3               he02047a_1    conda-forge
oauthlib                  3.2.2              pyhd8ed1ab_1    conda-forge
openssl                   3.4.0                hb9d3cd8_0    conda-forge
packaging                 24.2               pyhd8ed1ab_2    conda-forge
patch                     2.7.6             h7f98852_1002    conda-forge
patchelf                  0.17.2               h58526e2_0    conda-forge
pathspec                  0.12.1             pyhd8ed1ab_1    conda-forge
pcre2                     10.44                hba22ea6_2    conda-forge
perl                      5.32.1          7_hd590300_perl5    conda-forge
pexpect                   4.9.0              pyhd8ed1ab_1    conda-forge
pip                       24.3.1             pyh8b19718_2    conda-forge
pkginfo                   1.12.0             pyhd8ed1ab_1    conda-forge
pkgutil-resolve-name      1.3.10             pyhd8ed1ab_2    conda-forge
platformdirs              4.3.6              pyhd8ed1ab_1    conda-forge
pluggy                    1.5.0              pyhd8ed1ab_1    conda-forge
psutil                    6.1.0           py312h66e93f0_0    conda-forge
ptyprocess                0.7.0              pyhd8ed1ab_1    conda-forge
py-lief                   0.14.1          py312h2ec8cdc_2    conda-forge
pybind11-abi              4                    hd8ed1ab_3    conda-forge
pycosat                   0.6.6           py312h66e93f0_2    conda-forge
pycparser                 2.22               pyh29332c3_1    conda-forge
pycryptodome              3.21.0          py312h6368725_0    conda-forge
pygit2                    1.16.0          py312h66e93f0_0    conda-forge
pygithub                  2.5.0              pyhd8ed1ab_0    conda-forge
pygments                  2.18.0             pyhd8ed1ab_1    conda-forge
pyjwt                     2.10.1             pyhd8ed1ab_0    conda-forge
pynacl                    1.5.0           py312h66e93f0_4    conda-forge
pysocks                   1.7.1              pyha55dd90_7    conda-forge
python                    3.12.8          h9e4cc4f_1_cpython    conda-forge
python-dateutil           2.9.0.post0        pyhff2d567_1    conda-forge
python-libarchive-c       5.1             py312h7900ff3_1    conda-forge
python_abi                3.12                    5_cp312    conda-forge
pytz                      2024.2             pyhd8ed1ab_1    conda-forge
pyyaml                    6.0.2           py312h66e93f0_1    conda-forge
rattler-build             0.33.1               hbcf9e9b_0    conda-forge
rattler-build-conda-compat 1.2.2              pyhd8ed1ab_0    conda-forge
readline                  8.2                  h8228510_1    conda-forge
referencing               0.35.1             pyhd8ed1ab_1    conda-forge
reproc                    14.2.5.post0         hb9d3cd8_0    conda-forge
reproc-cpp                14.2.5.post0         h5888daf_0    conda-forge
requests                  2.32.3             pyhd8ed1ab_1    conda-forge
requests-oauthlib         2.0.0              pyhd8ed1ab_1    conda-forge
rich                      13.9.4             pyhd8ed1ab_1    conda-forge
ripgrep                   14.1.1               h8fae777_0    conda-forge
rpds-py                   0.22.3          py312h12e396e_0    conda-forge
ruamel.yaml               0.18.6          py312h66e93f0_1    conda-forge
ruamel.yaml.clib          0.2.8           py312h66e93f0_1    conda-forge
ruamel.yaml.jinja2        0.2.7              pyhd8ed1ab_1    conda-forge
scrypt                    0.8.27          py312h2214df5_0    conda-forge
secretstorage             3.3.3           py312h7900ff3_3    conda-forge
setuptools                75.6.0             pyhff2d567_1    conda-forge
shellingham               1.5.4              pyhd8ed1ab_1    conda-forge
simdjson                  3.11.3               h84d6215_0    conda-forge
six                       1.17.0             pyhd8ed1ab_0    conda-forge
smmap                     5.0.0              pyhd8ed1ab_0    conda-forge
sniffio                   1.3.1              pyhd8ed1ab_1    conda-forge
soupsieve                 2.5                pyhd8ed1ab_1    conda-forge
spdlog                    1.14.1               hed91bc2_1    conda-forge
tk                        8.6.13          noxft_h4845f30_101    conda-forge
tomli                     2.2.1              pyhd8ed1ab_1    conda-forge
tomli-w                   1.1.0              pyhd8ed1ab_1    conda-forge
tomlkit                   0.13.2             pyha770c72_1    conda-forge
toolz                     1.0.0              pyhd8ed1ab_1    conda-forge
tqdm                      4.67.1             pyhd8ed1ab_0    conda-forge
trove-classifiers         2024.10.21.16      pyhd8ed1ab_1    conda-forge
truststore                0.10.0             pyhd8ed1ab_0    conda-forge
typer                     0.15.1             pyhd8ed1ab_0    conda-forge
typer-slim                0.15.1             pyhd8ed1ab_0    conda-forge
typer-slim-standard       0.15.1               hd8ed1ab_0    conda-forge
typing-extensions         4.12.2               hd8ed1ab_1    conda-forge
typing_extensions         4.12.2             pyha770c72_1    conda-forge
tzdata                    2024b                hc8b5060_0    conda-forge
urllib3                   2.3.0              pyhd8ed1ab_0    conda-forge
userpath                  1.7.0              pyhd8ed1ab_0    conda-forge
uv                        0.5.11               h0f3a69f_0    conda-forge
virtualenv                20.28.0            pyhd8ed1ab_0    conda-forge
vsts-python-api           0.1.25             pyhd8ed1ab_1    conda-forge
wheel                     0.45.1             pyhd8ed1ab_1    conda-forge
wrapt                     1.17.0          py312h66e93f0_0    conda-forge
yaml                      0.2.5                h7f98852_2    conda-forge
yaml-cpp                  0.8.0                h59595ed_0    conda-forge
zipp                      3.21.0             pyhd8ed1ab_1    conda-forge
zstandard                 0.23.0          py312hef9b889_1    conda-forge
zstd                      1.5.6                ha6fb4c9_0    conda-forge
```

### Environment info

```shell
active environment : base
    active env location : /home/mgorny/miniforge3
            shell level : 1
       user config file : /home/mgorny/.condarc
 populated config files : /home/mgorny/miniforge3/.condarc
                          /home/mgorny/.condarc
          conda version : 24.11.2
    conda-build version : 24.11.2
         python version : 3.12.8.final.0
                 solver : libmamba (default)
       virtual packages : __archspec=1=zen2
                          __conda=24.11.2=0
                          __cuda=12.6=0
                          __glibc=2.40=0
                          __linux=6.12.6=0
                          __unix=0=0
       base environment : /home/mgorny/miniforge3  (writable)
      conda av data dir : /home/mgorny/miniforge3/etc/conda
  conda av metadata url : None
           channel URLs : https://mgorny.github.io/conda-channel/mgorny/linux-64
                          https://mgorny.github.io/conda-channel/mgorny/noarch
                          https://conda.anaconda.org/conda-forge/linux-64
                          https://conda.anaconda.org/conda-forge/noarch
          package cache : /home/mgorny/miniforge3/pkgs
                          /home/mgorny/.conda/pkgs
       envs directories : /home/mgorny/miniforge3/envs
                          /home/mgorny/.conda/envs
               platform : linux-64
             user-agent : conda/24.11.2 requests/2.32.3 CPython/3.12.8 Linux/6.12.6-gentoo-dist gentoo/2.17 glibc/2.40 solver/libmamba conda-libmamba-solver/24.11.1 libmambapy/2.0.5
                UID:GID : 1000:1000
             netrc file : None
           offline mode : False
```

Discussion:
mgorny: CC @wolfv 

Patch:
diff --git a/conda_smithy/linter/lints.py b/conda_smithy/linter/lints.py
index 1a12485e..f961edd9 100644
--- a/conda_smithy/linter/lints.py
+++ b/conda_smithy/linter/lints.py
@@ -813,6 +813,8 @@ def lint_stdlib(
     if recipe_version == 1:
         all_build_reqs = [flatten_v1_if_else(reqs) for reqs in all_build_reqs]
         all_build_reqs_flat = flatten_v1_if_else(all_build_reqs_flat)
+        all_run_reqs_flat = flatten_v1_if_else(all_run_reqs_flat)
+        all_contraints_flat = flatten_v1_if_else(all_contraints_flat)
 
     # this check needs to be done per output --> use separate (unflattened) requirements
     for build_reqs in all_build_reqs:
diff --git a/conda_smithy/linter/utils.py b/conda_smithy/linter/utils.py
index 281d43c0..9745b48b 100644
--- a/conda_smithy/linter/utils.py
+++ b/conda_smithy/linter/utils.py
@@ -236,8 +236,10 @@ def flatten_v1_if_else(requirements: list[str | dict]) -> list[str]:
     flattened_requirements = []
     for req in requirements:
         if isinstance(req, dict):
-            flattened_requirements.extend(req["then"])
-            flattened_requirements.extend(req.get("else") or [])
+            flattened_requirements.extend(flatten_v1_if_else(req["then"]))
+            flattened_requirements.extend(
+                flatten_v1_if_else(req.get("else") or [])
+            )
         else:
             flattened_requirements.append(req)
     return flattened_requirements
diff --git a/news/fix-if-else-in-run.rst b/news/fix-if-else-in-run.rst
new file mode 100644
index 00000000..b47bab21
--- /dev/null
+++ b/news/fix-if-else-in-run.rst
@@ -0,0 +1,24 @@
+**Added:**
+
+* <news item>
+
+**Changed:**
+
+* <news item>
+
+**Deprecated:**
+
+* <news item>
+
+**Removed:**
+
+* <news item>
+
+**Fixed:**
+
+* Fix handling ``if``/``else`` blocks in ``run`` and ``run_constraints`` requirements, for v1 recipes (#2197)
+* Fix flattening nested ``if``/``else`` blocks in v1 recipes (#2197)
+
+**Security:**
+
+* <news item>


Test patch:
diff --git a/tests/recipes/v1_recipes/torchvision.yaml b/tests/recipes/v1_recipes/torchvision.yaml
new file mode 100644
index 00000000..0f943464
--- /dev/null
+++ b/tests/recipes/v1_recipes/torchvision.yaml
@@ -0,0 +1,227 @@
+context:
+  version: 0.20.1
+  build_number: 2
+  # see github.com/conda-forge/conda-forge.github.io/issues/1059 for naming discussion
+  # torchvision requires that CUDA major and minor versions match with pytorch
+  # https://github.com/pytorch/vision/blob/fa99a5360fbcd1683311d57a76fcc0e7323a4c1e/torchvision/extension.py#L79C1-L85C1
+  torch_proc_type: ${{ "cuda" ~ cuda_compiler_version | version_to_buildstring if cuda_compiler_version != "None" else "cpu" }}
+  # Upstream has specific compatability ranges for pytorch and python which are
+  # updated every 0.x release. https://github.com/pytorch/vision#installation
+  compatible_pytorch: 2.5
+
+  tests_to_skip: >
+    ${{ 'skip test_url_is_accessible instead of hitting 20+ servers per run, since' if 0 }}
+    ${{ 'each server might be occasionally unresponsive and end up failing our CI' if 0 }}
+    test_url_is_accessible
+    ${{ 'spurious failure because upstream skip (Image.__version__ >= "7") does not trigger for Pillow "10"' if 0 }}
+    or (test_transforms and test_adjust_saturation)
+    ${{ 'osx warns with nnpack if there is no AVX2, see conda-forge/pytorch-cpu-feedstock#56' if 0 }}
+    ${{ "or test_adjust_sharpness" if osx }}
+    ${{ '2021/10/28 hmaarrfk: I am able to run it locally on a large machine.' if 0 }}
+    ${{ 'It seems to fail around testing of vgg' if 0 }}
+    ${{ 'This test seems to just destroy the memory of the system.' if 0 }}
+    or test_forward_backward
+    or test_jit_forward_backward
+    ${{ '2022/01/21 hmaarrfk (test_frame_reading)' if 0 }}
+    ${{ 'They indicate that there can be a 1% error in their test.' if 0 }}
+    ${{ 'However, this test seems to causing the CIs to fail when this' if 0 }}
+    ${{ 'case is hit. For example the last CI failed with' if 0 }}
+    ${{ '>                   assert mean_delta.item() < 2.5' if 0 }}
+    ${{ 'E                   assert 2.502098560333252 < 2.5' if 0 }}
+    or test_frame_reading
+    ${{ 'Random perspective tests can fail if the perspective is too sharp' if 0 }}
+    ${{ 'https://github.com/conda-forge/torchvision-feedstock/issues/38' if 0 }}
+    or test_randomperspective_fill
+    ${{ 'Tolerance on the test_frozenbatchnorm2d_eps test seems to be too strict' if 0 }}
+    or test_frozenbatchnorm2d_eps
+    or test_random_apply
+    ${{ '2022/03/29 hmaarrfk' if 0 }}
+    ${{ 'It seems that this test can cause segmentation faults on the CIs.' if 0 }}
+    or test_write_video_with_audio
+    or test_video_clips_custom_fps
+    ${{ '2022/07 hmaarrfk really large memory tests. Fail on CIs' if 0 }}
+    or test_memory_efficient_densenet
+    or test_resnet_dilation
+    or test_mobilenet_v2_residual_setting
+    or test_mobilenet_norm_layer
+    or test_inception_v3_eval
+    or test_fasterrcnn_double
+    or test_googlenet_eval
+    or test_fasterrcnn_switch_devices
+    or test_mobilenet_v2_residual_setting
+    or test_vitc_models
+    or test_classification_model
+    or test_segmentation_model
+    or test_detection_model
+    or test_detection_model_validation
+    or test_video_model
+    or test_quantized_classification_model
+    or test_detection_model_trainable_backbone_layers
+    or test_raft
+    or test_build_fx_feature_extractor
+    ${{ "2023/01 These tests fail on newer numpy with module 'numpy' has no attribute 'int'" if 0 }}
+    or test_transformation_range
+    or test_transformation_discrete
+    ${{ '2023/05 The gaussian blur tests are known to be flaky due to some non-determinism on CUDA (see pytorch/vision#6755)' if 0 }}
+    or test_batched_vs_single
+    ${{ '2023/11 Draw boxes test broken by pillow 1.10.0, but is non-critical and the test is patched upstream (pytorch/vision#8051)' if 0 }}
+    or test_draw_boxes
+    ${{ '2024/02 These tests assert warnings and in PyTorch 2.1.2 the number of warnings increased' if 0 }}
+    ${{ 'causing them to fail' if 0 }}
+    or test_pretrained_pos or test_equivalent_behavior_weights
+    ${{ '2024/12 These tests use Internet' if 0 }}
+    or test_decode_gif or test_download_url or "test_get_model[lraspp"
+
+recipe:
+  name: torchvision
+  version: ${{ version }}
+
+source:
+  url: https://github.com/pytorch/vision/archive/refs/tags/v${{ version }}.tar.gz
+  sha256: 7e08c7f56e2c89859310e53d898f72bccc4987cd83e08cfd6303513da15a9e71
+  patches:
+    # Our newer conda-forge clang compilers complain about this for OSX
+    # https://github.com/pytorch/vision/pull/8406/files#r1730151047
+    - patches/0001-Use-system-giflib.patch
+    - patches/0002-Force-nvjpeg-and-force-failure.patch
+    # 2024/08 hmaarrfk
+    # known flaky test https://github.com/pytorch/vision/blob/9e78fe29e0851b10eb8fba0b88cc521ad67cf322/test/test_image.py#L840
+    - patches/0003-Skip-OSS-CI-in-conda-forge-as-well.patch
+    # Can likely remove after 0.20.1
+    # https://github.com/pytorch/vision/pull/8776
+    - patches/8776_compatibility_with_pyav_14.patch
+
+build:
+  number: ${{ build_number }}
+  string: ${{ torch_proc_type }}_py${{ python | version_to_buildstring }}_h${{ hash }}_${{ build_number }}
+  # CUDA < 12 not supported by pytorch anymore
+  skip: cuda_compiler_version == "11.8" or win
+
+outputs:
+  - package:
+      name: torchvision
+    build:
+      script:
+        env:
+          BUILD_VERSION: ${{ version }}
+    requirements:
+      build:
+        - ${{ stdlib('c') }}
+        - ${{ compiler('c') }}
+        - ${{ compiler('cxx') }}
+        - if: cuda_compiler_version != "None"
+          then:
+            - ${{ compiler('cuda') }}
+        # avoid nested conditions because of
+        # https://github.com/conda-forge/conda-smithy/issues/2165
+        - if: build_platform != target_platform
+          then:
+            - python
+            - cross-python_${{ target_platform }}
+            # - numpy
+            - pytorch ${{ compatible_pytorch }}.* [build=${{ torch_proc_type }}*]
+            - if: cuda_compiler_version != "None"
+              then:
+                - libcublas-dev
+                - libcusolver-dev
+                - libcusparse-dev
+                - libnvjpeg-dev
+      host:
+        - python
+        # - numpy
+        - pip
+        - setuptools
+        - if: cuda_compiler_version != "None"
+          then:
+            - cudnn
+            - libcublas-dev
+            - libcusolver-dev
+            - libcusparse-dev
+            - libnvjpeg-dev
+        - libjpeg-turbo
+        - libpng
+        - libwebp
+        # https://github.com/pytorch/vision/pull/8406/files#r1730151047
+        - giflib
+        # Specify lgpl version of ffmpeg so that there are
+        # no quesitons about the license of the resulting binary
+        # hmaarrfk: 2022/07, I think that torchvision just has bugs with ffmpeg
+        # - ffmpeg {{ ffmpeg }} [build=lgpl_*]
+        # exclude 8.3.0 and 8.3.1 specifically due to pytorch/vision#4146, python-pillow/Pillow#5571
+        - pillow >=5.3.0,!=8.3.0,!=8.3.1
+        - libtorch ${{ compatible_pytorch }}.* [build=${{ torch_proc_type }}*]
+        - pytorch ${{ compatible_pytorch }}.* [build=${{ torch_proc_type }}*]
+        - requests
+      run:
+        - python
+        - pytorch ${{ compatible_pytorch }}.* [build=${{ torch_proc_type }}*]
+        - if: cuda_compiler_version != "None"
+          then:
+            - ${{ pin_compatible('cudnn') }}
+        - pillow >=5.3.0,!=8.3.0,!=8.3.1
+        # They don't really document it, but it seems that they want a minimum version
+        # https://github.com/pytorch/vision/blob/v0.19.0/packaging/torchvision/meta.yaml#L26
+        - numpy >=1.23.5
+        # While their conda package depends on requests, it seems it is only used for some test
+        # scripts and not the runtime
+        # - requests
+    tests:
+      - python:
+          imports:
+            - torchvision
+            - torchvision.datasets
+            - torchvision.models
+            - torchvision.transforms
+            - torchvision.utils
+          pip_check: true
+      - requirements:
+          run:
+            - pip
+        script:
+          - pip list
+          - if: unix
+            then: pip list | grep torchvision | grep ${{ version }}
+
+  - package:
+      name: torchvision-tests
+    build:
+      script: true
+    requirements:
+      run:
+        - ${{ pin_subpackage('torchvision', exact=True) }}
+    tests:
+      - files:
+          source:
+            - test/
+            - references/
+            - pytest.ini
+        requirements:
+          run:
+            - pytest
+            - requests
+            - av
+            - expecttest
+            - scipy
+            - pytest-mock
+            - pytest-socket
+        script:
+          - if: not aarch64
+            then: pytest --disable-socket --verbose -k "not (${{ tests_to_skip }})" --durations=50 test/
+          - if: aarch64 and (build_platform == target_platform)
+            then: pytest --disable-socket -k "not (${{ tests_to_skip }})" --durations=50 test/
+          - if: aarch64 and (build_platform != target_platform)
+            then: true
+
+about:
+  license: BSD-3-Clause
+  license_file: LICENSE
+  summary: Image and video datasets and models for torch deep learning
+  homepage: http://pytorch.org/
+  repository: https://github.com/pytorch/vision
+
+extra:
+  recipe-maintainers:
+    - nehaljwani
+    - hmaarrfk
+    - h-vetinari
+  feedstock-name: torchvision
diff --git a/tests/test_lint_recipe.py b/tests/test_lint_recipe.py
index d1309819..30901c71 100644
--- a/tests/test_lint_recipe.py
+++ b/tests/test_lint_recipe.py
@@ -2758,6 +2758,10 @@ def test_v1_recipes():
         lints, hints = linter.main(str(recipe_dir), return_hints=True)
         assert not lints
 
+    with get_recipe_in_dir("v1_recipes/torchvision.yaml") as recipe_dir:
+        lints, hints = linter.main(str(recipe_dir), return_hints=True)
+        assert not lints
+
     with get_recipe_in_dir("v1_recipes/ada-url.yaml") as recipe_dir:
         lints, hints = linter.main(str(recipe_dir), return_hints=True)
         assert not lints