python-peps/pep-0236/index.html

467 lines
37 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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> &raquo; </li>
<li><a href="../pep-0000/">PEP Index</a> &raquo; </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 &lt;tim.peters&#32;&#97;t&#32;gmail.com&gt;</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 Pythons 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 Im running. Why cant 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 havent 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 its 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">&quot;from&quot;</span> <span class="s2">&quot;__future__&quot;</span> <span class="s2">&quot;import&quot;</span> <span class="n">feature</span> <span class="p">[</span><span class="s2">&quot;as&quot;</span> <span class="n">name</span><span class="p">]</span>
<span class="p">(</span><span class="s2">&quot;,&quot;</span><span class="n">feature</span> <span class="p">[</span><span class="s2">&quot;as&quot;</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">&quot;&quot;&quot;This is a module docstring.&quot;&quot;&quot;</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; its 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">&quot;x is&quot;</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 theyre 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">&quot;_Feature(&quot;</span> <span class="n">OptionalRelease</span> <span class="s2">&quot;,&quot;</span> <span class="n">MandatoryRelease</span> <span class="s2">&quot;)&quot;</span>
</pre></div>
</div>
<p>where, normally, <em>OptionalRelease</em> &lt; <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"># &quot;alpha&quot;, &quot;beta&quot;, &quot;candidate&quot; or &quot;final&quot;; 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">&quot;beta&quot;</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">&quot;final&quot;</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 modules 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 isnt 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 Ms
choices, not necessarily the doctest modules choices. In the 2.1 release,
this isnt 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 cant
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 sessions 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 isnt 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 dont 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 Pythons 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 Im running. Why cant 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> wouldnt
accomplish what it <em>looks</em> like it should accomplish, its 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 youre
running under stands in relation to a given features 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 havent 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 dont hate you
if you dont, 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 cant 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 wont 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 &gt;= 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 Pythons 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 Im running. Why cant 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 havent 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>