Re: [Python-Dev] Py_BuildValue and decref

2006-09-11 Thread Mihai Ibanescu
On Sun, Sep 10, 2006 at 07:35:59PM +1200, Greg Ewing wrote:
 Barry Warsaw wrote:
  I just want to point out that the C API documentation is pretty  
  silent about the refcounting side-effects in error conditions (and  
  often in success conditions too) of most Python functions.  For  
  example, what is the refcounting side-effects of PyDict_SetItem() on  
  val?  What about if that function fails?  Has val been incref'd or  
  not?  What about the side-effects on any value the new one replaces,  
  both in success and failure?
 
 The usual principle is that the refcounting behaviour
 is (or should be) independent of whether the function
 succeeded or failed. In the absence of any statement
 to the contrary in the docs, you should be able to
 assume that.
 
 The words used to describe the refcount behaviour of
 some functions can be rather confusing, but it always
 boils down to one of two cases: either the function
 borrows a reference (and does its own incref if
 needed, the caller doesn't need to care) or it steals
 a reference (so the caller is always responsible for
 doing an incref if needed before calling).
 
 What that rather convoluted comment about PyTuple_SetItem
 is trying to say is just that it *always* steals a reference,
 regardless of whether it succeeds or fails. I expect the
 same is true of Py_BuildValue.

Given that it doesn't seem to be the case, and my quick look at the code
indicates that even internally python is inconsistent, should I file a
low-severity bug so we don't lose track of this?

Misa
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] Py_BuildValue and decref

2006-09-08 Thread Mihai Ibanescu
Hi,

Looking at:

http://docs.python.org/api/arg-parsing.html

The description for O is:

O (object) [PyObject *]
Store a Python object (without any conversion) in a C object pointer. The
C program thus receives the actual object that was passed. The object's
reference count is not increased. The pointer stored is not NULL.

There is no description of what happens when Py_BuildValue fails. Will it
decref the python object passed in? Will it not?

Looking at tupleobject.h:

/*
Another generally useful object type is a tuple of object pointers.
For Python, this is an immutable type.  C code can change the tuple items
(but not their number), and even use tuples are general-purpose arrays of
object references, but in general only brand new tuples should be mutated,
not ones that might already have been exposed to Python code.

*** WARNING *** PyTuple_SetItem does not increment the new item's reference
count, but does decrement the reference count of the item it replaces,
if not nil.  It does *decrement* the reference count if it is *not*
 ^^^
inserted in the tuple.  Similarly, PyTuple_GetItem does not increment the
returned item's reference count.
*/

So, if the call to PyTuple_SetItem fails, the value passed in is lost. Should
I expect the same thing with Py_BuildValue?


Looking at how other modules deal with this, I picked typeobject.c:

result = Py_BuildValue([O], (PyObject *)type);
if (result == NULL) {
Py_DECREF(to_merge);
return NULL;
}

so no attempt to DECREF type in the error case.


Further down...


if (n) {
state = Py_BuildValue((NO), state, slots);
if (state == NULL)
goto end;
}

and further down:

  end:
Py_XDECREF(cls);
Py_XDECREF(args);
Py_XDECREF(args2);
Py_XDECREF(slots);
Py_XDECREF(state);
Py_XDECREF(names);
Py_XDECREF(listitems);
Py_XDECREF(dictitems);
Py_XDECREF(copy_reg);
Py_XDECREF(newobj);
return res;

so it will attempt to DECREF the (non-NULL) slots in the error case.

It's probably not a big issue since if Py_BuildValue fails, you have bigger
issues than memory leaks, but it seems inconsistent to me. Can someone that
knows the internal implementation clarify one way over the other?

Thanks!
Misa
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Py_BuildValue and decref

