Repository: pallets/jinja (python)

Issue:
Template globals are not accessible within imports w/ enable_async
Template globals are not applied correctly when using the `enable_async` environment flag. 

When used normally, template globals can be used within imported macros.

With `enable_async=True`, template globals can only be accessed in macros within the immediate template.

### Example script:

```python
from jinja2 import Environment
from jinja2.loaders import DictLoader
import asyncio

templates = {
    "child.html": """\
{% extends default_layout or 'default.html' %}
{% from 'helpers.html' import imported_get_value%}
{% macro get_value() %}{{value}}{% endmacro %}
]{% block body %}
    {{ get_value() }}
    {{ imported_get_value() }}
{% endblock %}
""",
    "default.html": """\
<!doctype html>
<title>{{ value }}</title>
{% block body %}{% endblock %}
""",
    "helpers.html": """\
{% macro imported_get_value() %}{{value}}{% endmacro %}
""",
}


def sync_main():
    env = Environment(loader=DictLoader(templates))
    tmpl = env.get_template("child.html", globals={"value": "hello"})
    print(tmpl.render())


async def async_main():
    env = Environment(loader=DictLoader(templates), enable_async=True)
    tmpl = env.get_template("child.html", globals={"value": "hello"})
    print(await tmpl.render_async())


if __name__ == "__main__":
    print("---- SYNC ----")
    sync_main()
    print("---- ASYNC ----")
    asyncio.run(async_main())
```

### Output

```
---- SYNC ----
<!doctype html>
<title>hello</title>

    hello
    hello

---- ASYNC ----
<!doctype html>
<title>hello</title>

    hello
    
```

I expected the above output to be the same for sync and async.

Environment:

- Python version: 3.9.6 
- Jinja version: 3.0.1


Pull request:
Template globals not accessible within imported macros
* Pass context to `_get_default_module_async` to provide template globals to imports.
* Added tests.
* Refactored existing and new import global tests to use existing fixtures.
* Copied `CHANGES.rst` entry from #1241 since it best described the fix.

Relevant issues and PRs:

- One-liner, relies on the fix in PR #1241
- fixes #1494

Checklist:

- [x] Add tests that demonstrate the correct behavior of the change. Tests should fail without the change.
- [x] Add or update relevant docs, in the docs folder and in code.
- [x] Add an entry in `CHANGES.rst` summarizing the change and linking to the issue.
- [x] Add `.. versionchanged::` entries in any relevant code docs.
- [x] Run `pre-commit` hooks and fix any issues.
- [x] Run `pytest` and `tox`, no tests failed.


Patch:
diff --git a/CHANGES.rst b/CHANGES.rst
index 074dd1f8..eb51581d 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -9,6 +9,8 @@ Version 3.0.2
     names. :issue:`1452, 1453`
 -   Revert an unintended change that caused ``Undefined`` to act like
     ``StrictUndefined`` for the ``in`` operator. :issue:`1448`
+-   Imported macros have access to the current template globals in async
+    environments. :issue:`1494`
 
 
 Version 3.0.1
diff --git a/src/jinja2/compiler.py b/src/jinja2/compiler.py
index b6297202..52fd5b83 100644
--- a/src/jinja2/compiler.py
+++ b/src/jinja2/compiler.py
@@ -1090,10 +1090,8 @@ class CodeGenerator(NodeVisitor):
             self.write(
                 f"{f_name}(context.get_all(), True, {self.dump_local_context(frame)})"
             )
-        elif self.environment.is_async:
-            self.write("_get_default_module_async()")
         else:
-            self.write("_get_default_module(context)")
+            self.write(f"_get_default_module{self.choose_async('_async')}(context)")
 
     def visit_Import(self, node: nodes.Import, frame: Frame) -> None:
         """Visit regular imports."""


Test patch:
diff --git a/tests/test_async.py b/tests/test_async.py
index e1c8d234..375a7bac 100644
--- a/tests/test_async.py
+++ b/tests/test_async.py
@@ -189,6 +189,29 @@ class TestAsyncImports:
         assert m.variable == 42
         assert not hasattr(m, "notthere")
 
+    def test_import_with_globals(self, test_env_async):
+        t = test_env_async.from_string(
+            '{% import "module" as m %}{{ m.test() }}', globals={"foo": 42}
+        )
+        assert t.render() == "[42|23]"
+
+        t = test_env_async.from_string('{% import "module" as m %}{{ m.test() }}')
+        assert t.render() == "[|23]"
+
+    def test_import_with_globals_override(self, test_env_async):
+        t = test_env_async.from_string(
+            '{% set foo = 41 %}{% import "module" as m %}{{ m.test() }}',
+            globals={"foo": 42},
+        )
+        assert t.render() == "[42|23]"
+
+    def test_from_import_with_globals(self, test_env_async):
+        t = test_env_async.from_string(
+            '{% from "module" import test %}{{ test() }}',
+            globals={"foo": 42},
+        )
+        assert t.render() == "[42|23]"
+
 
 class TestAsyncIncludes:
     def test_context_include(self, test_env_async):
diff --git a/tests/test_imports.py b/tests/test_imports.py
index 054c9010..b59fb49d 100644
--- a/tests/test_imports.py
+++ b/tests/test_imports.py
@@ -99,45 +99,27 @@ class TestImports:
             t.render()
 
     def test_import_with_globals(self, test_env):
-        env = Environment(
-            loader=DictLoader(
-                {
-                    "macros": "{% macro test() %}foo: {{ foo }}{% endmacro %}",
-                    "test": "{% import 'macros' as m %}{{ m.test() }}",
-                    "test1": "{% import 'macros' as m %}{{ m.test() }}",
-                }
-            )
+        t = test_env.from_string(
+            '{% import "module" as m %}{{ m.test() }}', globals={"foo": 42}
         )
-        tmpl = env.get_template("test", globals={"foo": "bar"})
-        assert tmpl.render() == "foo: bar"
+        assert t.render() == "[42|23]"
 
-        tmpl = env.get_template("test1")
-        assert tmpl.render() == "foo: "
+        t = test_env.from_string('{% import "module" as m %}{{ m.test() }}')
+        assert t.render() == "[|23]"
 
     def test_import_with_globals_override(self, test_env):
-        env = Environment(
-            loader=DictLoader(
-                {
-                    "macros": "{% set foo = '42' %}{% macro test() %}"
-                    "foo: {{ foo }}{% endmacro %}",
-                    "test": "{% from 'macros' import test %}{{ test() }}",
-                }
-            )
+        t = test_env.from_string(
+            '{% set foo = 41 %}{% import "module" as m %}{{ m.test() }}',
+            globals={"foo": 42},
         )
-        tmpl = env.get_template("test", globals={"foo": "bar"})
-        assert tmpl.render() == "foo: 42"
+        assert t.render() == "[42|23]"
 
     def test_from_import_with_globals(self, test_env):
-        env = Environment(
-            loader=DictLoader(
-                {
-                    "macros": "{% macro testing() %}foo: {{ foo }}{% endmacro %}",
-                    "test": "{% from 'macros' import testing %}{{ testing() }}",
-                }
-            )
+        t = test_env.from_string(
+            '{% from "module" import test %}{{ test() }}',
+            globals={"foo": 42},
         )
-        tmpl = env.get_template("test", globals={"foo": "bar"})
-        assert tmpl.render() == "foo: bar"
+        assert t.render() == "[42|23]"
 
 
 class TestIncludes: