<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Python IMPORT_NAME bytecode mystery</title>
	<atom:link href="http://probablyprogramming.com/2008/04/14/python-import_name/feed/" rel="self" type="application/rss+xml" />
	<link>http://probablyprogramming.com/2008/04/14/python-import_name/</link>
	<description>It&#039;s what I&#039;m doing, and what posts on this blog are about.</description>
	<lastBuildDate>Sat, 05 Jun 2010 21:26:13 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: Thomas Lee &#187; The Internals of Python&#8217;s IMPORT_NAME Bytecode</title>
		<link>http://probablyprogramming.com/2008/04/14/python-import_name/comment-page-1/#comment-504</link>
		<dc:creator>Thomas Lee &#187; The Internals of Python&#8217;s IMPORT_NAME Bytecode</dc:creator>
		<pubDate>Mon, 14 Apr 2008 10:18:12 +0000</pubDate>
		<guid isPermaLink="false">http://probablyprogramming.com/?p=73#comment-504</guid>
		<description>&lt;p&gt;[...] was originally planned as a response to this post by Paul Bonser, but grew a little unwieldy (and his comment submission form seems to be [...]&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>[...] was originally planned as a response to this post by Paul Bonser, but grew a little unwieldy (and his comment submission form seems to be [...]</p>]]></content:encoded>
	</item>
	<item>
		<title>By: Thomas Lee</title>
		<link>http://probablyprogramming.com/2008/04/14/python-import_name/comment-page-1/#comment-503</link>
		<dc:creator>Thomas Lee</dc:creator>
		<pubDate>Mon, 14 Apr 2008 09:50:57 +0000</pubDate>
		<guid isPermaLink="false">http://probablyprogramming.com/?p=73#comment-503</guid>
		<description>&lt;p&gt;The documentation for &lt;strong&gt;import&lt;/strong&gt; solves this mystery (well, sort of!):&lt;/p&gt;

&lt;p&gt;http://docs.python.org/lib/built-in-funcs.html&lt;/p&gt;