2006-09-08 Thread Mihai Ibanescu
On Fri, Sep 08, 2006 at 06:27:08PM -0400, Barry Warsaw wrote:
 
 On Sep 8, 2006, at 6:06 PM, Mihai Ibanescu wrote:
 
 There is no description of what happens when Py_BuildValue fails.  
 Will it
 decref the python object passed in? Will it not?
 
 I just want to point out that the C API documentation is pretty  
 silent about the refcounting side-effects in error conditions (and  
 often in success conditions too) of most Python functions.  For  
 example, what is the refcounting side-effects of PyDict_SetItem() on  
 val?  What about if that function fails?  Has val been incref'd or  
 not?  What about the side-effects on any value the new one replaces,  
 both in success and failure?

In this particular case, it doesn't decref it (or so I read the code).
Relevant code is in do_mkvalue from Python/modsupport.c

case 'N':
case 'S':
case 'O':
if (**p_format == '') {
typedef PyObject *(*converter)(void *);
converter func = va_arg(*p_va, converter);
void *arg = va_arg(*p_va, void *);
++*p_format;
return (*func)(arg);
}
else {
PyObject *v;
v = va_arg(*p_va, PyObject *);
if (v != NULL) {
if (*(*p_format - 1) != 'N')
Py_INCREF(v);
}
else if (!PyErr_Occurred())
/* If a NULL was passed
 * because a call that should
 * have constructed a value
 * failed, that's OK, and we
 * pass the error on; but if
 * no error occurred it's not
 * clear that the caller knew
 * what she was doing. */
PyErr_SetString(PyExc_SystemError,
NULL object passed to
Py_BuildValue);
return v;
}


Barry, where can I ship you my cloning machine? :-)

Misa
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] logging module broken because of locale

2006-07-20 Thread Mihai Ibanescu
On Thu, Jul 20, 2006 at 05:09:38AM -0500, [EMAIL PROTECTED] wrote:
 
 Misa Good point. Does the attached patch look reasonable?
 
 ...
 Misa -self.when = string.upper(when)
 Misa +self.when = unicode(when).upper()
 ...
 
 The use of the string module instead of string methods suggests to me that
 the logging package attempts to work with older versions of Python.  Looking
 at PEP 291 it looks like 1.5.2 compatibility is desired (no string methods,
 no unicode).  I think a conscious decision by someone (probably Vinay Sajip)
 to give up that compatibility would be required.

Agreed. There is a note that the module should work with python = 1.5.2 at
the top of the module.

It's up to Vinay to decide if we want to drop support for 1.5.2 in the module
included in newer pythons, or the attached patch would make it work for 1.5.2
as well (as in it's not more broken than before). 

I would like to redo the patch once more to get rid of the try-except and use
__builtins__ instead (but for some reason it kept jumping from being a module
to being a dictionary and I just wanted the proof of concept).

Misa
--- Python-2.4.3/Lib/logging/handlers.py.nolocale   2006-07-19 
12:15:46.0 -0400
+++ Python-2.4.3/Lib/logging/handlers.py2006-07-20 09:45:57.0 
-0400
@@ -162,7 +162,7 @@
 
 def __init__(self, filename, when='h', interval=1, backupCount=0, 
encoding=None):
 BaseRotatingHandler.__init__(self, filename, 'a', encoding)
-self.when = string.upper(when)
+self.when = _upper(when)
 self.backupCount = backupCount
 # Calculate the real rollover interval, which is just the number of
 # seconds between rollovers.  Also set the filename suffix used when
@@ -645,7 +645,7 @@
 
 msg = self.log_format_string % (
 self.encodePriority(self.facility,
-string.lower(record.levelname)),
+_lower(record.levelname)),
 msg)
 try:
 if self.unixsocket:
@@ -854,7 +854,7 @@
 (GET or POST)
 
 logging.Handler.__init__(self)
-method = string.upper(method)
+method = _upper(method)
 if method not in [GET, POST]:
 raise ValueError, method must be GET or POST
 self.host = host
@@ -1007,3 +1007,25 @@
 self.flush()
 self.target = None
 BufferingHandler.close(self)
