python / importlib_metadata

Library to access metadata for Python packages
https://importlib-metadata.readthedocs.io
Apache License 2.0
125 stars 81 forks source link

entry_points parsing fails on comment lines #297

Closed agroszer closed 3 years ago

agroszer commented 3 years ago

https://github.com/python/importlib_metadata/commit/01cf7b4591671b5a44c28cb054e07074ce0ee760#diff-68d928f3527c08d068d21149666147cda5bbd2be1f2ebda260cc40434600d522

This breaks when there's a comment in entry_points, e.g. Paste has such an entry: https://github.com/cdent/paste/blob/master/setup.py#L92

jaraco commented 3 years ago

Oh, my. In this comment, I wrote:

Given that most metadata is mechanically generated, I'm okay with weak error handling.

I'd assumed that Setuptools was generating the syntax and not that it could allow the user to provide the content verbatim. It'll be straightforward to further eliminate comments, but I wonder what other cases may be missed. My instinct here is to fix the comments issue and see if other issues arise.

jaraco commented 3 years ago

For the record, here's the error:

$ pip-run --use-pep517 importlib_metadata git+https://github.com/cdent/paste -- -c "import importlib_metadata as im; print(im.entry_points(group='paste.filter_app_factory').names)"
  Running command git clone -q https://github.com/cdent/paste /private/var/folders/c6/v7hnmq453xb6p2dbz1gqc6rr0000gn/T/pip-req-build-yvzd166a
Collecting git+https://github.com/cdent/paste
  Cloning https://github.com/cdent/paste to /private/var/folders/c6/v7hnmq453xb6p2dbz1gqc6rr0000gn/T/pip-req-build-yvzd166a
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
    Preparing wheel metadata ... done
Collecting importlib_metadata
  Using cached importlib_metadata-3.9.0-py3-none-any.whl (14 kB)
Collecting setuptools
  Using cached setuptools-54.2.0-py3-none-any.whl (785 kB)
Collecting six>=1.4.0
  Using cached six-1.15.0-py2.py3-none-any.whl (10 kB)
Collecting zipp>=0.5
  Using cached zipp-3.4.1-py3-none-any.whl (5.2 kB)
Building wheels for collected packages: Paste
  Building wheel for Paste (PEP 517) ... done
  Created wheel for Paste: filename=Paste-3.5.0-py2.py3-none-any.whl size=593198 sha256=bbf309898ba54640d3d206f1f97da6c09ba518ba44ef90452ed26231b812f201
  Stored in directory: /private/var/folders/c6/v7hnmq453xb6p2dbz1gqc6rr0000gn/T/pip-ephem-wheel-cache-odtyv3k2/wheels/35/55/a5/cfed3ded27f7cf90293ed13bcdd881a6952647a6d7aad7ead3
Successfully built Paste
Installing collected packages: zipp, six, setuptools, Paste, importlib-metadata
Successfully installed Paste-3.5.0 importlib-metadata-3.9.0 setuptools-54.2.0 six-1.15.0 zipp-3.4.1
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/var/folders/c6/v7hnmq453xb6p2dbz1gqc6rr0000gn/T/pip-run-h4tf_ik2/importlib_metadata/__init__.py", line 893, in entry_points
    return SelectableGroups.load(eps).select(**params)
  File "/var/folders/c6/v7hnmq453xb6p2dbz1gqc6rr0000gn/T/pip-run-h4tf_ik2/importlib_metadata/__init__.py", line 331, in load
    ordered = sorted(eps, key=by_group)
  File "/var/folders/c6/v7hnmq453xb6p2dbz1gqc6rr0000gn/T/pip-run-h4tf_ik2/importlib_metadata/__init__.py", line 891, in <genexpr>
    dist.entry_points for dist in unique(distributions())
  File "/var/folders/c6/v7hnmq453xb6p2dbz1gqc6rr0000gn/T/pip-run-h4tf_ik2/importlib_metadata/__init__.py", line 517, in entry_points
    return EntryPoints._from_text_for(self.read_text('entry_points.txt'), self)
  File "/var/folders/c6/v7hnmq453xb6p2dbz1gqc6rr0000gn/T/pip-run-h4tf_ik2/importlib_metadata/__init__.py", line 244, in _from_text_for
    return cls(ep._for(dist) for ep in cls._from_text(text))
  File "/var/folders/c6/v7hnmq453xb6p2dbz1gqc6rr0000gn/T/pip-run-h4tf_ik2/importlib_metadata/__init__.py", line 244, in <genexpr>
    return cls(ep._for(dist) for ep in cls._from_text(text))
  File "/var/folders/c6/v7hnmq453xb6p2dbz1gqc6rr0000gn/T/pip-run-h4tf_ik2/importlib_metadata/__init__.py", line 255, in <genexpr>
    for name, value in values
ValueError: not enough values to unpack (expected 2, got 1)
mgorny commented 3 years ago

This doesn't resolve the problem with Paste, since its entry_points file is indented, i.e.:


      [paste.app_factory]
      cgi = paste.cgiapp:make_cgi_application [subprocess]
      static = paste.urlparser:make_static
      pkg_resources = paste.urlparser:make_pkg_resources
      urlparser = paste.urlparser:make_url_parser
      proxy = paste.proxy:make_proxy
      test = paste.debug.debugapp:make_test_app
      test_slow = paste.debug.debugapp:make_slow_app
      transparent_proxy = paste.proxy:make_transparent_proxy
      watch_threads = paste.debug.watchthreads:make_watch_threads

      [paste.composite_factory]
      urlmap = paste.urlmap:urlmap_factory
      cascade = paste.cascade:make_cascade

      [paste.filter_app_factory]
      error_catcher = paste.exceptions.errormiddleware:make_error_middleware
      cgitb = paste.cgitb_catcher:make_cgitb_middleware
      flup_session = paste.flup_session:make_session_middleware [Flup]
      gzip = paste.gzipper:make_gzip_middleware
      httpexceptions = paste.httpexceptions:make_middleware
      lint = paste.lint:make_middleware
      printdebug = paste.debug.prints:PrintDebugMiddleware
      profile = paste.debug.profile:make_profile_middleware [hotshot]
      recursive = paste.recursive:make_recursive_middleware
      # This isn't good enough to deserve the name egg:Paste#session:
      paste_session = paste.session:make_session_middleware
      wdg_validate = paste.debug.wdg_validate:make_wdg_validate_middleware [subprocess]
      evalerror = paste.evalexception.middleware:make_eval_exception
      auth_tkt = paste.auth.auth_tkt:make_auth_tkt_middleware
      auth_basic = paste.auth.basic:make_basic
      auth_digest = paste.auth.digest:make_digest
      auth_form = paste.auth.form:make_form
      grantip = paste.auth.grantip:make_grantip
      openid = paste.auth.open_id:make_open_id_middleware [openid]
      pony = paste.pony:make_pony
      cowbell = paste.cowbell:make_cowbell
      errordocument = paste.errordocument:make_errordocument
      auth_cookie = paste.auth.cookie:make_auth_cookie
      translogger = paste.translogger:make_filter
      config = paste.config:make_config_filter
      registry = paste.registry:make_registry_manager

      [paste.server_runner]
      http = paste.httpserver:server_runner