{"action":"created","issue":{"url":"https://api.github.com/repos/DRMacIver/hypothesis/issues/184","labels_url":"https://api.github.com/repos/DRMacIver/hypothesis/issues/184/labels{/name}","comments_url":"https://api.github.com/repos/DRMacIver/hypothesis/issues/184/comments","events_url":"https://api.github.com/repos/DRMacIver/hypothesis/issues/184/events","html_url":"https://github.com/DRMacIver/hypothesis/issues/184","id":109578725,"number":184,"title":"Hypothesis cannot be installed by `easy_install`","user":{"login":"jerith","id":43731,"avatar_url":"https://avatars.githubusercontent.com/u/43731?v=3","gravatar_id":"","url":"https://api.github.com/users/jerith","html_url":"https://github.com/jerith","followers_url":"https://api.github.com/users/jerith/followers","following_url":"https://api.github.com/users/jerith/following{/other_user}","gists_url":"https://api.github.com/users/jerith/gists{/gist_id}","starred_url":"https://api.github.com/users/jerith/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jerith/subscriptions","organizations_url":"https://api.github.com/users/jerith/orgs","repos_url":"https://api.github.com/users/jerith/repos","events_url":"https://api.github.com/users/jerith/events{/privacy}","received_events_url":"https://api.github.com/users/jerith/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/DRMacIver/hypothesis/labels/bug","name":"bug","color":"fc2929"},{"url":"https://api.github.com/repos/DRMacIver/hypothesis/labels/help-wanted","name":"help-wanted","color":"0052cc"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":10,"created_at":"2015-10-02T21:54:07Z","updated_at":"2015-10-03T18:47:49Z","closed_at":null,"body":"Sit back, dear reader, while I tell you a tale of sorrow and software, packaging and pain.\r\n\r\nA long time ago, when Python was new and the world was a simpler place, before `pip` roamed the earth, `easy_install` was the way to install packages. Its legacy lives on in `setuptools`, which still uses it in various situations.\r\n\r\nHere is what happens when various `setuptools` commands are invoked:\r\n\r\n`python setup.py egg_info` creates the `hypothesis.egg-info/` dir and fills it with a tasteful assortment of package metadata.\r\n`python setup.py sdist` builds egg-info, then constructs a source package that contains it along with the code.\r\n`python setup.py bdist_egg` builds egg-info, then constructs an egg zipfile that contains it along with the code.\r\n`python setup.py install` builds egg-info, then constructs an egg zipfile, then installs the egg it just built.\r\n`easy_install hypothesis` downloads the latest source tarball, extracts it, builds an egg zipfile from its contents, and then installs the egg it just built.\r\n\r\nThe observant among you may have noticed that one of these operations does not build egg-info. It's unnecessary when you're installing a source package, because the source package already contains the egg-info that was built during `python setup.py sdist`.\r\n\r\nAs mentioned above, when `easy_install` installs a source package, it does so by building an egg and then installing that egg. Specifically, it builds the egg from the contents of the source package and then looks in the location it put the freshly-built egg for a suitable egg to install. *And sometimes it doesn't find one.*\r\n\r\nLet us now take a brief digression to understand how `setuptools` finds packages to install. Among the various mechanisms is a handler for zipfiles. This explicitly ignores zipfiles that end in `.whl`, because those are wheels. After that, it looks for either egg metadata (in which case it's found an egg) or a directory ending in `.egg` (which it then treats as a potential nested egg and examines further).\r\n\r\nIn order to build an egg, `setuptools` copies the egg-info and source files to a build dir, compiles the relevant source, and then zips up the build dir and gives the resulting archive a filename ending in `.egg`. Remember that when `setuptools` builds the egg from an sdist, it assumes the egg-info is already in the source tarball.\r\n\r\nWe now have a condition under which `setuptools` can fail to find an egg it has just built. All one needs is a source package that does not contain egg-info (or does not contain it in the location `setuptools` expects it).\r\n\r\nFor Hypothesis 1.11.4, `setuptools` expects the tarball to contain `hypothesis-1.11.4/hypothesis.egg-info/PKG-INFO`. What the source tarball actually contains is `hypothesis-1.11.4/src/hypothesis.egg-info/PKG-INFO`. Therefore, the egg it builds during installation lacks the required metadata and is treated as a non-egg zipfile. Installation then fails with a perfectly accurate error message that is completely incomprehensible without knowledge of the above.\r\n\r\nThe solution here is to make sure that the egg-info gets put in the place `setuptools` expects to find it in the source tarball."},"comment":{"url":"https://api.github.com/repos/DRMacIver/hypothesis/issues/comments/145277262","html_url":"https://github.com/DRMacIver/hypothesis/issues/184#issuecomment-145277262","issue_url":"https://api.github.com/repos/DRMacIver/hypothesis/issues/184","id":145277262,"user":{"login":"DRMacIver","id":28623,"avatar_url":"https://avatars.githubusercontent.com/u/28623?v=3","gravatar_id":"","url":"https://api.github.com/users/DRMacIver","html_url":"https://github.com/DRMacIver","followers_url":"https://api.github.com/users/DRMacIver/followers","following_url":"https://api.github.com/users/DRMacIver/following{/other_user}","gists_url":"https://api.github.com/users/DRMacIver/gists{/gist_id}","starred_url":"https://api.github.com/users/DRMacIver/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DRMacIver/subscriptions","organizations_url":"https://api.github.com/users/DRMacIver/orgs","repos_url":"https://api.github.com/users/DRMacIver/repos","events_url":"https://api.github.com/users/DRMacIver/events{/privacy}","received_events_url":"https://api.github.com/users/DRMacIver/received_events","type":"User","site_admin":false},"created_at":"2015-10-03T18:47:49Z","updated_at":"2015-10-03T18:47:49Z","body":"Hmm. A thought. @ulope, do you have your file system set to be case sensitive? I wonder if that's the difference?"}}