&lt;p&gt;&quot;Note that even though locals() and [&#039;eggs&#039;] are passed in as arguments, the &lt;strong&gt;import&lt;/strong&gt;() function does not set the local variable named eggs; this is done by subsequent code that is generated for the import statement. (In fact, the standard implementation does not use its locals argument at all, and uses its globals only to determine the package context of the import statement.)&quot;&lt;/p&gt;

&lt;p&gt;Essentially, when the IMPORT_NAME is executed for &#039;from foo import bar, baz&#039;, the &lt;strong&gt;import&lt;/strong&gt; builtin is called with the fromlist (which is converted to a tuple of strings). to provide custom import handling for your Python programs. For example, you may want to prevent users of your program from writing scripts that import certain modules.&lt;/p&gt;

&lt;p&gt;The code in Python/ceval.c for IMPORT_NAME seems to back this up (I&#039;ve annotated it with a few comments ...):&lt;/p&gt;

&lt;pre lang=&quot;c&quot;&gt;    case IMPORT_NAME:
        w = GETITEM(names, oparg);
        /* 1. LOCATE THE __import__ BUILTIN */
        x = PyDict_GetItemString(f-&gt;f_builtins, &quot;__import__&quot;);
        if (x == NULL) {
            PyErr_SetString(PyExc_ImportError,
                    &quot;__import__ not found&quot;);
            break;
        }
        Py_INCREF(x);
        v = POP();
        u = TOP();
        /* 2. BUILD THE LIST OF ARGUMENTS FOR __import__ USING THE fromlist, globals() AND locals() */
        if (PyInt_AsLong(u) != -1 &#124;&#124; PyErr_Occurred())
            w = PyTuple_Pack(5,
                    w,
                    f-&gt;f_globals,
                    f-&gt;f_locals == NULL ?
                      Py_None : f-&gt;f_locals,
                    v,
                    u);
        else
            w = PyTuple_Pack(4,
                    w,
                    f-&gt;f_globals,
                    f-&gt;f_locals == NULL ?
                      Py_None : f-&gt;f_locals,
                    v);
        Py_DECREF(v);
        Py_DECREF(u);
        if (w == NULL) {
            u = POP();
            Py_DECREF(x);
            x = NULL;
            break;
        }
        READ_TIMESTAMP(intr0);
        v = x;
        /* 3. CALL __import__ */
        x = PyEval_CallObject(v, w);
        Py_DECREF(v);
        READ_TIMESTAMP(intr1);
        Py_DECREF(w);
        SET_TOP(x);
        if (x != NULL) continue;
        break;
&lt;/pre&gt;

&lt;p&gt;(hope the code looks okay - you need a &quot;preview&quot; feature :P)&lt;/p&gt;
</description>
		<content:encoded><![CDATA[<p>The documentation for <strong>import</strong> solves this mystery (well, sort of!):</p>

<p><a href="http://docs.python.org/lib/built-in-funcs.html" rel="nofollow">http://docs.python.org/lib/built-in-funcs.html</a></p>

<p>&#8220;Note that even though locals() and ['eggs'] are passed in as arguments, the <strong>import</strong>() function does not set the local variable named eggs; this is done by subsequent code that is generated for the import statement. (In fact, the standard implementation does not use its locals argument at all, and uses its globals only to determine the package context of the import statement.)&#8221;</p>

<p>Essentially, when the IMPORT_NAME is executed for &#8216;from foo import bar, baz&#8217;, the <strong>import</strong> builtin is called with the fromlist (which is converted to a tuple of strings). to provide custom import handling for your Python programs. For example, you may want to prevent users of your program from writing scripts that import certain modules.</p>

<p>The code in Python/ceval.c for IMPORT_NAME seems to back this up (I&#8217;ve annotated it with a few comments &#8230;):</p>


<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">    <span style="color: #b1b100;">case</span> IMPORT_NAME<span style="color: #339933;">:</span>
        w <span style="color: #339933;">=</span> GETITEM<span style="color: #009900;">&#40;</span>names<span style="color: #339933;">,</span> oparg<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #808080; font-style: italic;">/* 1. LOCATE THE __import__ BUILTIN */</span>
        x <span style="color: #339933;">=</span> PyDict_GetItemString<span style="color: #009900;">&#40;</span>f<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>f_builtins<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;__import__&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>x <span style="color: #339933;">==</span> NULL<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            PyErr_SetString<span style="color: #009900;">&#40;</span>PyExc_ImportError<span style="color: #339933;">,</span>
                    <span style="color: #ff0000;">&quot;__import__ not found&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        Py_INCREF<span style="color: #009900;">&#40;</span>x<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        v <span style="color: #339933;">=</span> POP<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        u <span style="color: #339933;">=</span> TOP<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #808080; font-style: italic;">/* 2. BUILD THE LIST OF ARGUMENTS FOR __import__ USING THE fromlist, globals() AND locals() */</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>PyInt_AsLong<span style="color: #009900;">&#40;</span>u<span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #339933;">-</span><span style="color: #0000dd;">1</span> <span style="color: #339933;">||</span> PyErr_Occurred<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
            w <span style="color: #339933;">=</span> PyTuple_Pack<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">5</span><span style="color: #339933;">,</span>
                    w<span style="color: #339933;">,</span>
                    f<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>f_globals<span style="color: #339933;">,</span>
                    f<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>f_locals <span style="color: #339933;">==</span> NULL <span style="color: #339933;">?</span>
                      Py_None <span style="color: #339933;">:</span> f<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>f_locals<span style="color: #339933;">,</span>
                    v<span style="color: #339933;">,</span>
                    u<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">else</span>
            w <span style="color: #339933;">=</span> PyTuple_Pack<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">4</span><span style="color: #339933;">,</span>
                    w<span style="color: #339933;">,</span>
                    f<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>f_globals<span style="color: #339933;">,</span>
                    f<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>f_locals <span style="color: #339933;">==</span> NULL <span style="color: #339933;">?</span>
                      Py_None <span style="color: #339933;">:</span> f<span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>f_locals<span style="color: #339933;">,</span>
                    v<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        Py_DECREF<span style="color: #009900;">&#40;</span>v<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        Py_DECREF<span style="color: #009900;">&#40;</span>u<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>w <span style="color: #339933;">==</span> NULL<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            u <span style="color: #339933;">=</span> POP<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            Py_DECREF<span style="color: #009900;">&#40;</span>x<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            x <span style="color: #339933;">=</span> NULL<span style="color: #339933;">;</span>
            <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        READ_TIMESTAMP<span style="color: #009900;">&#40;</span>intr0<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        v <span style="color: #339933;">=</span> x<span style="color: #339933;">;</span>
        <span style="color: #808080; font-style: italic;">/* 3. CALL __import__ */</span>
        x <span style="color: #339933;">=</span> PyEval_CallObject<span style="color: #009900;">&#40;</span>v<span style="color: #339933;">,</span> w<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        Py_DECREF<span style="color: #009900;">&#40;</span>v<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        READ_TIMESTAMP<span style="color: #009900;">&#40;</span>intr1<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        Py_DECREF<span style="color: #009900;">&#40;</span>w<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        SET_TOP<span style="color: #009900;">&#40;</span>x<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>x <span style="color: #339933;">!=</span> NULL<span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">continue</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span></pre></div></div>




<p>(hope the code looks okay &#8211; you need a &#8220;preview&#8221; feature <img src='http://probablyprogramming.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> )</p>]]></content:encoded>
	</item>
</channel>
</rss>
