conda-forge / conda-forge/conda-forge.github.io
"conda skeleton pypi" Meta-Mega-Issue
- Ngôn ngữ chính
- JavaScript
- Star
- 170
- Fork
- 320
- Merge trung bình
- 2 ngày 10 giờ
- Pull request đã merge (30 ngày)
- 5
Mô tả
Per @CJ-Wright's [sagacious advice](https://github.com/conda-forge/staged-recipes/pull/5574#issuecomment-381300150) at [my first conda-forge recipe](https://github.com/conda-forge/staged-recipes/pull/5574), this large-scale issue collects various interrelated ~~critiques~~ concerns of current documentation on the `conda skeleton pypi` command.
## Isn't All of This conda-build's Fault?
*Maybe.* Because of that likelihood, @CJ-Wright wisely suggested I open this issue at [the core `conda-build` tracker](https://github.com/conda/conda-build/issues) instead.
I unwisely ignored this suggestion. It's not necessarily clear to me that anything is explicitly broken *or* in need of immediate repair in the `conda skeleton pypi` command. Moreover, unconditionally rewriting the output produced by that command in the manner detailed below could be a Bad Thing™ in edge cases that I (as a sleep-deprived cottage neckbeard) am unaware of. Certainly, rewriting the `requirements/host:` list into a `requirements/build:` list would *definitely* be a Bad Thing™ in the general case of conda-build 3 support.
Many of the concerns listed below are probably specific to conda-forge. So, I don't know. I'm dumping them here – but sympathize with @CJ-Wright's preferred solution of improving the `conda skeleton pypi` command itself. Maybe we can do both? That is, maybe we can both improve conda-forge documentation (*which seems like low-hanging fruit*) and also improve `conda skeleton pypi` (*which really doesn't*).
Here we go, folks. Thanks again to @carlodri, @CJ-Wright, and @jakirkham for their tireless efforts.
## How Bad Could "conda skeleton pypi" Documentation Be, Anyway?
**Pretty bad,** frankly. The [conda-forge documentation](https://conda-forge.org/docs/recipe.html#getting-started) on this command is scant at best:
> If it is a python package you can generate a skeleton as a starting point with `conda skeleton pypi your_package_name`. You do not have to use skeleton, and **the recipes produced by skeleton will need to be edited.**
That latter constraint should *definitely* be emphasized, ideally by linking to a new subsection of the existing [*Writing the `meta.yaml`*](https://conda-forge.org/docs/meta.html#writing-the-meta-yaml) section – titled, say, "Autogenerating the `meta.yaml` from PyPI." This subsection should explicitly list *all* of the changes that a user must manually make to the `meta.yaml` file autogenerated by the `conda skeleton pypi {package_name}` command. To my painfully limited knowledge, these are:
### Inlining Extraneous Jinja2 Variables
```
# Rewriting this...
{% set file_ext = "tar.gz" %}
{% set hash_type = "sha256" %}
{% set hash_value = "..." %}
package:
name: '{{ name|lower }}'
version: '{{ version }}'
source:
fn: '{{ name }}-{{ version }}.{{ file_ext }}'
url: https://pypi.io/packages/source/{{ name[0] }}/{{ name }}/{{ name }}-{{ version }}.{{ file_ext }}
'{{ hash_type }}': '{{ hash_value }}'
# ...into this.
{% set sha256 = "..." %}
package:
name: {{ name|lower }}
version: {{ version }}
source:
fn: {{ name }}-{{ version }}.tar.gz
url: https://pypi.io/packages/source/{{ name[0] }}/{{ name }}/{{ name }}-{{ version }}.tar.gz
sha256: {{ sha256 }}
```
Obviously, `conda skeleton pypi` could be improved to do this – but should it be? *Someone* thought those extraneous Jinja2 variables and protective single-quoted strings were a good idea. Perhaps they were right. Perhaps they were horrifyingly wrong and will be called to atone in their next life as a conda-forge developer.
I just do not know.
### Disabling Features Specific to conda-build 3
```
# Rewriting this...
requirements:
host:
...
# ...into this.
requirements:
build:
- pip
...
```
**Right.** `conda skeleton pypi` should *never* be improved to do that. Well, the `- pip` addition isn't necessarily a bad idea... subject to the discussion under the next point, anyway.
### Building with `pip` Rather Than `setuptools`
```
# Rewriting this...
build:
...
script: python setup.py install --single-version-externally-managed --record=record.txt
# into this.
build:
...
script: python -m pip install --no-deps --ignore-installed .
```
This is probably something that `conda skeleton pypi` should also be improved to do. That said, doing so *would* add `pip` as an additional build-time dependency to all newly generated packages. That said, `pip` should typically be available at build-time under all build environments, anyway. That said, perhaps there are build environments for which this is *not* the case. That said, did I mention that I live in a cottage in the Canadian wilderness? :bear:
### Explicitly Listing a License File
```
# Rewriting this...
about:
license_file: ''
# ...into this, where {license_file} is the relative filename of this project's license relative to the project root.
about:
license_file: {license_file}
```
Sadly, this isn't something that `conda skeleton pypi` can reasonably automate. In theory, `conda` *could* introspect into the source tarball that it fetches from PyPI for a top-level file whose basename matches a trivial heuristic (e.g., `^LICENSE(?:\\..*)$'). In practice, it's *not* necessarily the case that each file matching that heuristic is actually a license file. Additionally, how would one handle edge cases such as the existence of multiple files matching that heuristic?
In short, this is probably better left to the end user. The manual way is often the good way. *"Explicit is better than implicit" or something, something.*
### Explicitly Listing Yourself as the Recipe Mainter
```
# Rewriting this...
extra:
recipe-maintainers: ''
# ...into this, where {github_username} is... your github username.
extra:
recipe-maintainers:
- {github_username}
```
Again, this isn't something that `conda skeleton pypi` can reasonably automate – not without web-crawling the `url` option passed to the `setuptools.setup()` function in `setup.py`, anyway.
### Reducing Duplication in Runtime Requirements
Lastly, it might be helpful to note that all duplicate runtime requirements *except* Python and setuptools should typically be removed from the `requirements/build:` list: e.g.,
```
# Rewriting this...
requirements:
build:
- pip
- python
- setuptools >=3.3
- numpy >=1.8.2
- pillow >=2.3.0
- scipy >=0.12.0
- dill >=0.2.3
- matplotlib >=1.5.0
- six >=1.5.2
- pyyaml >=3.10
run:
- python
- setuptools >=3.3
- numpy >=1.8.2
- pillow >=2.3.0
- scipy >=0.12.0
- dill >=0.2.3
- matplotlib >=1.5.0
- six >=1.5.2
- pyyaml >=3.10
# ...into this.
requirements:
build:
- pip
- python
- setuptools >=3.3
run:
- python
- setuptools >=3.3
- numpy >=1.8.2
- pillow >=2.3.0
- scipy >=0.12.0
- dill >=0.2.3
- matplotlib >=1.5.0
- six >=1.5.2
- pyyaml >=3.10
```
While this *is* something that `conda skeleton pypi` could reasonably automate, I'm unclear what the real-world consequences of doing so might be. After all, `conda` itself has no deterministic means of differentiating build-time requirements from runtime requirements. The `install_requires` option passed to the `setuptools.setup()` function in `setup.py` fails to differentiate between the two, which... is actually kind of insane, now that I think about it.
Maybe? Or is it actually the case that *all* dependencies listed by `install_requires` are indeed only runtime requirements? If True, then: "Yes, `conda skeleton pypi` probably should automate that."
Setuptools, I hate you yet again.
## Just End It Already
Most of the above could probably be automated with a really hacky regex-based script of some sort runnable on user machines, which would post-process the `meta.yaml` file produced by `conda skeleton pypi` into a format consumable by conda-forge. Since nobody (*including me*) wants to write that script, publishing something resembling the above instructions might be the next best thing.
Let the end user deal with it, I say. Let them eat cake and cackle madly as they do so.
Hướng dẫn đóng góp
Đánh giá
Issue này chưa được đánh giá.