+
+def _upper(s):
+A version of upper() that tries to be locale-independent by converting
+the string to unicode (which is not subject to case conversion being
+locale specific)
+
+try:
+ret = str(unicode(s).upper())
+except NameError:
+ret = string.upper(s)
+return ret
+
+def _lower(s):
+A version of lower() that tries to be locale-independent by converting
+the string to unicode (which is not subject to case conversion being
+locale specific)
+
+try:
+ret = str(unicode(s).lower())
+except NameError:
+ret = string.lower(s)
+return ret
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] logging module broken because of locale

2006-07-20 Thread Mihai Ibanescu
On Thu, Jul 20, 2006 at 06:08:05PM +0200, Martin v. Löwis wrote:
 Mihai Ibanescu wrote:
  It's up to Vinay to decide if we want to drop support for 1.5.2 in the 
  module
  included in newer pythons, or the attached patch would make it work for 
  1.5.2
  as well (as in it's not more broken than before). 
 
 That still wouldn't work with Python 1.5.2, as that version did not
 support Unicode at all.

Yes, as I said, it won't be more broken than before applying the patch (my
first patch was breaking 1.5.2 completely).

If people choose to compile python 2.4.3 without unicode support, it won't
work either. But if you choose to disable unicode you probably live in a very
constrained environment and you may not be affected by the locale bug at all.

I agree the patch is not perfect :-) but I think it solves the problem for
most people.

Misa
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] logging module broken because of locale

2006-07-19 Thread Mihai Ibanescu
On Tue, Jul 18, 2006 at 02:55:56PM -0400, Fred L. Drake, Jr. wrote:
 On Tuesday 18 July 2006 14:52, Mihai Ibanescu wrote:
   Unicode might be a perfectly acceptable suggestion for others too.
 
 Are we still supporting builds that don't include Unicode?  If so, that needs 
 to be considered in a patch as well.

Good point. Does the attached patch look reasonable?

Thanks,
Misa
--- Python-2.4.3/Lib/logging/handlers.py.nolocale   2006-07-19 
12:15:46.0 -0400
+++ Python-2.4.3/Lib/logging/handlers.py2006-07-19 12:16:14.0 
-0400
@@ -44,6 +44,12 @@
 DEFAULT_SOAP_LOGGING_PORT   = 9023
 SYSLOG_UDP_PORT = 514
 
+# If python was not built with unicode support, use the str function instead
+# of the unicode type, and hope locale doesn't break things.
+
+if not hasattr(__builtins__, 'unicode'):
+unicode = str
+
 class BaseRotatingHandler(logging.FileHandler):
 
 Base class for handlers that rotate log files at a certain point.
@@ -162,7 +168,7 @@
 
 def __init__(self, filename, when='h', interval=1, backupCount=0, 
encoding=None):
 BaseRotatingHandler.__init__(self, filename, 'a', encoding)
-self.when = string.upper(when)
+self.when = unicode(when).upper()
 self.backupCount = backupCount
 # Calculate the real rollover interval, which is just the number of
 # seconds between rollovers.  Also set the filename suffix used when
@@ -642,10 +648,12 @@
 
 We need to convert record level to lowercase, maybe this will
 change in the future.
+We convert it to unicode first, to avoid locale from changing the
+meaning of lower() and upper()
 
 msg = self.log_format_string % (
 self.encodePriority(self.facility,
-string.lower(record.levelname)),
+unicode(record.levelname).lower()),
 msg)
 try:
 if self.unixsocket:
@@ -854,7 +862,7 @@
 (GET or POST)
 
 logging.Handler.__init__(self)
-method = string.upper(method)
+method = unicode(method).upper()
 if method not in [GET, POST]:
 raise ValueError, method must be GET or POST
 self.host = host
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] logging module broken because of locale

