{"action":"created","comment":{"url":"https://api.github.com/repos/hylang/hy/pulls/comments/223463532","pull_request_review_id":162596436,"id":223463532,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIyMzQ2MzUzMg==","diff_hunk":"@@ -48,88 +35,144 @@ def _(fn):\n             # names that are invalid in Python.\n             fn._hy_macro_pass_compiler = False\n \n-        module_name = fn.__module__\n-        if module_name.startswith(\"hy.core\"):\n-            module_name = None\n-        _hy_macros[module_name][name] = fn\n+        module = inspect.getmodule(fn)\n+        module_macros = module.__dict__.setdefault('__macros__', {})\n+        module_macros[name] = fn\n+\n         return fn\n     return _\n \n \n def tag(name):\n     \"\"\"Decorator to define a tag macro called `name`.\n-\n-    This stores the macro `name` in the namespace for the module where it is\n-    defined.\n-\n-    If the module where it is defined is in `hy.core`, then the macro is stored\n-    in the default `None` namespace.\n-\n-    This function is called from the `deftag` special form in the compiler.\n-\n     \"\"\"\n     def _(fn):\n         _name = mangle('#{}'.format(name))\n+\n         if not PY3:\n             _name = _name.encode('UTF-8')\n+\n         fn.__name__ = _name\n-        module_name = fn.__module__\n+\n+        module = inspect.getmodule(fn)\n+\n+        module_name = module.__name__\n         if module_name.startswith(\"hy.core\"):\n             module_name = None\n-        _hy_tag[module_name][mangle(name)] = fn\n+\n+        module_tags = module.__dict__.setdefault('__tags__', {})\n+        module_tags[mangle(name)] = fn\n \n         return fn\n     return _\n \n \n def require(source_module, target_module, assignments, prefix=\"\"):\n-    \"\"\"Load macros from `source_module` in the namespace of\n-    `target_module`. `assignments` maps old names to new names, or\n-    should be the string \"ALL\". If `prefix` is nonempty, it is\n-    prepended to the name of each imported macro. (This means you get\n-    macros named things like \"mymacromodule.mymacro\", which looks like\n-    an attribute of a module, although it's actually just a symbol\n-    with a period in its name.)\n+    \"\"\"Load macros from one module into the namespace of another.\n \n     This function is called from the `require` special form in the compiler.\n \n-    \"\"\"\n+    Parameters\n+    ----------\n+    source_module: str or types.ModuleType\n+        The module from which macros are to be imported.\n \n-    seen_names = set()\n-    if prefix:\n-        prefix += \".\"\n-    if assignments != \"ALL\":\n-        assignments = {mangle(str_type(k)): v for k, v in assignments}\n+    target_module: str, types.ModuleType or None\n+        The module into which the macros will be loaded.  If `None`, then\n+        the caller's namespace.\n+        The latter is useful during evaluation of generated AST/bytecode.\n \n-    for d in _hy_macros, _hy_tag:\n-        for name, macro in d[source_module].items():\n-            seen_names.add(name)\n-            if assignments == \"ALL\":\n-                d[target_module][mangle(prefix + name)] = macro\n-            elif name in assignments:\n-                d[target_module][mangle(prefix + assignments[name])] = macro\n+    assignments: str or list of tuples of strs\n+        The string \"ALL\" or a dict of macro names to aliases.\n \n-    if assignments != \"ALL\":\n-        unseen = frozenset(assignments.keys()).difference(seen_names)\n-        if unseen:\n-            raise ImportError(\"cannot require names: \" + repr(list(unseen)))\n+    prefix: str, optional (\"\")\n+        If nonempty, its value is prepended to the name of each imported macro.\n+        This allows one to emulate namespaced macros, like\n+        \"mymacromodule.mymacro\", which looks like an attribute of a module.\n \n+    Returns\n+    -------\n+    out: None\n+    \"\"\"\n+    if not inspect.ismodule(source_module):\n+        source_module = importlib.import_module(source_module)\n+\n+    source_macros = source_module.__dict__.setdefault('__macros__', {})\n+    source_tags = source_module.__dict__.setdefault('__tags__', {})\n+\n+    if len(source_module.__macros__) + len(source_module.__tags__) == 0:","path":"hy/macros.py","position":151,"original_position":151,"commit_id":"9e995695929953a5a824e5002e11cde0dc63d6f1","original_commit_id":"9e995695929953a5a824e5002e11cde0dc63d6f1","user":{"login":"brandonwillard","id":971601,"node_id":"MDQ6VXNlcjk3MTYwMQ==","avatar_url":"https://avatars0.githubusercontent.com/u/971601?v=4","gravatar_id":"","url":"https://api.github.com/users/brandonwillard","html_url":"https://github.com/brandonwillard","followers_url":"https://api.github.com/users/brandonwillard/followers","following_url":"https://api.github.com/users/brandonwillard/following{/other_user}","gists_url":"https://api.github.com/users/brandonwillard/gists{/gist_id}","starred_url":"https://api.github.com/users/brandonwillard/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/brandonwillard/subscriptions","organizations_url":"https://api.github.com/users/brandonwillard/orgs","repos_url":"https://api.github.com/users/brandonwillard/repos","events_url":"https://api.github.com/users/brandonwillard/events{/privacy}","received_events_url":"https://api.github.com/users/brandonwillard/received_events","type":"User","site_admin":false},"body":"Perhaps it's reasonable to silently allow a `(require module)` when `module` has no macros or tags, but I'm on the fence about that.  Regardless, that check short-circuits the steps that follow and provides a much more precise error when `assignments` are not just `ALL`.","created_at":"2018-10-08T18:47:45Z","updated_at":"2018-10-08T18:47:45Z","html_url":"https://github.com/hylang/hy/pull/1682#discussion_r223463532","pull_request_url":"https://api.github.com/repos/hylang/hy/pulls/1682","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/hylang/hy/pulls/comments/223463532"},"html":{"href":"https://github.com/hylang/hy/pull/1682#discussion_r223463532"},"pull_request":{"href":"https://api.github.com/repos/hylang/hy/pulls/1682"}},"in_reply_to_id":223453573},"pull_request":{"url":"https://api.github.com/repos/hylang/hy/pulls/1682","id":217552409,"node_id":"MDExOlB1bGxSZXF1ZXN0MjE3NTUyNDA5","html_url":"https://github.com/hylang/hy/pull/1682","diff_url":"https://github.com/hylang/hy/pull/1682.diff","patch_url":"https://github.com/hylang/hy/pull/1682.patch","issue_url":"https://api.github.com/repos/hylang/hy/issues/1682","number":1682,"state":"open","locked":false,"title":"Macro processing updates and fixes","user":{"login":"brandonwillard","id":971601,"node_id":"MDQ6VXNlcjk3MTYwMQ==","avatar_url":"https://avatars0.githubusercontent.com/u/971601?v=4","gravatar_id":"","url":"https://api.github.com/users/brandonwillard","html_url":"https://github.com/brandonwillard","followers_url":"https://api.github.com/users/brandonwillard/followers","following_url":"https://api.github.com/users/brandonwillard/following{/other_user}","gists_url":"https://api.github.com/users/brandonwillard/gists{/gist_id}","starred_url":"https://api.github.com/users/brandonwillard/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/brandonwillard/subscriptions","organizations_url":"https://api.github.com/users/brandonwillard/orgs","repos_url":"https://api.github.com/users/brandonwillard/repos","events_url":"https://api.github.com/users/brandonwillard/events{/privacy}","received_events_url":"https://api.github.com/users/brandonwillard/received_events","type":"User","site_admin":false},"body":"This PR changes the way macros are loaded and managed within modules/namespaces, their scope of evaluation, and how `require` statements are treated during the module bytecode loading process.\r\n\r\nAlongside those changes, a general refactoring was started that moves toward a `HyASTCompiler` that can operate in two fashions: 1) compilation that occurs within a module and allows macros to interact with the compiler (as they are currently configured to do), and 2) compilation that does not require a concrete module context but does not allow true macro-compiler interaction.  The latter case could drastically simplify some of the module importing work-arounds that currently exist in this PR (e.g. when interacting with `runpy`).\r\n\r\nIt addresses/closes the following issues:\r\n- [x] https://github.com/hylang/hy/issues/1268\r\n- [x] https://github.com/hylang/hy/issues/1650\r\n- [x] https://github.com/hylang/hy/issues/1416","created_at":"2018-09-24T03:56:25Z","updated_at":"2018-10-08T18:47:45Z","closed_at":null,"merged_at":null,"merge_commit_sha":"093f1bc396493917dd312d9c111d6756eecbb09b","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/hylang/hy/pulls/1682/commits","review_comments_url":"https://api.github.com/repos/hylang/hy/pulls/1682/comments","review_comment_url":"https://api.github.com/repos/hylang/hy/pulls/comments{/number}","comments_url":"https://api.github.com/repos/hylang/hy/issues/1682/comments","statuses_url":"https://api.github.com/repos/hylang/hy/statuses/9e995695929953a5a824e5002e11cde0dc63d6f1","head":{"label":"brandonwillard:macro-changes","ref":"macro-changes","sha":"9e995695929953a5a824e5002e11cde0dc63d6f1","user":{"login":"brandonwillard","id":971601,"node_id":"MDQ6VXNlcjk3MTYwMQ==","avatar_url":"https://avatars0.githubusercontent.com/u/971601?v=4","gravatar_id":"","url":"https://api.github.com/users/brandonwillard","html_url":"https://github.com/brandonwillard","followers_url":"https://api.github.com/users/brandonwillard/followers","following_url":"https://api.github.com/users/brandonwillard/following{/other_user}","gists_url":"https://api.github.com/users/brandonwillard/gists{/gist_id}","starred_url":"https://api.github.com/users/brandonwillard/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/brandonwillard/subscriptions","organizations_url":"https://api.github.com/users/brandonwillard/orgs","repos_url":"https://api.github.com/users/brandonwillard/repos","events_url":"https://api.github.com/users/brandonwillard/events{/privacy}","received_events_url":"https://api.github.com/users/brandonwillard/received_events","type":"User","site_admin":false},"repo":{"id":135207099,"node_id":"MDEwOlJlcG9zaXRvcnkxMzUyMDcwOTk=","name":"hy","full_name":"brandonwillard/hy","private":false,"owner":{"login":"brandonwillard","id":971601,"node_id":"MDQ6VXNlcjk3MTYwMQ==","avatar_url":"https://avatars0.githubusercontent.com/u/971601?v=4","gravatar_id":"","url":"https://api.github.com/users/brandonwillard","html_url":"https://github.com/brandonwillard","followers_url":"https://api.github.com/users/brandonwillard/followers","following_url":"https://api.github.com/users/brandonwillard/following{/other_user}","gists_url":"https://api.github.com/users/brandonwillard/gists{/gist_id}","starred_url":"https://api.github.com/users/brandonwillard/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/brandonwillard/subscriptions","organizations_url":"https://api.github.com/users/brandonwillard/orgs","repos_url":"https://api.github.com/users/brandonwillard/repos","events_url":"https://api.github.com/users/brandonwillard/events{/privacy}","received_events_url":"https://api.github.com/users/brandonwillard/received_events","type":"User","site_admin":false},"html_url":"https://github.com/brandonwillard/hy","description":"A dialect of Lisp that's embedded in Python","fork":true,"url":"https://api.github.com/repos/brandonwillard/hy","forks_url":"https://api.github.com/repos/brandonwillard/hy/forks","keys_url":"https://api.github.com/repos/brandonwillard/hy/keys{/key_id}","collaborators_url":"https://api.github.com/repos/brandonwillard/hy/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/brandonwillard/hy/teams","hooks_url":"https://api.github.com/repos/brandonwillard/hy/hooks","issue_events_url":"https://api.github.com/repos/brandonwillard/hy/issues/events{/number}","events_url":"https://api.github.com/repos/brandonwillard/hy/events","assignees_url":"https://api.github.com/repos/brandonwillard/hy/assignees{/user}","branches_url":"https://api.github.com/repos/brandonwillard/hy/branches{/branch}","tags_url":"https://api.github.com/repos/brandonwillard/hy/tags","blobs_url":"https://api.github.com/repos/brandonwillard/hy/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/brandonwillard/hy/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/brandonwillard/hy/git/refs{/sha}","trees_url":"https://api.github.com/repos/brandonwillard/hy/git/trees{/sha}","statuses_url":"https://api.github.com/repos/brandonwillard/hy/statuses/{sha}","languages_url":"https://api.github.com/repos/brandonwillard/hy/languages","stargazers_url":"https://api.github.com/repos/brandonwillard/hy/stargazers","contributors_url":"https://api.github.com/repos/brandonwillard/hy/contributors","subscribers_url":"https://api.github.com/repos/brandonwillard/hy/subscribers","subscription_url":"https://api.github.com/repos/brandonwillard/hy/subscription","commits_url":"https://api.github.com/repos/brandonwillard/hy/commits{/sha}","git_commits_url":"https://api.github.com/repos/brandonwillard/hy/git/commits{/sha}","comments_url":"https://api.github.com/repos/brandonwillard/hy/comments{/number}","issue_comment_url":"https://api.github.com/repos/brandonwillard/hy/issues/comments{/number}","contents_url":"https://api.github.com/repos/brandonwillard/hy/contents/{+path}","compare_url":"https://api.github.com/repos/brandonwillard/hy/compare/{base}...{head}","merges_url":"https://api.github.com/repos/brandonwillard/hy/merges","archive_url":"https://api.github.com/repos/brandonwillard/hy/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/brandonwillard/hy/downloads","issues_url":"https://api.github.com/repos/brandonwillard/hy/issues{/number}","pulls_url":"https://api.github.com/repos/brandonwillard/hy/pulls{/number}","milestones_url":"https://api.github.com/repos/brandonwillard/hy/milestones{/number}","notifications_url":"https://api.github.com/repos/brandonwillard/hy/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/brandonwillard/hy/labels{/name}","releases_url":"https://api.github.com/repos/brandonwillard/hy/releases{/id}","deployments_url":"https://api.github.com/repos/brandonwillard/hy/deployments","created_at":"2018-05-28T20:39:05Z","updated_at":"2018-09-25T21:49:35Z","pushed_at":"2018-10-07T21:20:24Z","git_url":"git://github.com/brandonwillard/hy.git","ssh_url":"git@github.com:brandonwillard/hy.git","clone_url":"https://github.com/brandonwillard/hy.git","svn_url":"https://github.com/brandonwillard/hy","homepage":"http://hylang.org/","size":4979,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit","node_id":"MDc6TGljZW5zZTEz"},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"hylang:master","ref":"master","sha":"d2319dc91c90cfd56aed505f72e449df92119672","user":{"login":"hylang","id":4141508,"node_id":"MDEyOk9yZ2FuaXphdGlvbjQxNDE1MDg=","avatar_url":"https://avatars3.githubusercontent.com/u/4141508?v=4","gravatar_id":"","url":"https://api.github.com/users/hylang","html_url":"https://github.com/hylang","followers_url":"https://api.github.com/users/hylang/followers","following_url":"https://api.github.com/users/hylang/following{/other_user}","gists_url":"https://api.github.com/users/hylang/gists{/gist_id}","starred_url":"https://api.github.com/users/hylang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hylang/subscriptions","organizations_url":"https://api.github.com/users/hylang/orgs","repos_url":"https://api.github.com/users/hylang/repos","events_url":"https://api.github.com/users/hylang/events{/privacy}","received_events_url":"https://api.github.com/users/hylang/received_events","type":"Organization","site_admin":false},"repo":{"id":7184072,"node_id":"MDEwOlJlcG9zaXRvcnk3MTg0MDcy","name":"hy","full_name":"hylang/hy","private":false,"owner":{"login":"hylang","id":4141508,"node_id":"MDEyOk9yZ2FuaXphdGlvbjQxNDE1MDg=","avatar_url":"https://avatars3.githubusercontent.com/u/4141508?v=4","gravatar_id":"","url":"https://api.github.com/users/hylang","html_url":"https://github.com/hylang","followers_url":"https://api.github.com/users/hylang/followers","following_url":"https://api.github.com/users/hylang/following{/other_user}","gists_url":"https://api.github.com/users/hylang/gists{/gist_id}","starred_url":"https://api.github.com/users/hylang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hylang/subscriptions","organizations_url":"https://api.github.com/users/hylang/orgs","repos_url":"https://api.github.com/users/hylang/repos","events_url":"https://api.github.com/users/hylang/events{/privacy}","received_events_url":"https://api.github.com/users/hylang/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/hylang/hy","description":"A dialect of Lisp that's embedded in Python","fork":false,"url":"https://api.github.com/repos/hylang/hy","forks_url":"https://api.github.com/repos/hylang/hy/forks","keys_url":"https://api.github.com/repos/hylang/hy/keys{/key_id}","collaborators_url":"https://api.github.com/repos/hylang/hy/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/hylang/hy/teams","hooks_url":"https://api.github.com/repos/hylang/hy/hooks","issue_events_url":"https://api.github.com/repos/hylang/hy/issues/events{/number}","events_url":"https://api.github.com/repos/hylang/hy/events","assignees_url":"https://api.github.com/repos/hylang/hy/assignees{/user}","branches_url":"https://api.github.com/repos/hylang/hy/branches{/branch}","tags_url":"https://api.github.com/repos/hylang/hy/tags","blobs_url":"https://api.github.com/repos/hylang/hy/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/hylang/hy/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/hylang/hy/git/refs{/sha}","trees_url":"https://api.github.com/repos/hylang/hy/git/trees{/sha}","statuses_url":"https://api.github.com/repos/hylang/hy/statuses/{sha}","languages_url":"https://api.github.com/repos/hylang/hy/languages","stargazers_url":"https://api.github.com/repos/hylang/hy/stargazers","contributors_url":"https://api.github.com/repos/hylang/hy/contributors","subscribers_url":"https://api.github.com/repos/hylang/hy/subscribers","subscription_url":"https://api.github.com/repos/hylang/hy/subscription","commits_url":"https://api.github.com/repos/hylang/hy/commits{/sha}","git_commits_url":"https://api.github.com/repos/hylang/hy/git/commits{/sha}","comments_url":"https://api.github.com/repos/hylang/hy/comments{/number}","issue_comment_url":"https://api.github.com/repos/hylang/hy/issues/comments{/number}","contents_url":"https://api.github.com/repos/hylang/hy/contents/{+path}","compare_url":"https://api.github.com/repos/hylang/hy/compare/{base}...{head}","merges_url":"https://api.github.com/repos/hylang/hy/merges","archive_url":"https://api.github.com/repos/hylang/hy/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/hylang/hy/downloads","issues_url":"https://api.github.com/repos/hylang/hy/issues{/number}","pulls_url":"https://api.github.com/repos/hylang/hy/pulls{/number}","milestones_url":"https://api.github.com/repos/hylang/hy/milestones{/number}","notifications_url":"https://api.github.com/repos/hylang/hy/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/hylang/hy/labels{/name}","releases_url":"https://api.github.com/repos/hylang/hy/releases{/id}","deployments_url":"https://api.github.com/repos/hylang/hy/deployments","created_at":"2012-12-15T21:20:51Z","updated_at":"2018-10-07T19:42:44Z","pushed_at":"2018-10-08T16:08:06Z","git_url":"git://github.com/hylang/hy.git","ssh_url":"git@github.com:hylang/hy.git","clone_url":"https://github.com/hylang/hy.git","svn_url":"https://github.com/hylang/hy","homepage":"http://hylang.org/","size":4959,"stargazers_count":2600,"watchers_count":2600,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":269,"mirror_url":null,"archived":false,"open_issues_count":157,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit","node_id":"MDc6TGljZW5zZTEz"},"forks":269,"open_issues":157,"watchers":2600,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/hylang/hy/pulls/1682"},"html":{"href":"https://github.com/hylang/hy/pull/1682"},"issue":{"href":"https://api.github.com/repos/hylang/hy/issues/1682"},"comments":{"href":"https://api.github.com/repos/hylang/hy/issues/1682/comments"},"review_comments":{"href":"https://api.github.com/repos/hylang/hy/pulls/1682/comments"},"review_comment":{"href":"https://api.github.com/repos/hylang/hy/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/hylang/hy/pulls/1682/commits"},"statuses":{"href":"https://api.github.com/repos/hylang/hy/statuses/9e995695929953a5a824e5002e11cde0dc63d6f1"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"brandonwillard"}}