buffer interface problem

Chris Rebert crebert at ucsd.edu
Thu Jan 7 14:03:56 CET 2010


On Thu, Jan 7, 2010 at 4:47 AM, Andrew Gillanders
<andrew.gillanders at uqconnect.edu.au> wrote:
> On 07/01/2010, at 7:13 PM, Chris Rebert wrote:
>> On Thu, Jan 7, 2010 at 12:19 AM, Andrew Gillanders
>> <andrew.gillanders at uqconnect.edu.au> wrote:
>>>
>>> I have run into a problem running a Python script that is part of the
>>> TerraGear suite for building scenery for FlightGear. I am using Mac OS X
>>> 10.4, running Python (version 3.0.1) in a Unix terminal.
>>>
>>> The purpose of the script is to walk a directory tree, unzipping files,
>>> and
>>> passing the contents to an executable C program. The problem occurs here:
>>>
>>>   gzin = GzipFile(fname, 'rb')
>>>   data = gzin.readline()
>>>   min_x,min_y = map(atoi,data.split()[:2])
>>>
>>> The input file, when uncompressed, is an ASCII file with a line with two
>>> numbers, then a line of four numbers, then many long lines of numbers. I
>>> can
>>> see what the last is trying to do: split the string into two words,
>>> convert
>>> them to integers, and assign them to min_x and min_y.
>>>
>>> At the third line, I get the message "expected an object with the buffer
>>> interface". Which object is it referring to?
>>
>> The elements of the list produced by `data.split()[:2]`, which are
>> either Unicode strings or bytestrings, neither of which are buffers.
>>
>>> Have some functions been
>>> changed to pass buffer objects instead of strings? How can I fix the
>>> source
>>> code to make it run?
>>
>> The error is being raised by the atoi() function (in the future,
>> please post the full Traceback, not just the final error message).
>> What module/library does your atoi() function come from (look for an
>> `import` statement mentioning it)?
>> The only functions by that name in the Python standard library both
>> operate on strings, not buffers, and thus can't be the same one your
>> code is using.
>>
>> In any case, replacing `atoi` with `int` in your code will likely
>> solve the problem. The built-in int() function* can convert strings to
>> integers.

> Thanks Chris. The atoi function was coming from the locale library (from
> locale import atoi). I changed it to int and now it works.

Hm, that's odd since it was one of the 2 functions in the std lib
which the docs say operates on strings...

> The next hurdle is this:
>    gzin = GzipFile(fname, 'rb')
>
>    data = gzin.readline()
> #    min_x,min_y = map(atoi,data.split()[:2])
>    min_x,min_y = map(int,data.split()[:2])
>
>    data = gzin.readline()
> #    span_x,step_x,span_y,step_y = map(atoi,data.split()[:4])
>    span_x,step_x,span_y,step_y = map(int,data.split()[:4])
>
>    data = gzin.read().split('\n')
>
> The last line is a problem, giving me this message: Type str doesn't support
> the buffer API (I am guessing a conflict between split and read?)

Ah, looking at the 3.0 docs on buffers, I'd surmise gzin.read()
returns bytes (http://docs.python.org/3.1/library/functions.html#bytes)
rather than a string.
You'll want to decode the bytes into characters first, and then you
can operate on the resulting string normally.
Try:

data = gzin.read().decode('ascii').split('\n')

> Sorry, I am new to Python, so how do I get a Traceback?

You should get one by default. Are you running the script in some
environment other than the command line?

Here's what a traceback looks like:

Traceback (most recent call last):
  File "foo", line 161, in <module>
    main()
  File "foo.py", line 157, in main
    bot.run()
  File "foo.py", line 68, in bar
    self.baz("Enter number: ")
  File "foo.py", line 112, in baz
    choice = int(raw_input(prompt))-1
ValueError: invalid literal for int() with base 10: 'y'

Cheers,
Chris
--
http://blog.rebertia.com



More information about the Python-list mailing list