2006-07-18 Thread Mihai Ibanescu
On Mon, Jul 17, 2006 at 03:39:55PM -0400, Mihai Ibanescu wrote:
 Hi,
 
 This is reported on sourceforge:
 
 http://sourceforge.net/tracker/index.php?func=detailaid=1524081group_id=5470atid=105470
 
 I am willing to try and patch the problem, but I'd like to discuss my ideas
 first.
 
 The basic problem is that, in some locale, INFO.lower() != info. So,
 initializing a dictionary with keys that appear to be lower-case in English
 is unsafe for other locale.
 
 Now, the other problem is, people can choose to initialize the locale any time
 they want, and can choose to change it too. My initial approach was to create
 the dictionary with strings to which lower() was explicitly called.
 
 But, since priority_names is class-scoped, it gets evaluated at module import
 time, which is way too early in the game (most likely the locale will be set
 afterwards).
 
 Any thoughts on the proper way to approach this?

To follow up on my own email: it looks like, even though in some locale
INFO.lower() != info

uINFO.lower() == info (at least in the Turkish locale).

Is that guaranteed, at least for now (for the current versions of python)?

Thanks,
Misa
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] logging module broken because of locale

2006-07-18 Thread Mihai Ibanescu
On Tue, Jul 18, 2006 at 10:19:54AM -0700, Guido van Rossum wrote:
 Alternatively, does info.upper() == INFO everywhere?

Not in the Turkish locale :-(

# begin /tmp/foo.py
import locale

locale.setlocale(locale.LC_ALL, '')

print info.upper()
print info.upper() == INFO
# end /tmp/foo.py

LANG=tr_TR.UTF-8 python /tmp/foo.py
iNFO
False

Thanks,
Misa
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] logging module broken because of locale

2006-07-18 Thread Mihai Ibanescu
On Tue, Jul 18, 2006 at 10:53:23AM -0700, Guido van Rossum wrote:
 And uinfo.upper()?

Yepp, that shows the right thing (at least in the several locales I tested,
Turkish included).

It's along the lines of uINFO.lower() I was proposing in my second post :-)

Misa
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] logging module broken because of locale

2006-07-18 Thread Mihai Ibanescu
On Tue, Jul 18, 2006 at 07:54:28PM +0200, Martin v. Löwis wrote:
 Mihai Ibanescu wrote:
  To follow up on my own email: it looks like, even though in some locale
  INFO.lower() != info
  
  uINFO.lower() == info (at least in the Turkish locale).
  
  Is that guaranteed, at least for now (for the current versions of python)?
 
 It's guaranteed for now; unicode.lower is not locale-aware.

OK, should I write a patch for the logging module to convert the string to
unicode before applying lower()? So far that seems like the way to go.

Maybe this could also be explained in the documentation:

http://docs.python.org/lib/node323.html

I don't think I've seen it in the locale documentation that locale settings do
not affect unicode strings, and that particular page says 

quote
If, when coding a module for general use, you need a locale independent version
of an operation that is affected by the locale (such as string.lower(), or
certain formats used with time.strftime()), you will have to find a way to do
it without using the standard library routine.
/quote

Unicode might be a perfectly acceptable suggestion for others too.

Misa
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] logging module broken because of locale

2006-07-17 Thread Mihai Ibanescu
Hi,

This is reported on sourceforge:

http://sourceforge.net/tracker/index.php?func=detailaid=1524081group_id=5470atid=105470

I am willing to try and patch the problem, but I'd like to discuss my ideas
first.

The basic problem is that, in some locale, INFO.lower() != info. So,
initializing a dictionary with keys that appear to be lower-case in English
is unsafe for other locale.

Now, the other problem is, people can choose to initialize the locale any time
they want, and can choose to change it too. My initial approach was to create
the dictionary with strings to which lower() was explicitly called.

But, since priority_names is class-scoped, it gets evaluated at module import
time, which is way too early in the game (most likely the locale will be set
afterwards).

Any thoughts on the proper way to approach this?

Thanks,
Misa
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com