{"action":"created","issue":{"url":"https://api.github.com/repos/pyinstaller/pyinstaller/issues/1393","labels_url":"https://api.github.com/repos/pyinstaller/pyinstaller/issues/1393/labels{/name}","comments_url":"https://api.github.com/repos/pyinstaller/pyinstaller/issues/1393/comments","events_url":"https://api.github.com/repos/pyinstaller/pyinstaller/issues/1393/events","html_url":"https://github.com/pyinstaller/pyinstaller/pull/1393","id":99871717,"number":1393,"title":"Module Import Ordering Preserved","user":{"login":"leycec","id":217028,"avatar_url":"https://avatars.githubusercontent.com/u/217028?v=3","gravatar_id":"","url":"https://api.github.com/users/leycec","html_url":"https://github.com/leycec","followers_url":"https://api.github.com/users/leycec/followers","following_url":"https://api.github.com/users/leycec/following{/other_user}","gists_url":"https://api.github.com/users/leycec/gists{/gist_id}","starred_url":"https://api.github.com/users/leycec/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/leycec/subscriptions","organizations_url":"https://api.github.com/users/leycec/orgs","repos_url":"https://api.github.com/users/leycec/repos","events_url":"https://api.github.com/users/leycec/events{/privacy}","received_events_url":"https://api.github.com/users/leycec/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/pyinstaller/pyinstaller/labels/@high","name":"@high","color":"e11d21"},{"url":"https://api.github.com/repos/pyinstaller/pyinstaller/labels/modulegraph","name":"modulegraph","color":"fef2c0"},{"url":"https://api.github.com/repos/pyinstaller/pyinstaller/labels/more%20work","name":"more work","color":"c7def8"},{"url":"https://api.github.com/repos/pyinstaller/pyinstaller/labels/PY3","name":"PY3","color":"fef2c0"}],"state":"open","locked":false,"assignee":{"login":"htgoebel","id":784161,"avatar_url":"https://avatars.githubusercontent.com/u/784161?v=3","gravatar_id":"","url":"https://api.github.com/users/htgoebel","html_url":"https://github.com/htgoebel","followers_url":"https://api.github.com/users/htgoebel/followers","following_url":"https://api.github.com/users/htgoebel/following{/other_user}","gists_url":"https://api.github.com/users/htgoebel/gists{/gist_id}","starred_url":"https://api.github.com/users/htgoebel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/htgoebel/subscriptions","organizations_url":"https://api.github.com/users/htgoebel/orgs","repos_url":"https://api.github.com/users/htgoebel/repos","events_url":"https://api.github.com/users/htgoebel/events{/privacy}","received_events_url":"https://api.github.com/users/htgoebel/received_events","type":"User","site_admin":false},"milestone":{"url":"https://api.github.com/repos/pyinstaller/pyinstaller/milestones/9","html_url":"https://github.com/pyinstaller/pyinstaller/milestones/PyInstaller%203.0","labels_url":"https://api.github.com/repos/pyinstaller/pyinstaller/milestones/9/labels","id":831132,"number":9,"title":"PyInstaller 3.0","description":" * Add Python 3 support\r\n * Use modulegraph library for dependency analysis.","creator":{"login":"pyinstaller-tickets-migration","id":5377465,"avatar_url":"https://avatars.githubusercontent.com/u/5377465?v=3","gravatar_id":"","url":"https://api.github.com/users/pyinstaller-tickets-migration","html_url":"https://github.com/pyinstaller-tickets-migration","followers_url":"https://api.github.com/users/pyinstaller-tickets-migration/followers","following_url":"https://api.github.com/users/pyinstaller-tickets-migration/following{/other_user}","gists_url":"https://api.github.com/users/pyinstaller-tickets-migration/gists{/gist_id}","starred_url":"https://api.github.com/users/pyinstaller-tickets-migration/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pyinstaller-tickets-migration/subscriptions","organizations_url":"https://api.github.com/users/pyinstaller-tickets-migration/orgs","repos_url":"https://api.github.com/users/pyinstaller-tickets-migration/repos","events_url":"https://api.github.com/users/pyinstaller-tickets-migration/events{/privacy}","received_events_url":"https://api.github.com/users/pyinstaller-tickets-migration/received_events","type":"User","site_admin":false},"open_issues":22,"closed_issues":185,"state":"open","created_at":"2014-10-18T13:32:07Z","updated_at":"2015-09-19T14:47:15Z","due_on":"2015-09-29T22:00:00Z","closed_at":null},"comments":67,"created_at":"2015-08-09T07:04:16Z","updated_at":"2015-09-21T14:22:45Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/pyinstaller/pyinstaller/pulls/1393","html_url":"https://github.com/pyinstaller/pyinstaller/pull/1393","diff_url":"https://github.com/pyinstaller/pyinstaller/pull/1393.diff","patch_url":"https://github.com/pyinstaller/pyinstaller/pull/1393.patch"},"body":"This pull request preserves the order in which modules are imported by the user application. Because that is both needful and good.\r\n\r\nSpecifically, a new public `lib.modulegraph.modulegraph.Node.order` attribute – guaranteed to monotonically increase on _every_ module importation and hence provide a reliable means of comparing importation order – is added. (Tested and working, you may be sure.)\r\n\r\nThis low-level machinery partially fixes #1367. Hooks may now test the order in which two hypothetical modules `foo` and `bar` were initially imported as follows:\r\n\r\n```\r\nfrom PyInstaller.utils.hooks.hookutils import logger\r\n\r\ndef hook(mod):\r\n    if mod.graph.findNode('foo').order < mod.graph.findNode('bar').order:\r\n        logger.debug('Module \"foo\" imported before module \"bar\". Why? I dunno.')\r\n    else:\r\n        logger.debug('Module \"bar\" imported before module \"foo\". Suck it, you.')\r\n\r\n    return mod\r\n```\r\n\r\n## What About #1367? Why You No Fix, Huh?\r\n\r\nWould someone (...hey, no names: @htgoebel) mind posting a minimal-length example (MLE) demonstrating the exact issue of #1367?\r\n\r\nWhile I _do_ have the Python 2 version of wxPython locally installed, I'm unsure how to properly replicate this issue. I know; it's probably trivial. I'm feeble-brained, but hard-working. As soon as I get an MLE, I'll append a commit to this pull request fixing #1367 in entirety.\r\n\r\n## What Else? There's Always Something Else\r\n\r\nwxPython's Python 2 version (referred to as \"Classic\") and Python 3 version (referred to as \"Phoenix\") appear to be [_very_ dissimilar](http://wxpython.org/Phoenix/docs/html/MigrationGuide.html#the-wx-namespace-and-submodules-reorganized) – to the point of actually being different projects that confusingly share the same name. Our import hooks should probably account for these differences in ways I cannot possibly fathom.\r\n\r\nThus [spaketh Walt](http://www.bartleby.com/142/20.html)."},"comment":{"url":"https://api.github.com/repos/pyinstaller/pyinstaller/issues/comments/141997370","html_url":"https://github.com/pyinstaller/pyinstaller/pull/1393#issuecomment-141997370","issue_url":"https://api.github.com/repos/pyinstaller/pyinstaller/issues/1393","id":141997370,"user":{"login":"codewarrior0","id":307683,"avatar_url":"https://avatars.githubusercontent.com/u/307683?v=3","gravatar_id":"","url":"https://api.github.com/users/codewarrior0","html_url":"https://github.com/codewarrior0","followers_url":"https://api.github.com/users/codewarrior0/followers","following_url":"https://api.github.com/users/codewarrior0/following{/other_user}","gists_url":"https://api.github.com/users/codewarrior0/gists{/gist_id}","starred_url":"https://api.github.com/users/codewarrior0/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codewarrior0/subscriptions","organizations_url":"https://api.github.com/users/codewarrior0/orgs","repos_url":"https://api.github.com/users/codewarrior0/repos","events_url":"https://api.github.com/users/codewarrior0/events{/privacy}","received_events_url":"https://api.github.com/users/codewarrior0/received_events","type":"User","site_admin":false},"created_at":"2015-09-21T14:22:44Z","updated_at":"2015-09-21T14:22:44Z","body":"This *is* getting kind of confusing. Even the title of this PR isn't relevant any more.\r\n\r\nTo recap:\r\n\r\n1. `wx.lib.pubsub` hook was broken\r\n1. Said hook relied on knowing the order certain modules are imported.\r\n1. @leycec proposed a fix that makes `modulegraph` aware of the import order\r\n1. We discovered hooks aren't even run according to import order (#1367, #1420)\r\n1. @leycec proposed several new types of hooks that follow the import order\r\n  1. These new hooks require us to fork `modulegraph`\r\n  1. The `modulegraph` maintainer keeps breaking stuff, so forking `modulegraph` is fine.\r\n1. I obsoleted the old `wx.lib.pubsub` hook by [patching FrozenImporter](https://github.com/pyinstaller/pyinstaller/compare/python3...codewarrior0:frozenimporter-path-mod)\r\n  1. Now, import order isn't important any more. The new `wx.lib.pubsub` hook will just bring in an entire subtree.\r\n1. @leycec goes off on a rant about the internal consistency of complex data structures.\r\n  1. This rant is surprisingly useful as it outlines what we can and can't get away with inside of hook functions.\r\n1. @leycec throws away half of his proposed hook-types.\r\n1. I notice that maybe the old `fake-site` hook is still needed even with `Py_NoSite=1`\r\n1. @leycec has finally begun adding commits to this PR:\r\n  1. Port `test_wx_lib_pubsub` to the new test suite.\r\n  1. Begin implementing the API for the proposed hook-types.\r\n  1. These commits will not even address `wx.lib.pubsub`\r\n    1. Nor do they rely on any kind of module import ordering\r\n      1. So the `wx.lib.pubsub` stuff could go into another PR\r\n      1. And the new hook-types could go into yet another PR"}}