conda / conda-build

Commands and tools for building conda packages
https://docs.conda.io/projects/conda-build/
Other
373 stars 415 forks source link

meta.yaml’s `build.entry_points` has the wrong name #4234

Open flying-sheep opened 3 years ago

flying-sheep commented 3 years ago

Actual Behavior

In meta.yaml, one is expected to specify console scripts as build.entry_points: https://docs.conda.io/projects/conda-build/en/latest/resources/define-metadata.html#python-entry-points

Expected Behavior

The key should be called build.scripts or build.entry_points.console_scripts or similar, as console scripts are one type of entry point.

In PEP 621, the table for generic entry points is [project.entry-points], with [project.scripts] and [project.gui-scripts] providing shortcuts for what would otherwise be called [project.entry-points.console_scripts] and [project.entry-points.gui_scripts].

Impact

The python packaging ecosystem is complex enough. We should strive to use the correct names for abstractions to help people understand what’s going on.

marscher commented 1 year ago

In my opinion, this design choice is a blocker for all generic entry points. For instance ASDF (advanced scientific data format) declares user data defintions as entry points. Strangely this works, if the entry points are declared via setup.cfg, but not via pyproject.toml

This is the example from https://setuptools.pypa.io/en/latest/userguide/entry_point.html

[project.entry-points."timmins.display"]
excl = "timmins_plugin_fancy:excl_display"
lined = "timmins_plugin_fancy:lined_display"

with a recipe snippet like this:

{% set pyproject = load_file_data("../../pyproject.toml", from_recipe_dir=True)  %}
{% set proj = pyproject.get('project') %}
  # ...
  entry_points:
  {% for e in proj.get('entry-points') %}
    - {{ e }}
  {% endfor %}

leads to the following exception:

failed to create env, retrying.  exception was: not enough values to unpack (expected 2, got 1)
WARNING:conda_build.environ:failed to create env, retrying.  exception was: not enough values to unpack (expected 2, got 1)
Traceback (most recent call last):
  File "/home/marscher/miniconda3/lib/python3.10/site-packages/conda_build/environ.py", line 910, in create_env
    execute_actions(actions, index)
  File "/home/marscher/miniconda3/lib/python3.10/site-packages/conda/common/io.py", line 86, in decorated
    return f(*args, **kwds)
  File "/home/marscher/miniconda3/lib/python3.10/site-packages/conda/plan.py", line 320, in execute_actions
    execute_instructions(plan, index, verbose)
  File "/home/marscher/miniconda3/lib/python3.10/site-packages/conda/plan.py", line 532, in execute_instructions
    cmd(state, arg)
  File "/home/marscher/miniconda3/lib/python3.10/site-packages/conda/instructions.py", line 73, in UNLINKLINKTRANSACTION_CMD
    unlink_link_transaction.execute()
  File "/home/marscher/miniconda3/lib/python3.10/site-packages/conda/core/link.py", line 277, in execute
    self.verify()
  File "/home/marscher/miniconda3/lib/python3.10/site-packages/conda/common/io.py", line 86, in decorated
    return f(*args, **kwds)
  File "/home/marscher/miniconda3/lib/python3.10/site-packages/conda/core/link.py", line 227, in verify
    self.prepare()
  File "/home/marscher/miniconda3/lib/python3.10/site-packages/conda/core/link.py", line 216, in prepare
    grps = self._prepare(self.transaction_context, stp.target_prefix,
  File "/home/marscher/miniconda3/lib/python3.10/site-packages/conda/core/link.py", line 377, in _prepare
    cls._make_entry_point_actions(
  File "/home/marscher/miniconda3/lib/python3.10/site-packages/conda/core/link.py", line 912, in _make_entry_point_actions
    return CreatePythonEntryPointAction.create_actions(*required_quad)
  File "/home/marscher/miniconda3/lib/python3.10/site-packages/conda/core/path_actions.py", line 606, in create_actions
    actions = tuple(cls(transaction_context, package_info, target_prefix,
  File "/home/marscher/miniconda3/lib/python3.10/site-packages/conda/core/path_actions.py", line 607, in <genexpr>
    *this_triplet(ep_def))
  File "/home/marscher/miniconda3/lib/python3.10/site-packages/conda/core/path_actions.py", line 600, in this_triplet
    command, module, func = parse_entry_point_def(entry_point_def)
  File "/home/marscher/miniconda3/lib/python3.10/site-packages/conda/common/path.py", line 150, in parse_entry_point_def
    cmd_mod, func = ep_definition.rsplit(':', 1)
ValueError: not enough values to unpack (expected 2, got 1)

The value which is being parsed at the time is "timmins.display", where it should contain the definition of what "display" contains, e.g. "excl = "timmins_plugin_fancy:excl_display" lined = "timmins_plugin_fancy:lined_display""

edit: after a conda render the entry-point section already looks truncated:

build:
  entry_points:
    - timmins.display
kenodegard commented 1 year ago

@marscher looks like the recipe needs to be something like:

{% set pyproject = load_file_data("../../pyproject.toml", from_recipe_dir=True)  %}
{% set proj = pyproject.get('project') %}
  # ...
  entry_points:
  {% for module, entrypoints in project.get('entry-points').items() %}
  {% for name, path in entrypoints.items() %}
    - {{ name }} = {{ module }}.{{ path }}
  {% endfor %}
  {% endfor %}
marscher commented 1 year ago

thanks @kenodegard, that did the trick!

Nodd commented 1 year ago

9951 is related

jakirkham commented 1 year ago

Is that issue number right? Am not seeing that one

jezdez commented 1 year ago

This seems like a bug to me, rather than requesting a new feature. Not sure why "entrypoints" was used in such a way, since they were already well-established in setuptools/easy_install when conda-build was written, and it's an ambiguous use of the term.. I don't fully understand the history, but it seems sensible to fix this.

jakirkham commented 1 year ago

Not sure I understand your question Jannis. Am interpreting it as, why would one want to list entry points in the recipe if they are listed in other files (like setup.py)? Though please let me know if I've misunderstood that.

Answering that question (assuming it is the question asked), there were various issues encountered with the entry points generated by Setuptools.

For example it made use of pkg_resources, which in turn meant setuptools needed to be a run dependency of anything that used entry points generated by Setuptools. This in turn meant Setuptools was getting pulled into host environments implicitly, which caused various issues.

Another issue was the executables generated on Windows had issues when their paths were rewritten by conda-build. They also didn't behave well in noarch: python packages.

There are probably other issues that I'm forgetting.

In any event we have found it easier to just stomp on the entry points created by Setuptools (or others) and write our own with Conda-build. This process has worked well and not seen the issues noted above.


To this specific issue, am not sure I would go with bug per se. Instead would suggest this is a UI discussion. The user has proposed new keys and there is a question about how these would be structured/behave (GUI entry points have been an interesting corner case for example)

github-actions[bot] commented 2 months ago

Hi there, thank you for your contribution!

This issue has been automatically marked as stale because it has not had recent activity. It will be closed automatically if no further activity occurs.

If you would like this issue to remain open please:

  1. Verify that you can still reproduce the issue at hand
  2. Comment that the issue is still reproducible and include:
    • What OS and version you reproduced the issue on
    • What steps you followed to reproduce the issue

NOTE: If this issue was closed prematurely, please leave a comment.

Thanks!

flying-sheep commented 2 months ago

nah