ninjaaron / fast-entry_points

make entry_points specified in setup.py load more quickly.
BSD 2-Clause "Simplified" License
124 stars 18 forks source link

fastep should inject code after module docstrings and __future__ imports #18

Open jayvdb opened 5 years ago

jayvdb commented 5 years ago

Using fastep on pyflakes:

$ fastep
$ python3 setup.py build
  File "setup.py", line 5
    from __future__ import with_statement
    ^
SyntaxError: from __future__ imports must occur at the beginning of the file

Using fastep on gpgme:

$ fastep
$ python3 setup.py build
Traceback (most recent call last):
  File "setup.py", line 28, in <module>
    description, long_description = __doc__.split("\n\n", 1)
AttributeError: 'NoneType' object has no attribute 'split'
jayvdb commented 5 years ago

I guess there will also be issues with setup.py that use distutils.core rather than setuptools - most can be migrated to setuptools but I've found a few which are not easily automatically upgraded.

jayvdb commented 5 years ago

Continuing from the post at https://github.com/ninjaaron/fast-entry_points/issues/11#issuecomment-542650736 about fastep not being designed for all setup.py , and that being a hard problem to solve, you may have noticed https://github.com/Nuitka/Nuitka/issues/553 . There are also a few other tools which fiddle with setup.py , and I would be looking for a way to make this reliable without constant fiddles to account for all the crazy variations of setup.py. An ast reader is one way (and some tools help for this), but I am looking further afield for other existing tools - maybe @dephell might be part of the solution with their converters.

ninjaaron commented 5 years ago

I'll work on the getting fastep to be inserted in a more sensible place in the setup script and evaluate how dephell might be useful for this project.

I have to say that I have some reservations about turning this short, simple module that's intended to be vendored into a static analysis project about whether this monkey patch can be used and how best to automatically inject it. It almost feels like it could even be a separate project, or at least a thorough re-architechture of this project.

For one thing, fastentrypoints.py, as it exists right now, is a single module that triggers a monkey-patch of setuptools when it is imported. This is fine for the thing I originally meant to do with it, but for the usecase you have in mind, it would be worthwhile, in my opinion, to separate this into a package with separate modules: The module which actually gets vendored and has no external dependencies, and at least one other module that is responsible for injecting the right code. I'll think about how to do this without breaking my current users, but it might be easier to put fastentrypoints in maintenance mode and make a clean break.

Thoughts?

jayvdb commented 5 years ago

Rather than splitting the two, my hope was to find an existing project which already is the "setup.py editing toolkit" we need, or is an existing project which can be morphed into it with a bit of effort and a maintainer who likes that problem domain. I cant put my finger on that project just yet, but I do have vague memories of people doing rather crazy things like that, so I'll do a little digging around over the next few days to get a short list together.

ninjaaron commented 5 years ago

I think that requires splitting this project into a package rather than a single module in any case (which it probably already should be). One hard line here is that the vendored code is not allowed to have dependencies. It should be a single file you can drop into the project--and there's really no reason users of a package even need to have the current code that implements fastep installed on their system in the first place (and multiple copies of it for every package that uses fastentrypoints). The size of the vendored code could already be reduced considerably.