<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
     xmlns:atom="http://www.w3.org/2005/Atom"
     xmlns:dc="http://purl.org/dc/elements/1.1/"
     xmlns:wfw="http://wellformedweb.org/CommentAPI/"
     >
  <channel>
    <title>Let’s Discuss the Matter Further</title>
    <link>http://rhodesmill.org/brandon</link>
    <description>Your Blog's short description</description>
    <pubDate>Thu, 19 Jan 2012 00:48:19 GMT</pubDate>
    <generator>Blogofile</generator>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>PyEphem now available for Python 3.0!</title>
      <link>http://rhodesmill.org/brandon/2008/pyephem-now-available-for-python-30/</link>
      <pubDate>Sat, 13 Dec 2008 02:05:07 EST</pubDate>
      <category><![CDATA[python]]></category>
      <category><![CDATA[pyephem]]></category>
      <category><![CDATA[computing]]></category>
      <guid>http://rhodesmill.org/brandon/?p=27</guid>
      <description>PyEphem now available for Python 3.0!</description>
      <content:encoded><![CDATA[
<p>
Eager not to be left behind by the advance of history,
I have released <a href="http://rhodesmill.org/pyephem/">PyEphem</a>
tonight for Python 3.0!
After updating its C-language routines earlier this week,
as <a
href="http://rhodesmill.org/brandon/2008/porting-a-c-extension-module-to-python-30/">described
in my previous post</a>,
and adjusting its Python syntax,
I thought that my work was done —
until I received a bug report from Reto Schüttel,
an enterprising Swiss programmer.
He had read my previous post,
asked me for the location of PyEphem's <a
href="https://code.launchpad.net/~brandon-rhodes/pyephem/python-3">Python 3.0
branch</a>,
downloaded it with <a href="http://bazaar-vcs.org/">bzr</a>,
and already tried it out, not only on his Linux machine,
but <i>also</i> on his OS X machine!
</p>
<p>
While the <a
href="http://bazaar.launchpad.net/~brandon-rhodes/pyephem/python-3/changes/419?start_revid=419">first
twenty revisions</a> of my branch deal with simple Python 3.0 mechanics,
I must congratulate Mr. Schüttel
for most of the improvements in the <a
href="http://bazaar.launchpad.net/~brandon-rhodes/pyephem/python-3/changes/431?start_revid=431">subsequent
dozen revisions</a>.
We not only exchanged emails all day
as I produced one revision after another
that I needed him to test,
but he then joined me on IRC tonight until 3:30am in his time zone
as we worked out the last problems.
</p>
<p>
The issues were all related to localization under OS X.
The astronomy library underlying PyEphem used the C-language functions
<tt>sscanf()</tt> and <tt>atof()</tt>
to turn strings into numbers,
and it turns out that these functions are very sensitive to locale
under the specific combination of OS X and Python 3.0!
Because of his locale,
the functions wanted a comma instead of a period
to separate whole numbers from their decimal fraction
(so that <i>π</i> would have to be input like <tt>3,141</tt>
rather than like <tt>3.141</tt>).
They also wanted month name abbreviations
to be in German rather than English,
ruining my test cases
that check planet positions against
<a href="http://www.usno.navy.mil/">Naval Observatory</a> tables
which use English month abbreviations
like <i>Jan</i>, <i>Feb</i>, and <i>Mar</i>
with very little regard for how the months would be spelled in German.
We are still mystified by the combination of Python version
and operation system that were necessary to cause this problem:
</p>
<pre>
Python 2.6 under Linux: tests passed
Python 3.0 under Linux: tests passed
Python 2.6 under OS X: tests passed
Python 3.0 under OS X: <b>broken: sscanf()/atof() change with locale</b>
</pre>
<p>
But the tests worked fine if he put <tt>LANG=C</tt> on the command line.
</p>
<p>
To work around this problem,
I discovered a wonderful <tt>PyOS_ascii_strtod()</tt> function
in Python's C library that avoided all of the problems
that I was having with localization,
and so I gradually rewrote the astronomy routines
to use that function instead.
Fixing the problems with month names was easier;
instead of trying to make Python convert month abbreviations
by passing the <tt>'%b'</tt> conversion character
to <tt>time.strptime()</tt>,
I simply converted months to integers myself
and then passed the integers in
with the simpler <tt>'%m'</tt> format character.
It was only late at night
that we finally tracked down every routine that was misbehaving.
</p>
<p>
The final puzzle was how to release my new software.
The <a href="http://pypi.python.org/pypi">Python Package Index</a>
does not yet allow a project to offer separate source code archives
for both the Python 2.x and the 3.0 version of a project.
There might be some clever way
of storing both versions of the source code
in the same <tt>.tar.gz</tt> file,
but the packages I see on PyPI that already support both 2.x and 3.0
contain enough <tt>#ifdef</tt> statements
to convince me that I want to keep my branches separate!
</p>
<p>
I was saved by a peculiarity of my project.
Though it provides the Python <i>package</i> named <tt>ephem</tt>,
the actual <i>project</i> on PyPI
has always been named “PyEphem” instead.
The product has to have the “Py” in front, you see,
to distinguish it
both from the original text-screen <tt>ephem</tt> command
and the modern
<a href="http://www.clearskyinstitute.com/xephem/">XEphem</a>
graphical application,
and my first instinct had been to name the project after the product.
But as I gained experience with PyPI,
it seemed more and more awkward
that programmers who wanted their programs to be able to:
</p>
<pre>import ephem</pre>
<p>
had to remember to type something different when installing:
</p>
<pre>easy_install pyephem</pre>
<p>
Since I had been wanting to switch PyPI names anyway,
I suddenly saw my chance!
I have now released the new Python 3.0 version of PyEphem
<a href="http://pypi.python.org/pypi/ephem/">under
the actual package name <i>ephem</i></a>
and will continue to maintain the 2.x version of the package
separately under
<a href="http://pypi.python.org/pypi/pyephem/">the old <i>pyephem</i>
name</a>.
Obviously,
this solution only works because of my project's unique circumstances;
I have no idea what other projects should do
who also want to come out with their new Python 3.0 versions
this weekend.
</p>
<p>
Fans of PyEphem should rest assured
that when I develop new features,
I will be adding them to <i>both</i> versions
of PyEphem for probably at least the next decade.
I have absolutely no intention of abandoning or slowing development
of the Python 2.x version of the library;
I simply wanted the library available to users of the new platform.
As always,
feel free to email me with bugs, suggestions, and new features —
and, enjoy using PyEphem and Python!
</p>]]></content:encoded>
    </item>
    <item>
      <title>Porting a C extension module to Python 3.0</title>
      <link>http://rhodesmill.org/brandon/2008/porting-a-c-extension-module-to-python-30/</link>
      <pubDate>Tue, 09 Dec 2008 04:18:16 EST</pubDate>
      <category><![CDATA[python]]></category>
      <category><![CDATA[grok]]></category>
      <category><![CDATA[pyephem]]></category>
      <category><![CDATA[zope]]></category>
      <category><![CDATA[computing]]></category>
      <guid>http://rhodesmill.org/brandon/?p=25</guid>
      <description>Porting a C extension module to Python 3.0</description>
      <content:encoded><![CDATA[
<p>
With several packages already advertising
<a href="http://pypi.python.org/pypi?:action=browse&c=214&c=534"
 >Python 3.0 compatibility</a>,
it seemed high time to look into releasing my
<a href="http://rhodesmill.org/pyephem/">PyEphem astronomy package</a>
in an edition compatible with the new language.
But I hesitated:
how difficult is it <i>really</i>,
and how many hours of work will it consume,
to port a C-language extension module to Python 3.0?
</p>
<p>
The answer is that,
while the necessary changes were surprisingly easy,
they took lots of time to figure out
because I did not find them documented in any one place.
I offer the following notes to assist
any other adventurers who want to experiment
with porting their extension modules to 3.0.
These notes might also suggest
useful additions to the official documentation.
</p>
<p>
But, first, I need to issue three cautions.
To develop under 3.0, you may have to forego several Python tools
that you probably thought you could no longer do without.
The world of 3.0 is a windswept and icy landscape
from which the glaciers have just receded,
and you will find the stone tools rather primitive
when compared to the comforts of civilization
that you enjoy under Python 2.
To wit:
</p>
<ul>
<li>I cannot find
 <a href="http://pypi.python.org/pypi/virtualenv/1.3.1">virtualenv</a>
 for 3.0,
 which is a disaster.
 This means that you have to create a separate Python 3.0 install,
 built with a different <tt>--prefix</tt> option to <tt>./configure</tt>,
 for each development environment you want to create on your box.
</li>
<li>I cannot find a version of the
 <a href="http://peak.telecommunity.com/DevCenter/setuptools">setuptools</a>
 available for 3.0.
 This means limiting your <tt>setup.py</tt> instructions
 to the primitive vocabulary of the <tt>distutils</tt> package.
 For example,
 I find myself unable to run the PyEphem test suite at this late hour
 because I have been running it for so long with:
 <pre>$ python setup.py test</pre>
 that I am not sure how to get it running otherwise.
</li>
<li>Should you succeed in porting your extension module,
 it is not at <i>all</i> clear how to distribute it.
 I had expected either a new PyPI to spring into being —
 since every package will need an entirely different version under 3.0 —
 or for a sophisticated scheme to appear
 for registering one <tt>pyephem.tar.gz</tt> as the Python 2 version
 and another <tt>pyephem.tar.gz</tt> for 3.0.
 But while the most recent version of your package can
 mark itself as
 <a href="http://pypi.python.org/pypi?:action=browse&c=214&c=527"
  >2-compatible</a> or
 <a href="http://pypi.python.org/pypi?:action=browse&c=214&c=533"
  >3-compatible</a> (or both)
 using classifiers,
 there is no way to have <i>two</i> “most recent” versions
 of a package.
 Are we supposed to start distributing a single <tt>tar.gz</tt>
 that includes the source code for both Python series,
 and that selects the right code by detecting the interpreter version
 at the top of the <tt>setup.py</tt> file?
</li>
</ul>
<p>
So if you make the effort to port your code right now,
you might find that the shiny new version of your module
is all dressed up, but has no place to go.
If you experiment with the following steps, though,
you will at least be ready
when an official distribution channel does appear
for releasing your package into the wilds of 3.0.
</p>
<!--more-->
<h2>Four Steps To 3.0</h2>
<p>
Yes, four steps were all that were necessary
to convert my quite complex extension module to Python 3.0!
</p>
<ol>
<li><b>Use PyModule_Create().</b>
 The old mechanism that I had been using
 to initialize my extension module,
 the rather clunkily-named <tt>Py_InitModule3()</tt>,
 happily does not even exist in the Python 3.0 header files.
 Instead, call the <tt>PyModule_Create()</tt> function
 which you can find described
 in the <a href="http://docs.python.org/3.0/extending/extending.html#the-module-s-method-table-and-initialization-function"
  >Module Initialization</a>
 section of the <a href="http://docs.python.org/3.0/extending/"
  >Extending and Embedding</a> document.
 And be sure to keep its return value:
 unlike in older Pythons,
 you now have to return the module object it creates
 as the return value from your module initialization function.
</li>
<li>
 <p>
 <b>Adjust all Python object headers.</b>
 Each type object in my code started with a macro
 to set up the common fields that all Python objects share.
 This was then followed by the <b>ob_size</b> field,
 which in my code always is always zero,
 and then the type name:
 </p>

<div class="pygments_murphy syntax_highlight"><pre><span class="cm">/* For Python 2 */</span><br/><br/><span class="k">static</span> <span class="n">PyTypeObject</span> <span class="n">BinaryStarType</span> <span class="o">=</span> <span class="p">{</span><br/>     <span class="n">PyObject_HEAD_INIT</span><span class="p">(</span><span class="nb">NULL</span><span class="p">)</span><br/>     <span class="mi">0</span><span class="p">,</span>                   <span class="cm">/* ob_size */</span><br/>     <span class="s">&quot;ephem.BinaryStar&quot;</span><span class="p">,</span>  <span class="cm">/* tp_name */</span><br/>     <span class="p">...</span><br/></pre></div>


 <p>
 Though the Python 3.0 documentation
 <a href="http://docs.python.org/3.0/extending/newtypes.html"
  ><i>still</i> shows this as the way to create types</a>,
 this technique will now completely fail.
 (The <a href="http://bugs.python.org/issue4385">bug indicating
 that the documentation gets this wrong</a> has,
 as its most recent comment,
 the helpful note
 “I'm lowering the priority so it doesn't block the release.”)
 Anyway, the solution is simple:
 the first two lines in the struct shown above
 simply have to be combined into a single macro call:
 </p>

<div class="pygments_murphy syntax_highlight"><pre><span class="cm">/* For Python 3.0 */</span><br/><br/><span class="k">static</span> <span class="n">PyTypeObject</span> <span class="n">BinaryStarType</span> <span class="o">=</span> <span class="p">{</span><br/>     <span class="n">PyVarObject_HEAD_INIT</span><span class="p">(</span><span class="nb">NULL</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span><br/>     <span class="s">&quot;ephem.BinaryStar&quot;</span><span class="p">,</span>  <span class="cm">/* tp_name */</span><br/>     <span class="p">...</span><br/></pre></div>


 <p>
 With this change, my objects are now operating fine.
 </p>
</li>
<li><b>Use plain “static.”</b>
 PyEphem inherits code from an era
 when it was popular to use variations on the <tt>static</tt> keyword
 so that Python could work around problems
 with various troublesome C compilers.
 This filled my code with <tt>staticforward</tt> declarations
 like the one you can see at the top of the old Python 2.2
 <a href="http://www.python.org/doc/2.2/ext/dnt-basics.html"
  >Defining New Types</a> page.
 It turns out that for well-behaved compilers
 these were always simply synonyms for the <tt>static</tt> keyword,
 which is what you must replace them with
 when porting your code to 3.0.
</li>
<li><b>Upgrade to Unicode.</b>
 Python 3.0 makes a clean and sharp distinction
 between strings, which are sequences of Unicode characters,
 and byte arrays, which can represent anything.
 To reflect this sea change down at the C level,
 the decision was made
 to eliminate <i>everything</i> from the C API
 whose name started with <tt>PyString</tt>.
 The obvious compiler errors that result from this
 provide a clear signal to programmers
 that they have to decide,
 everywhere that they had been using an old-style Python string,
 whether they should now represent that data
 with the <tt>PyUnicode</tt> or the <tt>PyBytes</tt> type.
 This was a brilliant decision;
 the transition could have been a nightmare
 had it remained possible for old code to compile
 without having been properly converted!
 <p>
 When migrating the PyEphem code base,
 I found that most of the Unicode transition was very easy.
 Everywhere that my code handled or created a string object,
 I simply changed the prefix of the function to <tt>PyUnicode</tt>
 and everything worked:
 </p>
 <pre>
 PyString_Check      ... becomes ... PyUnicode_Check
 PyString_FromString ... becomes ... PyUnicode_FromString
 PyString_FromFormat ... becomes ... PyUnicode_FromFormat
</pre>
 <p>
 Well, okay, the trick does not work <i>everywhere</i>;
 this one was harder to guess:
 </p>
 <pre>
 PyString_Size ... becomes ... PyUnicode_GET_SIZE
</pre>
 <p>
 The situations that require real thought
 are the places where my code needs to convert a Python string
 into the sort of simple ASCII character array
 that the underlying C library can absorb.
 At the moment, my code is leaning heavily
 on a pitiful <tt>PyUnicode_AsString()</tt> routine
 that I wrote just to get things working;
 in the morning I will have to look into doing this more correctly,
 including catching the error if a fancy Unicode character is present
 that cannot properly be converted.
 </p>
</li>
</ol>
<p>
Overall, I am very impressed with how quickly
I was able to get my extension module compiling and running
under Python 3.0.
The procedure was simple —
I just tried, over and over again, to build the module with:
</p>
<pre>
$ python3.0 setup.py build
</pre>
<p>
and then tackled the compiler errors that resulted.
Once every last warning had been addressed,
the module started up and operated without a single further complaint.
This calls for celebration!
I'm going to bed.
</p>
]]></content:encoded>
    </item>
    <item>
      <title>PyEphem 3.7.2.4, now on Launchpad!</title>
      <link>http://rhodesmill.org/brandon/2008/pyephem-3724-now-on-launchpad/</link>
      <pubDate>Sat, 14 Jun 2008 13:39:57 EDT</pubDate>
      <category><![CDATA[python]]></category>
      <category><![CDATA[pyephem]]></category>
      <category><![CDATA[web notes]]></category>
      <category><![CDATA[computing]]></category>
      <guid>http://rhodesmill.org/brandon/?p=19</guid>
      <description>PyEphem 3.7.2.4, now on Launchpad!</description>
      <content:encoded><![CDATA[
<p><img style="float: right;"
 src="http://rhodesmill.org/pyephem/_static/pyephem-logo-short.png"
 alt="PyEphem logo" />
I have decided to give my
<a href="http://rhodesmill.org/pyephem">PyEphem
astronomy library for Python</a>
a public source code repository,
an open forum for user questions,
and a bug tracker where my users
can see the progress of their bug reports out in the open
rather than having them scattered across our email inboxes.
To accomplish all of this,
I simply registered PyEphem with
<a href="http://launchpad.net/">Launchpad</a>,
a site built to host software projects
that is already used by several projects for which I have great respect.
</p>

<p>
Because users might become confused
now that PyEphem is spread across <i>three</i> web sites —
the home page is here at rhodesmill.org,
releases are posted over at the
<a href="http://www.python.org/pypi">Python Package Index</a>,
and, again, the development project is now hosted at Launchpad —
I have completely
<a href="http://rhodesmill.org/pyephem">redesigned the PyEphem home
page</a> with the goal of making the three-site distinction
clear, coherent, and easy to navigate.
The new home page and documentation
are generated by the wonderful
<a href="http://sphinx.pocoo.org/">Sphinx documentation engine</a>,
and I am still thrilled about how pretty my code samples look
(check out the one on the PyEphem home page!)
now that Sphinx is coloring them in with the renowned
<a href="http://pygments.org/">Pygments</a> system.
</p>

<p>
I have simultaneously released a new version of PyEphem
that includes the new Sphinx-based documentation,
along with several important fixes to the software itself.
From now on,
rather than cluttering my own blog
with every minor version of PyEphem that I might release,
fans of the software should visit its
<a href="https://launchpad.net/pyephem/+announcements">News and
announcements</a> page on Launchpad
and subscribe themselves to its
<a href="http://feeds.launchpad.net/pyephem/announcements.atom">Atom/RSS
feed</a>.
You will still see the project mentioned here
whenever a technical or scientific issue
becomes interesting enough for me to write about;
but the audience of astronomers and hobbyists
who just need to know when the next version is released
should not have to wade through my blog to do so!
</p>

<p>
My users have already begun transferring
their questions and problems to Lauchpad,
and I look forward to offering much greater accountability
through a fully public development process.
</p>]]></content:encoded>
    </item>
    <item>
      <title>New PyEphem release: 3.7.2.2</title>
      <link>http://rhodesmill.org/brandon/2007/new-pyephem-release-3722/</link>
      <pubDate>Tue, 11 Dec 2007 09:42:07 EST</pubDate>
      <category><![CDATA[pyephem]]></category>
      <category><![CDATA[computing]]></category>
      <guid>http://rhodesmill.org/brandon/2007/new-pyephem-release-3722/</guid>
      <description>New PyEphem release: 3.7.2.2</description>
      <content:encoded><![CDATA[
On Sunday afternoon I released a new version of <a href="http://rhodesmill.org/pyephem/">PyEphem</a>, which is available from the Python Package Index as <a href="http://pypi.python.org/pypi/pyephem/3.7.2.2">version 3.7.2.2</a>!  I want to thank the users who spurred its development&nbsp;— in particular, <a href="http://asemonline.org/archives/category/members-pages/john-ducheks-pages/">John Duchek</a> of the Astronomical Society of Eastern Missouri encouraged me both to create the new moon-phase functions, and, as I <a href="http://rhodesmill.org/brandon/2007/pyephem-available-for-windows/">announced</a> several weeks ago, to finally make PyEphem available in binary form for Windows.  Thanks, John!

PyEphem now also includes a small database of world cities, so that people living near one can simply call <tt>ephem.city('Boston')</tt> to get their longitude, latitude, and elevation, rather than having to look up the numbers themselves.]]></content:encoded>
    </item>
    <item>
      <title>PyEphem available for Windows!</title>
      <link>http://rhodesmill.org/brandon/2007/pyephem-available-for-windows/</link>
      <pubDate>Fri, 09 Nov 2007 11:10:25 EST</pubDate>
      <category><![CDATA[python]]></category>
      <category><![CDATA[pyephem]]></category>
      <category><![CDATA[computing]]></category>
      <guid>http://rhodesmill.org/brandon/2007/pyephem-available-for-windows/</guid>
      <description>PyEphem available for Windows!</description>
      <content:encoded><![CDATA[
Over the years I have received many requests from frustrated Windows users, asking for a Windows-native version of my <a href="http://rhodesmill.org/pyephem/">PyEphem</a> astronomy library for Python. For most Windows users, an attempt to build the extension ends abruptly with the terrible and famous message:

<blockquote><tt>error: Python was built with version 7.1 of Visual Studio, and extensions need to be built with the same version of the compiler, but it isn't installed.</tt></blockquote>

And, as I myself do not have Visual Studio on the small Windows machine that I deign to own for the sake of my photo printer, I have never been able to offer my users much help. But earlier this year, a helpful PyEphem user named Jeff Kowalczyk emailed me a link to Philip von Weitershausen's post <a href="http://www.z3lab.org/sections/blogs/philipp-weitershausen/2007_07_26_cheap-binary-windows">“Cheap binary Windows eggs”</a>, which describes a method for building Python extensions using a freely available compiler.

<!--more-->

Aside from the difficulty that the Python setuptools ignored the <tt>pydistutils.cfg</tt> file he recommended, making it necessary for me to name the compiler on the command line, his instructions produced a PyEphem windows egg with only a few steps:

<ul>
<li>I installed <a href="http://www.python.org/download/windows/">Python for Windows</a>.</li>
<li>I installed the <a href="http://cheeseshop.python.org/pypi/setuptools/">setuptools package</a> using its Windows <tt class="docutils literal"><span class="pre">.exe</span></tt> installer (scroll down the page to find it).</li>
<li>I installed the <a href="http://www.mingw.org/">MinGW compiler</a>.</li>
<li>I installed <a href="http://gnuwin32.sourceforge.net/packages/libarchive.htm">LibArchive for Windows</a>.</li>
<li>I added to my Windows <tt class="docutils literal"><span class="pre">Path</span></tt>:
<pre>C:\Python25;C:\MingW\bin;C:\Program Files\GnuWin32\bin</pre>
</li>
<li>I downloaded the <a href="http://rhodesmill.org/pyephem/">PyEphem</a> source archive.</li>
<li>I brought up a command window and ran:
<pre>
C:\dev&gt; bsdtar -xf pyephem-3.7.2.1.tar.gz
C:\dev&gt; cd pyephem-3.7.2.1
C:\dev\pyephem-3.7.2.1&gt; python setup.py build --compiler=mingw32
C:\dev\pyephem-3.7.2.1&gt; python setup.py bdist_egg
</pre>
</li>
<li>I uploaded the egg in the <tt>dist</tt> directory to the Cheese Shop.</li>
</ul>

Windows users will now find my Windows binary eggs on the <a href="http://pypi.python.org/pypi/pyephem/">Cheese Shop PyEphem entry</a>!

Always keep in mind that behind a small triumph like this one for a Free Software developer like myself stands a great mountain-mass of work by hundreds of others in the community. In this case one helpful user lead to one informative blog post which lead to a solid and available tool&nbsp;— MinGW&nbsp;— that is a descendant of the GCC compiler Richard Stallman himself started writing over twenty years ago! All of which allowed the delivery, to a new (and closed) platform, of my Python interface to <a href="http://www.clearskyinstitute.com/xephem/index.html">astronomy routines</a> which <a href="http://www.clearskyinstitute.com/resumes/ecdowney/resume.html">Elwood Charles Downey</a> has been maintaining for more than a quarter-century.]]></content:encoded>
    </item>
  </channel>
</rss>

