Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
970e3d9
allow a mapping, rather than just a dict subclass, as globals
blhsing Jul 5, 2024
cf9945e
fixed typo
blhsing Jul 5, 2024
55f6dd4
regenerated header files
blhsing Jul 5, 2024
0d347f8
fixed error handling of DELETE_GLOBAL
blhsing Jul 5, 2024
4e1af59
fixed borrowed builtins reference
blhsing Jul 5, 2024
40f7c35
fixed error handling
blhsing Jul 5, 2024
698aa1f
use PyMapping_HasKeyStringWithError for proper error handling
blhsing Jul 5, 2024
fa1dcac
fixed usage of id __lltrace__
blhsing Jul 5, 2024
4343867
made _PyEval_BuiltinsFromGlobals return a new, non-borrowed reference
blhsing Jul 5, 2024
c5b38b0
release reference to builtins module
blhsing Jul 5, 2024
0daa66b
streamline code
blhsing Jul 5, 2024
2852b8f
added dict-specific path for insertion of __builtins__ into globals
blhsing Jul 5, 2024
5120260
try PyDict_* before PyMapping_*
blhsing Jul 5, 2024
723d665
switch from EAFP to LBYL
blhsing Jul 5, 2024
3908ee8
fixed typo
blhsing Jul 5, 2024
4a14682
dict-specific path for function
blhsing Jul 5, 2024
ab2974e
more dict-specific paths
blhsing Jul 5, 2024
1218ab7
minor adjustments
blhsing Jul 5, 2024
375af2b
📜🤖 Added by blurb_it.
blurb-it[bot] Jul 5, 2024
06b225b
removed redundant PyDict_Check; streamlined code
blhsing Jul 8, 2024
d584987
fixed check for null globals
blhsing Jul 8, 2024
3d3a563
updated docs
blhsing Jul 8, 2024
8bbc34c
minor update to docs
blhsing Jul 8, 2024
ca2ea12
updated tests
blhsing Jul 8, 2024
0f9e289
Update 2024-07-05-16-24-14.gh-issue-121306.nUBgho.rst
blhsing Jul 8, 2024
186ee55
Update 2024-07-05-16-24-14.gh-issue-121306.nUBgho.rst
blhsing Jul 8, 2024
190c09f
fixed reference count
blhsing Jul 8, 2024
09df171
Merge branch 'master' into allow-mapping-as-globals
blhsing Jul 8, 2024
1949be7
updated test to validate evaluated result
blhsing Jul 9, 2024
bb888ff
updated style
blhsing Jul 9, 2024
db01f51
regen headers
blhsing Jul 9, 2024
f0cd4e8
removed comments that are no longer applicable
blhsing Jul 9, 2024
d7d7d04
allow a mapping to be object.__dict__ and by extension module.__dict_…
blhsing Jul 11, 2024
cab9a52
simplified macros for unified dict/mapping API
blhsing Jul 11, 2024
f8c62c6
corrected comments
blhsing Jul 11, 2024
aa2d9b4
regen headers
blhsing Jul 11, 2024
362e0ac
fixed headers
blhsing Jul 11, 2024
bf7be59
simplified macro
blhsing Jul 11, 2024
0bf8239
fixed reference count
blhsing Jul 11, 2024
278c2ca
fixed typo in doc
blhsing Jul 11, 2024
d6735b9
fixed reference count
blhsing Jul 11, 2024
18dad2b
fixed possible uninitialized usage
blhsing Jul 11, 2024
35ada07
fixed logical operation
blhsing Jul 11, 2024
2e6a88a
updated tests
blhsing Jul 11, 2024
c29a10c
added test for mapping __dict__ for module; DRYer code with better ma…
blhsing Jul 12, 2024
3513a29
updated comment
blhsing Jul 12, 2024
97b813d
updated comment
blhsing Jul 12, 2024
6ea65b9
reformatted code; updated news
blhsing Jul 12, 2024
8137cab
reformatted code for clarity
blhsing Jul 12, 2024
725a327
fixed typo
blhsing Jul 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
updated docs
  • Loading branch information
blhsing committed Jul 8, 2024
commit 3d3a5630404ff5ccdbb9c386b9b76b449fd41057
33 changes: 20 additions & 13 deletions Doc/library/functions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@ are always available. They are listed here in alphabetical order.

:param globals:
The global namespace (default: ``None``).
:type globals: :class:`dict` | ``None``
:type globals: :term:`mapping` | ``None``

:param locals:
The local namespace (default: ``None``).
Expand All @@ -592,14 +592,14 @@ are always available. They are listed here in alphabetical order.

The *expression* argument is parsed and evaluated as a Python expression
(technically speaking, a condition list) using the *globals* and *locals*
mappings as global and local namespace. If the *globals* dictionary is
mappings as global and local namespace. If the *globals* mapping is
present and does not contain a value for the key ``__builtins__``, a
reference to the dictionary of the built-in module :mod:`builtins` is
inserted under that key before *expression* is parsed. That way you can
control what builtins are available to the executed code by inserting your
own ``__builtins__`` dictionary into *globals* before passing it to
own ``__builtins__`` mapping into *globals* before passing it to
:func:`eval`. If the *locals* mapping is omitted it defaults to the
*globals* dictionary. If both mappings are omitted, the expression is
*globals* mapping. If both mappings are omitted, the expression is
executed with the *globals* and *locals* in the environment where
:func:`eval` is called. Note, *eval()* will only have access to the
:term:`nested scopes <nested scope>` (non-locals) in the enclosing
Expand All @@ -619,7 +619,7 @@ are always available. They are listed here in alphabetical order.

