467 lines
37 KiB
HTML
467 lines
37 KiB
HTML
|
||
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<meta name="color-scheme" content="light dark">
|
||
<title>PEP 236 – Back to the __future__ | peps.python.org</title>
|
||
<link rel="shortcut icon" href="../_static/py.png">
|
||
<link rel="canonical" href="https://peps.python.org/pep-0236/">
|
||
<link rel="stylesheet" href="../_static/style.css" type="text/css">
|
||
<link rel="stylesheet" href="../_static/mq.css" type="text/css">
|
||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" media="(prefers-color-scheme: light)" id="pyg-light">
|
||
<link rel="stylesheet" href="../_static/pygments_dark.css" type="text/css" media="(prefers-color-scheme: dark)" id="pyg-dark">
|
||
<link rel="alternate" type="application/rss+xml" title="Latest PEPs" href="https://peps.python.org/peps.rss">
|
||
<meta property="og:title" content='PEP 236 – Back to the __future__ | peps.python.org'>
|
||
<meta property="og:description" content="Python Enhancement Proposals (PEPs)">
|
||
<meta property="og:type" content="website">
|
||
<meta property="og:url" content="https://peps.python.org/pep-0236/">
|
||
<meta property="og:site_name" content="Python Enhancement Proposals (PEPs)">
|
||
<meta property="og:image" content="https://peps.python.org/_static/og-image.png">
|
||
<meta property="og:image:alt" content="Python PEPs">
|
||
<meta property="og:image:width" content="200">
|
||
<meta property="og:image:height" content="200">
|
||
<meta name="description" content="Python Enhancement Proposals (PEPs)">
|
||
<meta name="theme-color" content="#3776ab">
|
||
</head>
|
||
<body>
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
|
||
<symbol id="svg-sun-half" viewBox="0 0 24 24" pointer-events="all">
|
||
<title>Following system colour scheme</title>
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
|
||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<circle cx="12" cy="12" r="9"></circle>
|
||
<path d="M12 3v18m0-12l4.65-4.65M12 14.3l7.37-7.37M12 19.6l8.85-8.85"></path>
|
||
</svg>
|
||
</symbol>
|
||
<symbol id="svg-moon" viewBox="0 0 24 24" pointer-events="all">
|
||
<title>Selected dark colour scheme</title>
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
|
||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||
<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z"></path>
|
||
</svg>
|
||
</symbol>
|
||
<symbol id="svg-sun" viewBox="0 0 24 24" pointer-events="all">
|
||
<title>Selected light colour scheme</title>
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
|
||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<circle cx="12" cy="12" r="5"></circle>
|
||
<line x1="12" y1="1" x2="12" y2="3"></line>
|
||
<line x1="12" y1="21" x2="12" y2="23"></line>
|
||
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
|
||
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
|
||
<line x1="1" y1="12" x2="3" y2="12"></line>
|
||
<line x1="21" y1="12" x2="23" y2="12"></line>
|
||
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
|
||
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
|
||
</svg>
|
||
</symbol>
|
||
</svg>
|
||
<script>
|
||
|
||
document.documentElement.dataset.colour_scheme = localStorage.getItem("colour_scheme") || "auto"
|
||
</script>
|
||
<section id="pep-page-section">
|
||
<header>
|
||
<h1>Python Enhancement Proposals</h1>
|
||
<ul class="breadcrumbs">
|
||
<li><a href="https://www.python.org/" title="The Python Programming Language">Python</a> » </li>
|
||
<li><a href="../pep-0000/">PEP Index</a> » </li>
|
||
<li>PEP 236</li>
|
||
</ul>
|
||
<button id="colour-scheme-cycler" onClick="setColourScheme(nextColourScheme())">
|
||
<svg aria-hidden="true" class="colour-scheme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
|
||
<svg aria-hidden="true" class="colour-scheme-icon-when-dark"><use href="#svg-moon"></use></svg>
|
||
<svg aria-hidden="true" class="colour-scheme-icon-when-light"><use href="#svg-sun"></use></svg>
|
||
<span class="visually-hidden">Toggle light / dark / auto colour theme</span>
|
||
</button>
|
||
</header>
|
||
<article>
|
||
<section id="pep-content">
|
||
<h1 class="page-title">PEP 236 – Back to the __future__</h1>
|
||
<dl class="rfc2822 field-list simple">
|
||
<dt class="field-odd">Author<span class="colon">:</span></dt>
|
||
<dd class="field-odd">Tim Peters <tim.peters at gmail.com></dd>
|
||
<dt class="field-even">Status<span class="colon">:</span></dt>
|
||
<dd class="field-even"><abbr title="Accepted and implementation complete, or no longer active">Final</abbr></dd>
|
||
<dt class="field-odd">Type<span class="colon">:</span></dt>
|
||
<dd class="field-odd"><abbr title="Normative PEP with a new feature for Python, implementation change for CPython or interoperability standard for the ecosystem">Standards Track</abbr></dd>
|
||
<dt class="field-even">Created<span class="colon">:</span></dt>
|
||
<dd class="field-even">26-Feb-2001</dd>
|
||
<dt class="field-odd">Python-Version<span class="colon">:</span></dt>
|
||
<dd class="field-odd">2.1</dd>
|
||
<dt class="field-even">Post-History<span class="colon">:</span></dt>
|
||
<dd class="field-even">26-Feb-2001</dd>
|
||
</dl>
|
||
<hr class="docutils" />
|
||
<section id="contents">
|
||
<details><summary>Table of Contents</summary><ul class="simple">
|
||
<li><a class="reference internal" href="#motivation">Motivation</a></li>
|
||
<li><a class="reference internal" href="#intent">Intent</a></li>
|
||
<li><a class="reference internal" href="#syntax">Syntax</a></li>
|
||
<li><a class="reference internal" href="#semantics">Semantics</a></li>
|
||
<li><a class="reference internal" href="#example">Example</a></li>
|
||
<li><a class="reference internal" href="#standard-module-future-py">Standard Module __future__.py</a></li>
|
||
<li><a class="reference internal" href="#resolved-problem-runtime-compilation">Resolved Problem: Runtime Compilation</a></li>
|
||
<li><a class="reference internal" href="#resolved-problem-native-interactive-shells">Resolved Problem: Native Interactive Shells</a></li>
|
||
<li><a class="reference internal" href="#resolved-problem-simulated-interactive-shells">Resolved Problem: Simulated Interactive Shells</a></li>
|
||
<li><a class="reference internal" href="#questions-and-answers">Questions and Answers</a><ul>
|
||
<li><a class="reference internal" href="#what-about-a-from-past-version-to-get-back-old-behavior">What about a “from __past__” version, to get back <em>old</em> behavior?</a></li>
|
||
<li><a class="reference internal" href="#what-about-incompatibilities-due-to-changes-in-the-python-virtual-machine">What about incompatibilities due to changes in the Python virtual machine?</a></li>
|
||
<li><a class="reference internal" href="#what-about-incompatibilities-due-to-changes-in-python-s-c-api">What about incompatibilities due to changes in Python’s C API?</a></li>
|
||
<li><a class="reference internal" href="#i-want-to-wrap-future-statements-in-try-except-blocks-so-i-can-use-different-code-depending-on-which-version-of-python-i-m-running-why-can-t-i">I want to wrap future_statements in try/except blocks, so I can use different code depending on which version of Python I’m running. Why can’t I?</a></li>
|
||
<li><a class="reference internal" href="#going-back-to-the-nested-scopes-example-what-if-release-2-2-comes-along-and-i-still-haven-t-changed-my-code-how-can-i-keep-the-2-1-behavior-then">Going back to the nested_scopes example, what if release 2.2 comes along and I still haven’t changed my code? How can I keep the 2.1 behavior then?</a></li>
|
||
<li><a class="reference internal" href="#overloading-import-sucks-why-not-introduce-a-new-statement-for-this">Overloading <code class="docutils literal notranslate"><span class="pre">import</span></code> sucks. Why not introduce a new statement for this?</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#copyright">Copyright</a></li>
|
||
<li><a class="reference internal" href="#references-and-footnotes">References and Footnotes</a></li>
|
||
</ul>
|
||
</details></section>
|
||
<section id="motivation">
|
||
<h2><a class="toc-backref" href="#motivation" role="doc-backlink">Motivation</a></h2>
|
||
<p>From time to time, Python makes an incompatible change to the advertised
|
||
semantics of core language constructs, or changes their accidental
|
||
(implementation-dependent) behavior in some way. While this is never done
|
||
capriciously, and is always done with the aim of improving the language over
|
||
the long term, over the short term it’s contentious and disrupting.</p>
|
||
<p><a class="pep reference internal" href="../pep-0005/" title="PEP 5 – Guidelines for Language Evolution">PEP 5</a>, Guidelines for Language Evolution suggests ways to ease the pain,
|
||
and this PEP introduces some machinery in support of that.</p>
|
||
<p><a class="pep reference internal" href="../pep-0227/" title="PEP 227 – Statically Nested Scopes">PEP 227</a>, Statically Nested Scopes is the first application, and will be
|
||
used as an example here.</p>
|
||
</section>
|
||
<section id="intent">
|
||
<h2><a class="toc-backref" href="#intent" role="doc-backlink">Intent</a></h2>
|
||
<p>[Note: This is policy, and so should eventually move into <a class="pep reference internal" href="../pep-0005/" title="PEP 5 – Guidelines for Language Evolution">PEP 5</a>]</p>
|
||
<p>When an incompatible change to core language syntax or semantics is being
|
||
made:</p>
|
||
<ol class="arabic simple">
|
||
<li>The release C that introduces the change does not change the syntax or
|
||
semantics by default.</li>
|
||
<li>A future release R is identified in which the new syntax or semantics will
|
||
be enforced.</li>
|
||
<li>The mechanisms described in <a class="pep reference internal" href="../pep-0230/" title="PEP 230 – Warning Framework">PEP 230</a>, Warning Framework are used to
|
||
generate warnings, whenever possible, about constructs or operations whose
|
||
meaning may <a class="footnote-reference brackets" href="#id3" id="id1">[1]</a> change in release R.</li>
|
||
<li>The new future_statement (see below) can be explicitly included in a module
|
||
M to request that the code in module M use the new syntax or semantics in
|
||
the current release C.</li>
|
||
</ol>
|
||
<p>So old code continues to work by default, for at least one release, although
|
||
it may start to generate new warning messages. Migration to the new syntax or
|
||
semantics can proceed during that time, using the future_statement to make
|
||
modules containing it act as if the new syntax or semantics were already being
|
||
enforced.</p>
|
||
<p>Note that there is no need to involve the future_statement machinery in new
|
||
features unless they can break existing code; fully backward- compatible
|
||
additions can– and should –be introduced without a corresponding
|
||
future_statement.</p>
|
||
</section>
|
||
<section id="syntax">
|
||
<h2><a class="toc-backref" href="#syntax" role="doc-backlink">Syntax</a></h2>
|
||
<p>A future_statement is simply a from/import statement using the reserved module
|
||
name <code class="docutils literal notranslate"><span class="pre">__future__</span></code>:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">future_statement</span><span class="p">:</span> <span class="s2">"from"</span> <span class="s2">"__future__"</span> <span class="s2">"import"</span> <span class="n">feature</span> <span class="p">[</span><span class="s2">"as"</span> <span class="n">name</span><span class="p">]</span>
|
||
<span class="p">(</span><span class="s2">","</span><span class="n">feature</span> <span class="p">[</span><span class="s2">"as"</span> <span class="n">name</span><span class="p">])</span><span class="o">*</span>
|
||
|
||
<span class="n">feature</span><span class="p">:</span> <span class="n">identifier</span>
|
||
<span class="n">name</span><span class="p">:</span> <span class="n">identifier</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>In addition, all future_statements must appear near the top of the module. The
|
||
only lines that can appear before a future_statement are:</p>
|
||
<ul class="simple">
|
||
<li>The module docstring (if any).</li>
|
||
<li>Comments.</li>
|
||
<li>Blank lines.</li>
|
||
<li>Other future_statements.</li>
|
||
</ul>
|
||
<p>Example:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="sd">"""This is a module docstring."""</span>
|
||
|
||
<span class="c1"># This is a comment, preceded by a blank line and followed by</span>
|
||
<span class="c1"># a future_statement.</span>
|
||
<span class="kn">from</span> <span class="nn">__future__</span> <span class="kn">import</span> <span class="n">nested_scopes</span>
|
||
|
||
<span class="kn">from</span> <span class="nn">math</span> <span class="kn">import</span> <span class="n">sin</span>
|
||
<span class="kn">from</span> <span class="nn">__future__</span> <span class="kn">import</span> <span class="n">alabaster_weenoblobs</span> <span class="c1"># compile-time error!</span>
|
||
<span class="c1"># That was an error because preceded by a non-future_statement.</span>
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
<section id="semantics">
|
||
<h2><a class="toc-backref" href="#semantics" role="doc-backlink">Semantics</a></h2>
|
||
<p>A future_statement is recognized and treated specially at compile time:
|
||
changes to the semantics of core constructs are often implemented by
|
||
generating different code. It may even be the case that a new feature
|
||
introduces new incompatible syntax (such as a new reserved word), in which
|
||
case the compiler may need to parse the module differently. Such decisions
|
||
cannot be pushed off until runtime.</p>
|
||
<p>For any given release, the compiler knows which feature names have been
|
||
defined, and raises a compile-time error if a future_statement contains a
|
||
feature not known to it <a class="footnote-reference brackets" href="#id4" id="id2">[2]</a>.</p>
|
||
<p>The direct runtime semantics are the same as for any <code class="docutils literal notranslate"><span class="pre">import</span></code> statement:
|
||
there is a standard module <code class="docutils literal notranslate"><span class="pre">__future__.py</span></code>, described later, and it will be
|
||
imported in the usual way at the time the future_statement is executed.</p>
|
||
<p>The <em>interesting</em> runtime semantics depend on the specific feature(s)
|
||
“imported” by the future_statement(s) appearing in the module.</p>
|
||
<p>Note that there is nothing special about the statement:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">__future__</span> <span class="p">[</span><span class="k">as</span> <span class="n">name</span><span class="p">]</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>That is not a future_statement; it’s an ordinary import statement, with no
|
||
special semantics or syntax restrictions.</p>
|
||
</section>
|
||
<section id="example">
|
||
<h2><a class="toc-backref" href="#example" role="doc-backlink">Example</a></h2>
|
||
<p>Consider this code, in file scope.py:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">x</span> <span class="o">=</span> <span class="mi">42</span>
|
||
<span class="k">def</span> <span class="nf">f</span><span class="p">():</span>
|
||
<span class="n">x</span> <span class="o">=</span> <span class="mi">666</span>
|
||
<span class="k">def</span> <span class="nf">g</span><span class="p">():</span>
|
||
<span class="nb">print</span> <span class="s2">"x is"</span><span class="p">,</span> <span class="n">x</span>
|
||
<span class="n">g</span><span class="p">()</span>
|
||
<span class="n">f</span><span class="p">()</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Under 2.0, it prints:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">x</span> <span class="ow">is</span> <span class="mi">42</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Nested scopes (<a class="pep reference internal" href="../pep-0227/" title="PEP 227 – Statically Nested Scopes">PEP 227</a>) are being introduced in 2.1. But under 2.1, it still
|
||
prints:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">x</span> <span class="ow">is</span> <span class="mi">42</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>and also generates a warning.</p>
|
||
<p>In 2.2, and also in 2.1 <em>if</em> <code class="docutils literal notranslate"><span class="pre">from</span> <span class="pre">__future__</span> <span class="pre">import</span> <span class="pre">nested_scopes</span></code> is
|
||
included at the top of <code class="docutils literal notranslate"><span class="pre">scope.py</span></code>, it prints:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">x</span> <span class="ow">is</span> <span class="mi">666</span>
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
<section id="standard-module-future-py">
|
||
<h2><a class="toc-backref" href="#standard-module-future-py" role="doc-backlink">Standard Module __future__.py</a></h2>
|
||
<p><code class="docutils literal notranslate"><span class="pre">Lib/__future__.py</span></code> is a real module, and serves three purposes:</p>
|
||
<ol class="arabic simple">
|
||
<li>To avoid confusing existing tools that analyze import statements and expect
|
||
to find the modules they’re importing.</li>
|
||
<li>To ensure that future_statements run under releases prior to 2.1 at least
|
||
yield runtime exceptions (the import of <code class="docutils literal notranslate"><span class="pre">__future__</span></code> will fail, because
|
||
there was no module of that name prior to 2.1).</li>
|
||
<li>To document when incompatible changes were introduced, and when they will
|
||
be– or were –made mandatory. This is a form of executable documentation,
|
||
and can be inspected programmatically via importing <code class="docutils literal notranslate"><span class="pre">__future__</span></code> and
|
||
examining its contents.</li>
|
||
</ol>
|
||
<p>Each statement in <code class="docutils literal notranslate"><span class="pre">__future__.py</span></code> is of the form:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">FeatureName</span> <span class="o">=</span> <span class="s2">"_Feature("</span> <span class="n">OptionalRelease</span> <span class="s2">","</span> <span class="n">MandatoryRelease</span> <span class="s2">")"</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>where, normally, <em>OptionalRelease</em> < <em>MandatoryRelease</em>, and both are
|
||
5-tuples of the same form as <code class="docutils literal notranslate"><span class="pre">sys.version_info</span></code>:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="n">PY_MAJOR_VERSION</span><span class="p">,</span> <span class="c1"># the 2 in 2.1.0a3; an int</span>
|
||
<span class="n">PY_MINOR_VERSION</span><span class="p">,</span> <span class="c1"># the 1; an int</span>
|
||
<span class="n">PY_MICRO_VERSION</span><span class="p">,</span> <span class="c1"># the 0; an int</span>
|
||
<span class="n">PY_RELEASE_LEVEL</span><span class="p">,</span> <span class="c1"># "alpha", "beta", "candidate" or "final"; string</span>
|
||
<span class="n">PY_RELEASE_SERIAL</span> <span class="c1"># the 3; an int )</span>
|
||
</pre></div>
|
||
</div>
|
||
<p><em>OptionalRelease</em> records the first release in which:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">__future__</span> <span class="kn">import</span> <span class="n">FeatureName</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>was accepted.</p>
|
||
<p>In the case of <em>MandatoryReleases</em> that have not yet occurred,
|
||
<em>MandatoryRelease</em> predicts the release in which the feature will become part
|
||
of the language.</p>
|
||
<p>Else <em>MandatoryRelease</em> records when the feature became part of the language;
|
||
in releases at or after that, modules no longer need:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">__future__</span> <span class="kn">import</span> <span class="n">FeatureName</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>to use the feature in question, but may continue to use such imports.</p>
|
||
<p><em>MandatoryRelease</em> may also be <code class="docutils literal notranslate"><span class="pre">None</span></code>, meaning that a planned feature got
|
||
dropped.</p>
|
||
<p>Instances of <code class="docutils literal notranslate"><span class="pre">class</span> <span class="pre">_Feature</span></code> have two corresponding methods,
|
||
<code class="docutils literal notranslate"><span class="pre">.getOptionalRelease()</span></code> and <code class="docutils literal notranslate"><span class="pre">.getMandatoryRelease()</span></code>.</p>
|
||
<p>No feature line will ever be deleted from <code class="docutils literal notranslate"><span class="pre">__future__.py</span></code>.</p>
|
||
<p>Example line:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">nested_scopes</span> <span class="o">=</span> <span class="n">_Feature</span><span class="p">((</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="s2">"beta"</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="s2">"final"</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>This means that:</p>
|
||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">__future__</span> <span class="kn">import</span> <span class="n">nested_scopes</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>will work in all releases at or after 2.1b1, and that nested_scopes are
|
||
intended to be enforced starting in release 2.2.</p>
|
||
</section>
|
||
<section id="resolved-problem-runtime-compilation">
|
||
<h2><a class="toc-backref" href="#resolved-problem-runtime-compilation" role="doc-backlink">Resolved Problem: Runtime Compilation</a></h2>
|
||
<p>Several Python features can compile code during a module’s runtime:</p>
|
||
<ol class="arabic simple">
|
||
<li>The <code class="docutils literal notranslate"><span class="pre">exec</span></code> statement.</li>
|
||
<li>The <code class="docutils literal notranslate"><span class="pre">execfile()</span></code> function.</li>
|
||
<li>The <code class="docutils literal notranslate"><span class="pre">compile()</span></code> function.</li>
|
||
<li>The <code class="docutils literal notranslate"><span class="pre">eval()</span></code> function.</li>
|
||
<li>The <code class="docutils literal notranslate"><span class="pre">input()</span></code> function.</li>
|
||
</ol>
|
||
<p>Since a module M containing a future_statement naming feature F explicitly
|
||
requests that the current release act like a future release with respect to F,
|
||
any code compiled dynamically from text passed to one of these from within M
|
||
should probably also use the new syntax or semantics associated with F. The
|
||
2.1 release does behave this way.</p>
|
||
<p>This isn’t always desired, though. For example, <code class="docutils literal notranslate"><span class="pre">doctest.testmod(M)</span></code>
|
||
compiles examples taken from strings in M, and those examples should use M’s
|
||
choices, not necessarily the doctest module’s choices. In the 2.1 release,
|
||
this isn’t possible, and no scheme has yet been suggested for working around
|
||
this. NOTE: <a class="pep reference internal" href="../pep-0264/" title="PEP 264 – Future statements in simulated shells">PEP 264</a> later addressed this in a flexible way, by adding
|
||
optional arguments to <code class="docutils literal notranslate"><span class="pre">compile()</span></code>.</p>
|
||
<p>In any case, a future_statement appearing “near the top” (see Syntax above) of
|
||
text compiled dynamically by an <code class="docutils literal notranslate"><span class="pre">exec</span></code>, <code class="docutils literal notranslate"><span class="pre">execfile()</span></code> or <code class="docutils literal notranslate"><span class="pre">compile()</span></code>
|
||
applies to the code block generated, but has no further effect on the module
|
||
that executes such an <code class="docutils literal notranslate"><span class="pre">exec</span></code>, <code class="docutils literal notranslate"><span class="pre">execfile()</span></code> or <code class="docutils literal notranslate"><span class="pre">compile()</span></code>. This can’t
|
||
be used to affect <code class="docutils literal notranslate"><span class="pre">eval()</span></code> or <code class="docutils literal notranslate"><span class="pre">input()</span></code>, however, because they only allow
|
||
expression input, and a future_statement is not an expression.</p>
|
||
</section>
|
||
<section id="resolved-problem-native-interactive-shells">
|
||
<h2><a class="toc-backref" href="#resolved-problem-native-interactive-shells" role="doc-backlink">Resolved Problem: Native Interactive Shells</a></h2>
|
||
<p>There are two ways to get an interactive shell:</p>
|
||
<ol class="arabic simple">
|
||
<li>By invoking Python from a command line without a script argument.</li>
|
||
<li>By invoking Python from a command line with the <code class="docutils literal notranslate"><span class="pre">-i</span></code> switch and with a
|
||
script argument.</li>
|
||
</ol>
|
||
<p>An interactive shell can be seen as an extreme case of runtime compilation
|
||
(see above): in effect, each statement typed at an interactive shell prompt
|
||
runs a new instance of <code class="docutils literal notranslate"><span class="pre">exec</span></code>, <code class="docutils literal notranslate"><span class="pre">compile()</span></code> or <code class="docutils literal notranslate"><span class="pre">execfile()</span></code>. A
|
||
future_statement typed at an interactive shell applies to the rest of the
|
||
shell session’s life, as if the future_statement had appeared at the top of a
|
||
module.</p>
|
||
</section>
|
||
<section id="resolved-problem-simulated-interactive-shells">
|
||
<h2><a class="toc-backref" href="#resolved-problem-simulated-interactive-shells" role="doc-backlink">Resolved Problem: Simulated Interactive Shells</a></h2>
|
||
<p>Interactive shells “built by hand” (by tools such as IDLE and the Emacs
|
||
Python-mode) should behave like native interactive shells (see above).
|
||
However, the machinery used internally by native interactive shells has not
|
||
been exposed, and there isn’t a clear way for tools building their own
|
||
interactive shells to achieve the desired behavior.</p>
|
||
<p>NOTE: <a class="pep reference internal" href="../pep-0264/" title="PEP 264 – Future statements in simulated shells">PEP 264</a> later addressed this, by adding intelligence to the standard
|
||
<code class="docutils literal notranslate"><span class="pre">codeop.py</span></code>. Simulated shells that don’t use the standard library shell
|
||
helpers can get a similar effect by exploiting the new optional arguments to
|
||
<code class="docutils literal notranslate"><span class="pre">compile()</span></code> added by <a class="pep reference internal" href="../pep-0264/" title="PEP 264 – Future statements in simulated shells">PEP 264</a>.</p>
|
||
</section>
|
||
<section id="questions-and-answers">
|
||
<h2><a class="toc-backref" href="#questions-and-answers" role="doc-backlink">Questions and Answers</a></h2>
|
||
<section id="what-about-a-from-past-version-to-get-back-old-behavior">
|
||
<h3><a class="toc-backref" href="#what-about-a-from-past-version-to-get-back-old-behavior" role="doc-backlink">What about a “from __past__” version, to get back <em>old</em> behavior?</a></h3>
|
||
<p>Outside the scope of this PEP. Seems unlikely to the author, though. Write a
|
||
PEP if you want to pursue it.</p>
|
||
</section>
|
||
<section id="what-about-incompatibilities-due-to-changes-in-the-python-virtual-machine">
|
||
<h3><a class="toc-backref" href="#what-about-incompatibilities-due-to-changes-in-the-python-virtual-machine" role="doc-backlink">What about incompatibilities due to changes in the Python virtual machine?</a></h3>
|
||
<p>Outside the scope of this PEP, although <a class="pep reference internal" href="../pep-0005/" title="PEP 5 – Guidelines for Language Evolution">PEP 5</a> suggests a grace period
|
||
there too, and the future_statement may also have a role to play there.</p>
|
||
</section>
|
||
<section id="what-about-incompatibilities-due-to-changes-in-python-s-c-api">
|
||
<h3><a class="toc-backref" href="#what-about-incompatibilities-due-to-changes-in-python-s-c-api" role="doc-backlink">What about incompatibilities due to changes in Python’s C API?</a></h3>
|
||
<p>Outside the scope of this PEP.</p>
|
||
</section>
|
||
<section id="i-want-to-wrap-future-statements-in-try-except-blocks-so-i-can-use-different-code-depending-on-which-version-of-python-i-m-running-why-can-t-i">
|
||
<h3><a class="toc-backref" href="#i-want-to-wrap-future-statements-in-try-except-blocks-so-i-can-use-different-code-depending-on-which-version-of-python-i-m-running-why-can-t-i" role="doc-backlink">I want to wrap future_statements in try/except blocks, so I can use different code depending on which version of Python I’m running. Why can’t I?</a></h3>
|
||
<p>Sorry! <code class="docutils literal notranslate"><span class="pre">try/except</span></code> is a runtime feature; future_statements are primarily
|
||
compile-time gimmicks, and your <code class="docutils literal notranslate"><span class="pre">try/except</span></code> happens long after the compiler
|
||
is done. That is, by the time you do <code class="docutils literal notranslate"><span class="pre">try/except</span></code>, the semantics in effect
|
||
for the module are already a done deal. Since the <code class="docutils literal notranslate"><span class="pre">try/except</span></code> wouldn’t
|
||
accomplish what it <em>looks</em> like it should accomplish, it’s simply not allowed.
|
||
We also want to keep these special statements very easy to find and to
|
||
recognize.</p>
|
||
<p>Note that you <em>can</em> import <code class="docutils literal notranslate"><span class="pre">__future__</span></code> directly, and use the information in
|
||
it, along with <code class="docutils literal notranslate"><span class="pre">sys.version_info</span></code>, to figure out where the release you’re
|
||
running under stands in relation to a given feature’s status.</p>
|
||
</section>
|
||
<section id="going-back-to-the-nested-scopes-example-what-if-release-2-2-comes-along-and-i-still-haven-t-changed-my-code-how-can-i-keep-the-2-1-behavior-then">
|
||
<h3><a class="toc-backref" href="#going-back-to-the-nested-scopes-example-what-if-release-2-2-comes-along-and-i-still-haven-t-changed-my-code-how-can-i-keep-the-2-1-behavior-then" role="doc-backlink">Going back to the nested_scopes example, what if release 2.2 comes along and I still haven’t changed my code? How can I keep the 2.1 behavior then?</a></h3>
|
||
<p>By continuing to use 2.1, and not moving to 2.2 until you do change your
|
||
code. The purpose of future_statement is to make life easier for people who
|
||
keep current with the latest release in a timely fashion. We don’t hate you
|
||
if you don’t, but your problems are much harder to solve, and somebody with
|
||
those problems will need to write a PEP addressing them. future_statement is
|
||
aimed at a different audience.</p>
|
||
</section>
|
||
<section id="overloading-import-sucks-why-not-introduce-a-new-statement-for-this">
|
||
<h3><a class="toc-backref" href="#overloading-import-sucks-why-not-introduce-a-new-statement-for-this" role="doc-backlink">Overloading <code class="docutils literal notranslate"><span class="pre">import</span></code> sucks. Why not introduce a new statement for this?</a></h3>
|
||
<p>Like maybe <code class="docutils literal notranslate"><span class="pre">lambda</span> <span class="pre">lambda</span> <span class="pre">nested_scopes</span></code>? That is, unless we introduce a
|
||
new keyword, we can’t introduce an entirely new statement. But if we
|
||
introduce a new keyword, that in itself would break old code. That would be
|
||
too ironic to bear. Yes, overloading <code class="docutils literal notranslate"><span class="pre">import</span></code> does suck, but not as
|
||
energetically as the alternatives – as is, future_statements are 100%
|
||
backward compatible.</p>
|
||
</section>
|
||
</section>
|
||
<section id="copyright">
|
||
<h2><a class="toc-backref" href="#copyright" role="doc-backlink">Copyright</a></h2>
|
||
<p>This document has been placed in the public domain.</p>
|
||
</section>
|
||
<section id="references-and-footnotes">
|
||
<h2><a class="toc-backref" href="#references-and-footnotes" role="doc-backlink">References and Footnotes</a></h2>
|
||
<aside class="footnote-list brackets">
|
||
<aside class="footnote brackets" id="id3" role="doc-footnote">
|
||
<dt class="label" id="id3">[<a href="#id1">1</a>]</dt>
|
||
<dd>Note that this is <em>may</em> and not <em>will</em>: better safe than sorry. Of course
|
||
spurious warnings won’t be generated when avoidable with reasonable cost.</aside>
|
||
<aside class="footnote brackets" id="id4" role="doc-footnote">
|
||
<dt class="label" id="id4">[<a href="#id2">2</a>]</dt>
|
||
<dd>This ensures that a future_statement run under a release prior to the
|
||
first one in which a given feature is known (but >= 2.1) will raise a
|
||
compile-time error rather than silently do a wrong thing. If transported
|
||
to a release prior to 2.1, a runtime error will be raised because of the
|
||
failure to import <code class="docutils literal notranslate"><span class="pre">__future__</span></code> (no such module existed in the standard
|
||
distribution before the 2.1 release, and the double underscores make it a
|
||
reserved name).</aside>
|
||
</aside>
|
||
</section>
|
||
</section>
|
||
<hr class="docutils" />
|
||
<p>Source: <a class="reference external" href="https://github.com/python/peps/blob/main/peps/pep-0236.rst">https://github.com/python/peps/blob/main/peps/pep-0236.rst</a></p>
|
||
<p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0236.rst">2023-09-09 17:39:29 GMT</a></p>
|
||
|
||
</article>
|
||
<nav id="pep-sidebar">
|
||
<h2>Contents</h2>
|
||
<ul>
|
||
<li><a class="reference internal" href="#motivation">Motivation</a></li>
|
||
<li><a class="reference internal" href="#intent">Intent</a></li>
|
||
<li><a class="reference internal" href="#syntax">Syntax</a></li>
|
||
<li><a class="reference internal" href="#semantics">Semantics</a></li>
|
||
<li><a class="reference internal" href="#example">Example</a></li>
|
||
<li><a class="reference internal" href="#standard-module-future-py">Standard Module __future__.py</a></li>
|
||
<li><a class="reference internal" href="#resolved-problem-runtime-compilation">Resolved Problem: Runtime Compilation</a></li>
|
||
<li><a class="reference internal" href="#resolved-problem-native-interactive-shells">Resolved Problem: Native Interactive Shells</a></li>
|
||
<li><a class="reference internal" href="#resolved-problem-simulated-interactive-shells">Resolved Problem: Simulated Interactive Shells</a></li>
|
||
<li><a class="reference internal" href="#questions-and-answers">Questions and Answers</a><ul>
|
||
<li><a class="reference internal" href="#what-about-a-from-past-version-to-get-back-old-behavior">What about a “from __past__” version, to get back <em>old</em> behavior?</a></li>
|
||
<li><a class="reference internal" href="#what-about-incompatibilities-due-to-changes-in-the-python-virtual-machine">What about incompatibilities due to changes in the Python virtual machine?</a></li>
|
||
<li><a class="reference internal" href="#what-about-incompatibilities-due-to-changes-in-python-s-c-api">What about incompatibilities due to changes in Python’s C API?</a></li>
|
||
<li><a class="reference internal" href="#i-want-to-wrap-future-statements-in-try-except-blocks-so-i-can-use-different-code-depending-on-which-version-of-python-i-m-running-why-can-t-i">I want to wrap future_statements in try/except blocks, so I can use different code depending on which version of Python I’m running. Why can’t I?</a></li>
|
||
<li><a class="reference internal" href="#going-back-to-the-nested-scopes-example-what-if-release-2-2-comes-along-and-i-still-haven-t-changed-my-code-how-can-i-keep-the-2-1-behavior-then">Going back to the nested_scopes example, what if release 2.2 comes along and I still haven’t changed my code? How can I keep the 2.1 behavior then?</a></li>
|
||
<li><a class="reference internal" href="#overloading-import-sucks-why-not-introduce-a-new-statement-for-this">Overloading <code class="docutils literal notranslate"><span class="pre">import</span></code> sucks. Why not introduce a new statement for this?</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a class="reference internal" href="#copyright">Copyright</a></li>
|
||
<li><a class="reference internal" href="#references-and-footnotes">References and Footnotes</a></li>
|
||
</ul>
|
||
|
||
<br>
|
||
<a id="source" href="https://github.com/python/peps/blob/main/peps/pep-0236.rst">Page Source (GitHub)</a>
|
||
</nav>
|
||
</section>
|
||
<script src="../_static/colour_scheme.js"></script>
|
||
<script src="../_static/wrap_tables.js"></script>
|
||
<script src="../_static/sticky_banner.js"></script>
|
||
</body>
|
||
</html> |