Hints: dynamic execution of statements is supported by the :func:`exec`
function. The :func:`globals` and :func:`locals` functions
return the current global and local dictionary, respectively, which may be
return the current global and local mapping, respectively, which may be
useful to pass around for use by :func:`eval` or :func:`exec`.

If the given source is a string, then leading and trailing spaces and tabs
Expand All @@ -642,6 +642,10 @@ are always available. They are listed here in alphabetical order.
The semantics of the default *locals* namespace have been adjusted as
described for the :func:`locals` builtin.

.. versionchanged:: 3.14

A mapping can now be passed as the *globals* argument.

.. index:: pair: built-in function; exec

.. function:: exec(source, /, globals=None, locals=None, *, closure=None)
Expand All @@ -658,12 +662,12 @@ are always available. They are listed here in alphabetical order.
:func:`exec` function. The return value is ``None``.

In all cases, if the optional parts are omitted, the code is executed in the
current scope. If only *globals* is provided, it must be a dictionary
(and not a subclass of dictionary), which
current scope. If only *globals* is provided, it must be a mapping, which
will be used for both the global and the local variables. If *globals* and
*locals* are given, they are used for the global and local variables,
respectively. If provided, *locals* can be any mapping object. Remember
that at the module level, globals and locals are the same dictionary.
respectively. If provided, *globals* and *locals* can be any mapping
objects. Remember that at the module level, globals and locals are the same
mapping.

.. note::

Expand All @@ -673,11 +677,11 @@ are always available. They are listed here in alphabetical order.
to access variables assigned at the top level (as the "top level"
variables are treated as class variables in a class definition).

If the *globals* dictionary does not contain a value for the key
``__builtins__``, a reference to the dictionary of the built-in module
If the *globals* mapping does not contain a value for the key
``__builtins__``, a reference to the mapping of the built-in module
:mod:`builtins` is inserted under that key. That way you can control what
builtins are available to the executed code by inserting your own
``__builtins__`` dictionary into *globals* before passing it to :func:`exec`.
``__builtins__`` mapping into *globals* before passing it to :func:`exec`.

The *closure* argument specifies a closure--a tuple of cellvars.
It's only valid when the *object* is a code object containing free variables.
Expand All @@ -698,7 +702,7 @@ are always available. They are listed here in alphabetical order.
.. note::

The default *locals* act as described for function :func:`locals` below.
Pass an explicit *locals* dictionary if you need to see effects of the
Pass an explicit *locals* mapping if you need to see effects of the
code on *locals* after function :func:`exec` returns.

.. versionchanged:: 3.11
Expand All @@ -713,6 +717,9 @@ are always available. They are listed here in alphabetical order.
The semantics of the default *locals* namespace have been adjusted as
described for the :func:`locals` builtin.

.. versionchanged:: 3.14

A mapping can now be passed as the *globals* argument.

.. function:: filter(function, iterable)

Expand Down
6 changes: 3 additions & 3 deletions Doc/reference/datamodel.rst
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@ Special read-only attributes
- Meaning

* - .. attribute:: function.__globals__
- A reference to the :class:`dictionary <dict>` that holds the function's
- A reference to the :term:`mapping` that holds the function's
:ref:`global variables <naming>` -- the global namespace of the module
in which the function was defined.

Expand Down Expand Up @@ -1356,11 +1356,11 @@ Special read-only attributes
Return a proxy for optimized scopes.

* - .. attribute:: frame.f_globals
- The dictionary used by the frame to look up
- The mapping used by the frame to look up
:ref:`global variables <naming>`

* - .. attribute:: frame.f_builtins
- The dictionary used by the frame to look up
- The mapping used by the frame to look up
:ref:`built-in (intrinsic) names <naming>`

* - .. attribute:: frame.f_lasti
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Allow a mapping to be used as a global namespace, applicable to frame and function objects, and built-in functions :func:`exec` and :func:`eval`.
Allow a mapping to be passed as the ``globals`` argument for the built-in functions ``exec`` and ``eval``.
15 changes: 4 additions & 11 deletions Objects/funcobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ PyObject *
PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname)
{
assert(globals != NULL);
assert(PyDict_Check(globals));
Py_INCREF(globals);

PyThreadState *tstate = _PyThreadState_GET();
Expand Down Expand Up @@ -182,23 +183,15 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname
// __module__: Use globals['__name__'] if it exists, or NULL.
PyObject *module;
PyObject *builtins = NULL;
int r;
if (PyDict_Check(globals)) {
r = PyDict_GetItemRef(globals, &_Py_ID(__name__), &module);
}
else if (PyMapping_Check(globals)) {
r = PyMapping_GetOptionalItem(globals, &_Py_ID(__name__), &module);
} else {
goto error;
}
if (r < 0) {
if (PyDict_GetItemRef(globals, &_Py_ID(__name__), &module) < 0) {
goto error;
}

builtins = _PyEval_BuiltinsFromGlobals(tstate, globals);
builtins = _PyEval_BuiltinsFromGlobals(tstate, globals); // borrowed ref
if (builtins == NULL) {
goto error;
}
Py_INCREF(builtins);

PyFunctionObject *op = PyObject_GC_New(PyFunctionObject, &PyFunction_Type);
if (op == NULL) {
Expand Down