Re: Grouping pairs - suggested tools

2010-09-21 Thread Alf P. Steinbach /Usenet

* Arnaud Delobelle, on 21.09.2010 11:13:

On Sep 21, 7:19 am, "Alf P. Steinbach /Usenet"  wrote:

* Alf P. Steinbach /Usenet, on 21.09.2010 01:09:






* Astley Le Jasper, on 20.09.2010 23:42:

I have a list of tuples that indicate a relationship, ie a is related
to b, b is related to c etc etc. What I want to do is cluster these
relationships into groups. An item will only be associated with a
single cluster.



Before I started, I wondered if there was any particular tool within
Python I should be looking at. I don't expect anyone to code this for
me, just say ... "you need to look at using x". I was going to use
populate a dictionary and



Sorry for being so vague.



Example Data:
[(a,b)
(a,c)
(a,d)
(b,c)
(b,d)
(c,d)
(e,f)
(e,g)
(f,g)
(h,i)]



Output (grouping id, item ref)
(1,a),
(1,b),
(1,c),
(1,d),
(2,e),
(2,f),
(2,g),
(3,h),
(3,i)



It seems to be the same problem as "equivalence sets".



This problem was solved early on because e.g. Fortran compilers had to construct
such sets (equivalence partitions of a set).



I though I'd just say "Google it!", because I know there's a standard algorithm
but I can't recall the name. However, googling it I found no mention of that
algorithm. Not even in the Wikipedia articles on equivalence sets.



A number of approaches spring to mind:



Approach 1:
Multi-pass. Originally you assign a distinct set number to each symbol.
In each pass through the symbols you replace one number with another as
per one of the equivalence specs. Stop when no replacements are done.



Approach 2:
Merging. For each new equivalence A=B you check whether A has been assigned
to a set, if not you create a new one, call that S1, and ditto for B, S2.
Merge S1 and S2, e.g. move all elements of S2 to S1.



Approach 3:
In a first pass convert the data to more explicit form, linking each symbol
to the symbols it's directly equivalent to. Then in second pass simply drag
out each equivalence group (recurse on each symbol's list of equivalences).



Approaches 1 and 2 seem to be pretty inefficient for a large number of symbols,
but I think approach 1 may be a practical option for a small number of symbols.


Uhm, thinking about it (it must have been my unconscious mind doing the work, it
just popped into my head), if you first sort each individual equivalence
relation so that you never have e.g. C=A but only A=C and so on, and then sort
the list of equivalences, then it should reduce to walking the list and just
starting a new set whenever a symbol is encountered that isn't yet in a set.


class Attributes: pass

sym = Attributes()
for name in ("a", "b", "c", "d", "e", "f", "g", "h", "i"):
  setattr( sym, name, name )

eq_specs = [
  (sym.a, sym.d),
  (sym.b, sym.a),
  (sym.b, sym.c),
  (sym.b, sym.d),
  (sym.c, sym.d),
  (sym.c, sym.a),
  (sym.e, sym.f),
  (sym.e, sym.g),
  (sym.f, sym.g),
  (sym.h, sym.i),
  ]

equalities = []
for eq in eq_specs:
  sorted_eq = eq if eq[0]<= eq[1] else (eq[1], eq[0])
  equalities.append( sorted_eq )
equalities.sort()

eq_sets = {}
eq_set_ids = {}
current_eq_set_id = 0
for eq in equalities:


This would make the body of the loop easier to read:

   for x, y in equalities:


  if eq_set_ids.get( eq[0] ) is None:


Why not simply:

if eq[0] in eq_set_ids:


  current_eq_set_id += 1
  eq_set_ids[eq[0]] = current_eq_set_id
  eq_sets[current_eq_set_id] = set( eq[0] )
  eq_set_id = eq_set_ids[eq[0]]
  eq_set_ids[eq[1]] = eq_set_id
  eq_sets[eq_set_id].add( eq[1] )

for eq_set_id in eq_sets.keys():
  for sym_name in eq_sets[eq_set_id]:
  print( "{}, {}".format( eq_set_id, sym_name ) )



1, a
1, c
1, b
1, d
2, e
2, g
2, f
3, i
3, h


Disclaimer: for me it's pretty late in day/night.

Cheers&  hth.,

- Alf

--
blog athttp://alfps.wordpress.com>


I think this won't work with the following graph:

eq_specs = [('a', 'c'), ('b', 'd'), ('c', 'd')]

Note that it is already sorted according to your sorting method.  I
don't have a Python machine to check this but I believe it will
output:

1, a
1, c
1, d
2, b

The flaw is that you fail to consider that the two vertices in the
current pair may already be part of a (partial) connected component.


Yeah, thanks.

I think the three general methods I listed will nicely work, though.

Moral: don't post insights from dream-world... ;-)


Cheers,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Grouping pairs - suggested tools

2010-09-20 Thread Alf P. Steinbach /Usenet

* Alf P. Steinbach /Usenet, on 21.09.2010 01:09:

* Astley Le Jasper, on 20.09.2010 23:42:

I have a list of tuples that indicate a relationship, ie a is related
to b, b is related to c etc etc. What I want to do is cluster these
relationships into groups. An item will only be associated with a
single cluster.

Before I started, I wondered if there was any particular tool within
Python I should be looking at. I don't expect anyone to code this for
me, just say ... "you need to look at using x". I was going to use
populate a dictionary and

Sorry for being so vague.

Example Data:
[(a,b)
(a,c)
(a,d)
(b,c)
(b,d)
(c,d)
(e,f)
(e,g)
(f,g)   
(h,i)]

Output (grouping id, item ref)
(1,a),
(1,b),
(1,c),
(1,d),
(2,e),
(2,f),
(2,g),
(3,h),
(3,i)


It seems to be the same problem as "equivalence sets".

This problem was solved early on because e.g. Fortran compilers had to construct
such sets (equivalence partitions of a set).

I though I'd just say "Google it!", because I know there's a standard algorithm
but I can't recall the name. However, googling it I found no mention of that
algorithm. Not even in the Wikipedia articles on equivalence sets.

A number of approaches spring to mind:

Approach 1:
Multi-pass. Originally you assign a distinct set number to each symbol.
In each pass through the symbols you replace one number with another as
per one of the equivalence specs. Stop when no replacements are done.

Approach 2:
Merging. For each new equivalence A=B you check whether A has been assigned
to a set, if not you create a new one, call that S1, and ditto for B, S2.
Merge S1 and S2, e.g. move all elements of S2 to S1.

Approach 3:
In a first pass convert the data to more explicit form, linking each symbol
to the symbols it's directly equivalent to. Then in second pass simply drag
out each equivalence group (recurse on each symbol's list of equivalences).

Approaches 1 and 2 seem to be pretty inefficient for a large number of symbols,
but I think approach 1 may be a practical option for a small number of symbols.


Uhm, thinking about it (it must have been my unconscious mind doing the work, it 
just popped into my head), if you first sort each individual equivalence 
relation so that you never have e.g. C=A but only A=C and so on, and then sort 
the list of equivalences, then it should reduce to walking the list and just 
starting a new set whenever a symbol is encountered that isn't yet in a set.




class Attributes: pass

sym = Attributes()
for name in ("a", "b", "c", "d", "e", "f", "g", "h", "i"):
setattr( sym, name, name )

eq_specs = [
(sym.a, sym.d),
(sym.b, sym.a),
(sym.b, sym.c),
(sym.b, sym.d),
(sym.c, sym.d),
(sym.c, sym.a),
(sym.e, sym.f),
(sym.e, sym.g),
(sym.f, sym.g),
(sym.h, sym.i),
]

equalities = []
for eq in eq_specs:
sorted_eq = eq if eq[0] <= eq[1] else (eq[1], eq[0])
equalities.append( sorted_eq )
equalities.sort()

eq_sets = {}
eq_set_ids = {}
current_eq_set_id = 0
for eq in equalities:
if eq_set_ids.get( eq[0] ) is None:
current_eq_set_id += 1
eq_set_ids[eq[0]] = current_eq_set_id
eq_sets[current_eq_set_id] = set( eq[0] )
eq_set_id = eq_set_ids[eq[0]]
eq_set_ids[eq[1]] = eq_set_id
eq_sets[eq_set_id].add( eq[1] )

for eq_set_id in eq_sets.keys():
for sym_name in eq_sets[eq_set_id]:
print( "{}, {}".format( eq_set_id, sym_name ) )




1, a
1, c
1, b
1, d
2, e
2, g
2, f
3, i
3, h



Disclaimer: for me it's pretty late in day/night.


Cheers & hth.,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Grouping pairs - suggested tools

2010-09-20 Thread Alf P. Steinbach /Usenet

* Astley Le Jasper, on 20.09.2010 23:42:

I have a list of tuples that indicate a relationship, ie a is related
to b, b is related to c etc etc. What I want to do is cluster these
relationships into groups.  An item will only be associated with a
single cluster.

Before I started, I wondered if there was any particular tool within
Python I should be looking at. I don't expect anyone to code this for
me, just say ... "you need to look at using x". I was going to use
populate a dictionary and

Sorry for being so vague.

Example Data:
[(a,b)
(a,c)
(a,d)
(b,c)
(b,d)
(c,d)
(e,f)
(e,g)
(f,g)
(h,i)]

Output (grouping id, item ref)
(1,a),
(1,b),
(1,c),
(1,d),
(2,e),
(2,f),
(2,g),
(3,h),
(3,i)


It seems to be the same problem as "equivalence sets".

This problem was solved early on because e.g. Fortran compilers had to construct 
such sets (equivalence partitions of a set).


I though I'd just say "Google it!", because I know there's a standard algorithm 
but I can't recall the name. However, googling it I found no mention of that 
algorithm. Not even in the Wikipedia articles on equivalence sets.


A number of approaches spring to mind:

  Approach 1:
  Multi-pass. Originally you assign a distinct set number to each symbol.
  In each pass through the symbols you replace one number with another as
  per one of the equivalence specs. Stop when no replacements are done.

  Approach 2:
  Merging. For each new equivalence A=B you check whether A has been assigned
  to a set, if not you create a new one, call that S1, and ditto for B, S2.
  Merge S1 and S2, e.g. move all elements of S2 to S1.

  Approach 3:
  In a first pass convert the data to more explicit form, linking each symbol
  to the symbols it's directly equivalent to. Then in second pass simply drag
  out each equivalence group (recurse on each symbol's list of equivalences).

Approaches 1 and 2 seem to be pretty inefficient for a large number of symbols, 
but I think approach 1 may be a practical option for a small number of symbols.



Cheers & hth.,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Static typing, Python, D, DbC

2010-09-12 Thread Alf P. Steinbach /Usenet

* Paul Rubin, on 13.09.2010 04:50:

Ed Keith  writes:

I think DbC as envisioned by the Eiffel guy...
the term is that it's a static verification technique,


Eiffel throws an exception when a contract is violated. That is run
time behavior, not static verification.


The runtime checks are for when static analysis hasn't been supplied
(that is usually a partly manual process).  DBC is always intended to be
statically verified as I understand it.  Doing it at runtime is just a
hackish fallback.


DBC can't in generally be statically checked. E.g. a precondition of a routine 
might be that its argument is a sorted array. So regarding the nature of the 
checks it's not hopelessly incompatible with Python.


Cheers,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: [Q] How far can stack [LIFO] solve do automatic garbage collection and prevent memory leak ?

2010-08-16 Thread Alf P. Steinbach /Usenet

* Standish P, on 16.08.2010 09:20:

[garble garble]


Nonsense article "We look for an exogenous stack" cross-posted to

  [comp.lang.c],
  [comp.lang.c++],
  [comp.theory],
  [comp.lang.python],
  [comp.lang.forth].

Please refrain from following up on Standish' article.


Cheers,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Different python versions confusion under Windows Vista x64

2010-07-19 Thread Alf P. Steinbach /Usenet

* Edward Diener, on 19.07.2010 14:53:

In Windows Vista x64 I have installed python 2.6 64-bit version and
python 3.1 64-bit version to separate folders. Within the command
interpreter I add python 2.6 to the PATH.

In the command interpreter, When I type python somescript.py with an

import sys
print (sys.version)

in the script, it shows:

3.1.2 (r312:79149, Mar 20 2010, 22:55:39) [MSC v.1500 64 bit (AMD64)]

In the command interpreter if I type 'python' I see:

Python 2.6.5 (r265:79096, Mar 19 2010, 18:02:59) [MSC v.1500 64 bit
(AMD64)] on win32

Does anybody have any ideas why this is happening ?


At a guess your description of what's happening is not entirely accurate.

Although it could be, since Windows moves in mysterious ways.

Please try the following commands in sequence, with no other commands:

  python -V
  echo %path%
  ftype python.file
  python somescript.py

Then right-click the command interpreter's title bar to get edit menu. /Mark/ 
the text of your commands and results. Then /copy/ it to the clipboard (note: 
you can't use [Ctrl C] here, use the edit menu or just press Enter). Then post 
the commands and results here, /paste/ them into your message (e.g. [Ctrl V]).


And then, if you haven't already figured it out, somebody probably will. :-)


Cheers & hth.,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


CPython 3.1.1 docs error in noddy3 example?

2010-07-19 Thread Alf P. Steinbach /Usenet
"Extending and Embedding the Python Interpreter" §2.1.2, the noddy3 extension 
module example, uses "S" as format character for string arguments in its call to 
PyArg_ParseTupleAndKeywords.


This causes Noddy to only accept bytes as arguments, instead of strings (format 
"U").


I suspect this is a leftover from Python 2.x, where strings were bytes, and that 
this is a bug?



Cheers,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Sharing: member type deduction for member pointers (Alf's device?)

2010-07-19 Thread Alf P. Steinbach /Usenet

* Vladimir Jovic, on 19.07.2010 09:41:

Alf P. Steinbach /Usenet wrote:


#include   // PyWeakPtr, PyPtr, PyModule,
PyClass
using namespace progrock;

namespace {
using namespace cppy;

struct Noddy
{
PyPtr   first;
PyPtr   last;
int number;

Noddy( PyWeakPtr pySelf, PyPtr args, PyPtr kwArgs )
: number( 0 )
{
devsupport::suppressUnusedWarning( pySelf );

PyWeakPtr   pFirstName  = 0;
PyWeakPtr   pLastName   = 0;

static char*kwlist[] = { "first", "last", "number", 0 };

::PyArg_ParseTupleAndKeywords(
args.rawPtr(), kwArgs.rawPtr(), "|OOi", kwlist,
pointerTo( pFirstName ), pointerTo( pLastName ), &number
)
>> Accept< IsNonZero >()
|| throwX( "Invalid args" );

if( pFirstName != 0 )   { first = pFirstName; }
if( pLastName != 0 ){ last = pLastName; }


Why not initiallize all member variables in the initializer list?


'PyPtr' is a smart pointer with default constructor, so 'first' and 'last' are 
initialized to zero implicitly.


My goal was to emulate the Python 3.1.1 docs' Noddy2 example as closely as 
possible. And that code's assignment of zero to 'first' and 'last' here 
corresponds to default initialization to zero. :-)


Anyway, parsing the Python arguments in the constructor initializer list is 
possible, but would be inefficient to do directly since it would then involve 
parsing the Python arguments three times (once for each data member).


There is at least one way around that problem, namely outfitting a derived class 
with knowledge of the Noddy class' Python-side __init__ arguments.


But I haven't implemented such support, and I don't know if it would do any 
good. As it is Noddy above is self-contained, except for exporting names to the 
Python side. With a derived class doing the argument parsing it would be less 
self-contained, and the machinery for that would add complexity, I think.


So, I strive to make things simple and explicit (KISS: Keep It Simple, Stupid!).

And I strive to not go into orgies of smart templates doing things implicitly...



}

PyPtr name()
{
(first != 0)
|| throwX( ::PyExc_AttributeError, "first" );
(last != 0)
|| throwX( ::PyExc_AttributeError, "last" );


Nice trick. I would still find this more readable :

if ( first != 0 )
{
   throwX( ::PyExc_AttributeError, "first" );
}


Ah, well. :-)

You can read about the rationale here: http://alfps.wordpress.com/2010/07/18/cppx-b-true-or-b-thrown-using-the-throwing-pattern/> 
 --  posted yesterday.


Of course the only reason that those member variables /can/ be 0 is because I'm 
following the doc's progression of examples. The next version in the docs avoid 
the 0 possibility, as I recall. And the simple way of achieving that in cppy 
would be to declare 'first' and 'last' as PyString instead of generic PyPtr...




return (PyString( first ) + L" " + PyString( last )).pyPtr();
}
};

struct NoddyPyClass: PyClass< Noddy >
{
NoddyPyClass( PyModule& m, PyString const& name, PyString
const& doc )
: PyClass< Noddy >( m, name, doc, Exposition()
.method(
L"name",CPPY_GLUE( name ),
L"Return the name, combining the first and last name"
)
.attribute(
L"first",   CPPY_GLUE( first ), L"first name"
)
.attribute(
L"last",CPPY_GLUE( last ),  L"last name"
)
.attribute(
L"number",  CPPY_GLUE( number ),L"noddy number"
)
)
{}
};

class NoddyModule: public PyModule
{
private:
NoddyPyClassnoddyPyClass_;

public:
NoddyModule()
: PyModule(
L"noddy2", L"Example module that creates an extension
type." )
, noddyPyClass_( *this,
L"Noddy", L"A Noddy object has a name and a noddy
number" )



hmmm what is L ?


It's standard C and C++ notation for a wide character literal, where each 
character is of type 'wchar_t' instead of plain 'char'.


Essentially the intent is to hold Unicode UTF16 or UTF32 code points, which is 
how it is in practice, although for political correctness the C and C++ 
standards allow for other wide ch

Re: why is this group being spammed?

2010-07-17 Thread Alf P. Steinbach /Usenet

* be.krul, on 18.07.2010 07:01:

why is this group being spammed?


It depends a little on what you're asking, e.g. technical versus motivation.

But I'll answer about something you probably didn't mean to ask, namely what 
human trait enables and almost forces that kind of behavior.


And I believe it is the same trait that let hypnotists do funny TV-shows with 
quite normal folks behaving in ridiculous ways, the same trait that causes wars, 
the same trait that causes religion, the same trait that holds back science so 
that "paradigm shifts" only occur when new generations take over, a trait that 
/makes/ your feet start moving to the rhythm when you hear the right kind of 
music, and so on. Namely the instinctual drive to fit in in a social group by 
sharing that group's behavior and values. This instinct is possibly stronger 
than the sex drive, e.g., wars are seldom fought over sex ("surrender, and give 
us sex!", no, that's not it, it's "surrender, and become part of us!").


Consider, there would be almost no spam if spamming didn't pay.

And the only way that spam can pay is if there are at least some suckers with 
good money.


And the only way that there can be a reasonable number of suckers of such 
monumental stupidity, who also have good money, is, as I see it, if intelligence 
and good sense is not a requirement for succeeding in society.


But what is required, then, for succeeding in society?

Some of it is no doubt blind chance, but I believe that the main requirement is 
simply one of fitting in, conformance. Thus, if my hypothesis is right, almost 
any idiot can rise to any level of responsibility and social standing simply by 
fitting in, conforming. This idiot then has good money and might be one of the 
suckers responding to spam.



Cheers,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Sharing: member type deduction for member pointers (Alf's device?)

2010-07-17 Thread Alf P. Steinbach /Usenet

* Alf P. Steinbach /Usenet, on 17.07.2010 11:50:

[Cross-posted comp.lang.c++ and comp.lang.python]

[snip]
this occurred to me:

 #define CPPY_GETSET_FORWARDERS( name )  \
 ::progrock::cppy::forwardersGetSet( \
 &CppClass::name \
 ).themForwarders< &CppClass::name >()

Here forwardersGetSet is a templated function that via argument type
deduction produces an instance of a templated struct, thereby "knowing"
the member type, which struct in turn has a member function templated on
the member pointer, which the macro supplies *twice*, once as run-time
arg and once as compile-time.


That trick allowed uniform treatment of data and function member pointers. :-)

So, with cppy the complete noddy2 example from the docs (I'm sort of working my 
way through the Python doc examples) now looks as shown below.


The "typelessness" of the 'first' and 'last' members is in order to recreate as 
close as possible the noddy2 functionality, or, lack of it. Also, I haven't got 
around to sort of backporting the 'Exposition' scheme to modules. So, exposure 
of module functionality looks a little different from same for types, for now.




// The Python 3.1.1 docs' Noddy 2 example rewritten using cppy.
// Docs: "Extending and Embedding the Python Interpreter" §2.1.1

#include   // PyWeakPtr, PyPtr, PyModule, PyClass
using namespace progrock;

namespace {
using namespace cppy;

struct Noddy
{
PyPtr   first;
PyPtr   last;
int number;

Noddy( PyWeakPtr pySelf, PyPtr args, PyPtr kwArgs )
: number( 0 )
{
devsupport::suppressUnusedWarning( pySelf );

PyWeakPtr   pFirstName  = 0;
PyWeakPtr   pLastName   = 0;

static char*kwlist[] = { "first", "last", "number", 0 };

::PyArg_ParseTupleAndKeywords(
args.rawPtr(), kwArgs.rawPtr(), "|OOi", kwlist,
pointerTo( pFirstName ), pointerTo( pLastName ), &number
)
>> Accept< IsNonZero >()
|| throwX( "Invalid args" );

if( pFirstName != 0 )   { first = pFirstName; }
if( pLastName != 0 ){ last = pLastName; }
}

PyPtr name()
{
(first != 0)
|| throwX( ::PyExc_AttributeError, "first" );
(last != 0)
|| throwX( ::PyExc_AttributeError, "last" );
return (PyString( first ) + L" " + PyString( last )).pyPtr();
}
};

struct NoddyPyClass: PyClass< Noddy >
{
NoddyPyClass( PyModule& m, PyString const& name, PyString const& doc )
: PyClass< Noddy >( m, name, doc, Exposition()
.method(
L"name",CPPY_GLUE( name ),
L"Return the name, combining the first and last name"
)
.attribute(
L"first",   CPPY_GLUE( first ), L"first name"
)
.attribute(
L"last",CPPY_GLUE( last ),  L"last name"
)
.attribute(
L"number",  CPPY_GLUE( number ),L"noddy number"
)
)
{}
};

class NoddyModule: public PyModule
{
private:
NoddyPyClassnoddyPyClass_;

public:
NoddyModule()
: PyModule(
L"noddy2", L"Example module that creates an extension type." )
, noddyPyClass_( *this,
L"Noddy", L"A Noddy object has a name and a noddy number" )
{}
};
}// namespace 


PyMODINIT_FUNC
PyInit_noddy2()
{
return cppy::safeInit< NoddyModule >();
}



I wonder if this is readable / self-documenting, or not?


Cheers,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Sharing: member type deduction for member pointers (Alf's device?)

2010-07-17 Thread Alf P. Steinbach /Usenet

[Cross-posted comp.lang.c++ and comp.lang.python]

Consider the following code, from an example usage of some C++ support for 
Python I'm working on, "cppy":




struct Noddy
{
PyPtr   first;
PyPtr   last;
int number;

Noddy( PyWeakPtr pySelf, PyPtr args, PyPtr kwArgs )
: number( 0 )
{
// ... some initialization here
}

PyPtr name()
{
return (PyString( first ) + L" " + PyString( last )).pyPtr();
}
};

struct NoddyPyClass: PyClass< Noddy >
{
typedef PyClass< Noddy >Base;

NoddyPyClass( PyModule& m, PyString const& name, PyString const& doc )
: Base( m, name, doc,
Exposition()
.method(
L"name",CPPY_METHOD_FORWARDER( name ),
L"Return the name, combining the first and last name"
)
.attribute(
L"first",   CPPY_GETSET_FORWARDERS( first ),
L"first name"
)
.attribute(
L"last",CPPY_GETSET_FORWARDERS( last ),
L"last name"
)
.attribute(
L"number",  CPPY_GETSET_FORWARDERS( number ),
L"noddy number"
)
)
{}
};



Originally e.g.

CPPY_GETSET_FORWARDERS( number ),

had to be written as

CPPY_GETSET_FORWARDERS( int, number ),

because in order to use a compile time member pointer as template actual 
argument, one needs to supply the member type as a separate template argument.


E.g. the template might look like

template< class Class, class MemberType, MemberType Class::*pMember >
struct ForwardersForGetAndSet
{
// Some definitions here, hardwiring that compile time member pointer!
};

Apparently there was no way around the user repeating explicitly the member type 
that the compiler already knew about... It seemed akin to deducing the return 
type of a function. Difficult in C++98 (although Boost does a fair job).


But then it seemed that I'm not totally senile yet, for this occurred to me:

#define CPPY_GETSET_FORWARDERS( name )  \
::progrock::cppy::forwardersGetSet( \
&CppClass::name \
).themForwarders< &CppClass::name >()

Here forwardersGetSet is a templated function that via argument type deduction 
produces an instance of a templated struct, thereby "knowing" the member type, 
which struct in turn has a member function templated on the member pointer, 
which the macro supplies *twice*, once as run-time arg and once as compile-time.


He he.

Perhaps this trick is well-known already, but it was new to me, so! :-)


Cheers,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Nested loop not working

2010-07-16 Thread Alf P. Steinbach /Usenet

* Johann Spies, on 16.07.2010 16:34:

I am overlooking something stupid.

I have two files: one with keywords and another with data (one record per line).

I want to determine for each keyword which lines in the second file
contains that keyword.

The following code is not working.  It loops through the second file
but only uses the first keyword in the first file.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import re

keywords = open("sleutelwoorde",'r')
data = open("sarua_marine_sleutelwoorde.csv",'r')

remove_quotes = re.compile('"')


for sw in keywords:
 for r in data:
 swc = remove_quotes('',sw)[:-1]
 if swc in r.lower():
 print swc + ' --->  ' + r
 print swc

What am I missing?


For the inner loop, 'data' is an object that represents a file and keeps track 
of a current read position of the file. The first execution of the loop moves 
that read position all the way to the End Of the File, EOF. The second time this 
loop is attempted, which would be for the second keyword, the 'data' object's 
read position is already at end of file, and thus nothing's done.


One way to just make it work is to open and close the data file within the outer 
loop. Actually with CPython it's automatically closed, as far as I can recall, 
so you only need to reopen it, but this (if true) is less than completely 
documented. This way is inefficient for small data set, but works.


In order to get a better handle on the general problem -- not the Python 
technicalitities -- google up "KWIC", KeyWord In Context. It's a common exercise 
problem given to first or second-year students. So I think there should be an 
abundance of answers and discussion, although I haven't googled.



Cheers & hth.,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Cpp + Python: static data dynamic initialization in *nix shared lib?

2010-07-14 Thread Alf P. Steinbach /Usenet

* Hrvoje Niksic, on 14.07.2010 10:17:

"Alf P. Steinbach /Usenet"  writes:


Also, things like the 'owned' option is just asking for trouble.


Isn't owned=true (or equivalent) a necessity when initializing from a
PyObject* returned by a function declared to return a "new reference"?


No, not quite.

Consider this signature (PyCXX):

   String( PyObject* pyob, bool owned = false )

versus this (cppy):

   PyString( PyPtr object )

With the first signature, every time you construct a String you have to remember 
to (explicitly or implicitly) set the bool flag correctly depending on where the 
actual argument value comes from.


With the second signature the /type/ of the actual argument decides, 
automatically, so there's much less room for messing things up.


With the second signature, if the actual argument is a raw PyObject* pointer 
then it's not owned, and the PyPtr formal argument doesn't increment the 
reference count but just takes ownership. If the actual argument, on the other 
hand, is a PyPtr, then the object is owned by the collection of PyPtr instances 
that refer to the object, and the new formal argument PyPtr instance then 
increments the reference count. In passing, if it should happen that the Python 
community uses the word 'owned' in the opposite sense of what's conventional in 
C++, then I guess & hope you'll figure out what I mean from this description.


PyPtr currently looks like this (complete code):



// progrock.cppy  --  "C++ plus Python"
// A simple C++ framework for writing Python 3.x extensions.
//
// Copyright (c) Alf P. Steinbach, 2010.

#ifndef CPPY_PYPTR_H
#define CPPY_PYPTR_H
#include 


//- Dependencies:

#include 
#include 
#include 



//- Interface:

namespace progrock{ namespace cppy {
using namespace cppx;

enum DoAddRef {};

class PyPtr
{
private:
PyObject*   p_;

public:
typedef cppy::DoAddRef  DoAddRef;

PyPtr( PyObject* p = 0 ): p_( p ) {}

PyPtr( PyObject* p, DoAddRef ): p_( p )
{
assert( p != 0 );  Py_INCREF( p_ );
}

PyPtr( PyPtr const& other ): p_( other.p_ ) { Py_XINCREF( p_ ); }

~PyPtr() { Py_XDECREF( p_ ); }

void swapWith( PyPtr& other )   { std::swap( p_, other.p_ ); }
PyPtr& operator=( PyPtr other ) { swapWith( other ); return *this; }

PyObject* get() const   { return p_; }

PyObject* release()
{
PyObject* const result  = p_;
p_ = 0;
return result;
}
};

inline PyObject* withAddedRef( PyObject* p )
{
Py_INCREF( p );
return p;
}

inline PyObject* pyNoneRef()
{
return withAddedRef( Py_None );
}
} }  // namespace progrock::cppy


#endif



As you can see at the end there, there is 'withAddedRef' and 'pyNoneRef', and 
for that matter the 'DoAddRef' and the 'release()' method, for the cases where 
PyPtr default handling doesn't quite cut it... :-)




How does your API deal with the distinction between new and borrowed
references?


See above.

There are some cases where it must be dealt with, but the main idea is to encode 
that into /types/, instead of as context-dependent figure-it-out.


That's also the main idea of C++ as compared to C, to encode much more into 
types, which helps both for compile time error detection and for automating 
things (like above), which is Very Nice, but which also can make for enormous 
waste of time trying to make the darned language do what you want it to do! :-)



Cheers & hth.,

- Alf


Disclaimer: it's late in the day/night for me, so the above explanation may have 
big logic holes, mispelings and so on, but I hope it gives the idea.


--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: floatref

2010-07-13 Thread Alf P. Steinbach /Usenet

* Steven D'Aprano, on 14.07.2010 06:31:


Gary did the right thing by pointing out that the simple-sounding term
"points to" is anything but simple, it depends on what you mean by
pointing and pointers.


Possibly you have a point here.


Cheers,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: floatref

2010-07-13 Thread Alf P. Steinbach /Usenet

* Gary Herron, on 14.07.2010 01:26:

On 07/13/2010 03:02 PM, Roald de Vries wrote:

Hi Gary,

On Jul 13, 2010, at 8:54 PM, Gary Herron wrote:

On 07/13/2010 10:26 AM, Roald de Vries wrote:

Hi all,

I have two objects that should both be able to alter a shared float.
So i need something like a mutable float object, or a float reference
object. Does anybody know if something like that exists? I know it's
not hard to build, but I have a feeling that there should be a
standard solution to it.

Roald


Huh? I must be missing something here. Isn't this what you use a
variable for:


Maybe I didn't explain well:

>>> shared_var = 1.0
>>> x.var = shared_var
>>> y.var = shared_var
>>> x.var = 2.0
>>> y.var
1.0

I wanted y.var and x.var to point to the same value, so that always
x.var == y.var. So that the last line becomes:

>>> y.var
2.0

Cheers, Roald


Please keep responses and further discussions on
list.python-l...@python.org
instead of using private emails.


Seconded. I didn't see that posting.



Python does not have pointers, so if I take your wording"y.var and x.var
to point to the same value" literally, then the answer is NO Python does
not do that.


This is just a terminological issue. Saying "Python does not have pointers" is 
highly misleading in response to the OP's statement. It's easy enough to 
understand what he means. E.g., in the Java language specification "pointer" has 
a suitable meaning. And in general, the term "pointer" encompasses far more than 
the concept of a C or Pascal pointer, e.g., in C++ it includes offset-like 
things called member pointers. You can't represent or usefully think of a C++ 
member pointer as a C or Pascal pointer. It isn't useful on its own. So, 
considering C++ and Java, the general pointer notion is something that refers, 
however obliquely. You chose a specific meaning of "pointer" where the OP's 
statement does not make sense, but presumably the OP is explaining his needs in 
terms of a more general meaning of "pointer"; assuming anything else is silly.




However, Python does have references all over the place, so you can
achieve something similar in many ways.

If x and y in your example code are instances of a class, than look into
using a property for x.var and y.var. A property is a thing that looks
like an attribute, (that would be var in x.var and y.var), but which
really executes getter/setter code when accessed. That getter/setter
code would then access/set the value in shared_var:


shared_var = 123

class Thing(object):
def get_var(self):
return shared_var
def set_var(self, v):
global shared_var
shared_var = v

var = property(get_var, set_var)


x = Thing()
y = Thing()

print x.var, y.var # prints: 123 123
x.var = 99
print x.var, y.var # prints: 99 99


This code goes through hoops to /hide/ the fact of the sharing.

Rather, I'd make that as explicit as possible.

Like,

  x = {"sharedVar": 123}
  y = x

The one won't be surprised when changing x["sharedVar"] also changes 
y["sharedVar"].


Cheers & hth.,

- Alf


--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Cpp + Python: static data dynamic initialization in *nix shared lib?

2010-07-13 Thread Alf P. Steinbach /Usenet

* sturlamolden, on 13.07.2010 22:06:

On 13 Jul, 21:39, "Alf P. Steinbach /Usenet"  wrote:


Thanks! It seems that SCXX does those things that I've been planning to do but
haven't got around to (wrapping standard Python types), while what it doesn't do
(abstracting away all those tables etc. and mapping Python calls to C++ calls)
is what I've been working on. Which could be a Very Nice combination except that
I'm assuming Py3, while SCXX seems to be Py2 only. :-(


I'd suggest PyCXX instead. http://cxx.sourceforge.net

SCXX is a tiny wrapper mostly used in scipy.weave to inline C++ in
Python.


Thanks. I looked up your URL, and PyCXX design goals seem to be much like what 
I'm doing, but different in some crucial ways. It's probably great, but it's not 
to my taste.


E.g. the PyCXX String class interface:


explicitString( PyObject *pyob, bool owned = false )
String( const Object &ob )
String()
String( const char *latin1 )
String( const char *latin1, Py_ssize_t size )
String( const std::string &latin1 )
String( const std::string &v, const char *encoding, const char 
*error=NULL )
String( const char *s, const char *encoding, const char *error=NULL )
	String( const char *s, Py_ssize_t len, const char *encoding, const char 
*error=NULL )

String &operator=( const Object &o )
String &operator=( PyObject *p )
String &operator=( const unicodestring &v )
size_type   size() const
size_type   capacity() const
unicodestring   as_unicodestring() const
std::string operator std::string() const
String  encode( const char *encoding, const char *error="strict" )
std::string 	as_std_string( const char *encoding=NULL, const char 
*error="strict" ) const



In C++ the only way to portably specify a string literal with national 
characters, is as a wide string literal. Otherwise the result depends on the 
source code encoding. Yet PyCXX's String does not support wchar_t.


Also, things like the 'owned' option is just asking for trouble.

I chose this example because a Python string wrapper is the only object wrapper 
(apart from a general PyPtr) that I've implemented so far. The PyCXX string 
wrapper fails the design criterions of general usability (including in 
particular lack of wide char support) and safety (in particular the 'owned' 
option). And it's underdocumented, like, what encoding does the operator 
std::string() produce?


The details don't matter though. I'm sure that PyCXX is Very Nice for its 
purpose, as is e.g. Boost.Python (which is Very Very Nice for its purpose). :-)



Cheers, & thanks for the link,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Cpp + Python: static data dynamic initialization in *nix shared lib?

2010-07-13 Thread Alf P. Steinbach /Usenet

* sturlamolden, on 13.07.2010 22:03:

On 9 Jul, 17:52, "Alf P. Steinbach /Usenet"  wrote:


For an extension module it seems that Python requires each routine to be defined
as 'extern "C"'.


That is strange. PyMethodDef is just a jump table. So why should
'extern "C"' matter?


Formally because they're incompatible function pointer types.

C++98 standard §7.5/1: "Two function types with different language linkages are 
distinct types even if they are otherwise identical". Add to that §7.5/4 "A 
linkage-specification shall occur only in namespace scope". And add to that 
§14-4 "A template, a template explicit specialization, or a class-template 
partial specialization shall not have C linkage." This means that formally 
correct code that generates callbacks by templating, is ruled out.


In practice, 'extern "C"' matters for the jump tables because for those few 
compilers if any where it really matters (not just the compiler emitting a 
warning like reportedly Sun CC does), different linkage can imply different 
machine code level calling convention. For example, who's responsible for 
cleaning up the stack, the order in which arguments are pushed or which 
registers they're passed in, and so forth. Ignoring such matters your code gets 
into la-la land pretty fast, but, it's a different matter when one /understands/ 
this and places a requirement on the compiler.




Good luck on re-inventing the wheel (you've probably heared about
Swig, SIP, Boost.Python, PyCXX, scipy.weave and Cython...)


Yes, I know Boost.Python in more detail and I've heard of all the rest except 
SIP, but then regarding SIP I really don't like QT (QT makes eminent sense in 
the context of Python, they're both essentially dynamically typed, but that 
means QT is not very nice as C++, plus there is the ugly preprocessor).


And as you'd guess if you were not in silly ignoramus assertion-mode, I'm not 
reinventing the wheel.



Cheers & hth.,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Cpp + Python: static data dynamic initialization in *nix shared lib?

2010-07-13 Thread Alf P. Steinbach /Usenet

* Jonathan Lee, on 13.07.2010 16:41:

Problem (C) is outside the realm of the C++ standard, since the C++ standard
doesn't support shared libraries, and I've never actually used *nix shared
libraries so I don't /know/...

Is such dynamic initialization guaranteed?



Not guaranteed, though I think there's a combination of dlopen options
and gcc command line parameters that invoke this behavior. See the
second page of

http://www.linuxjournal.com/article/3687

about auto-registration.

Personally, though, it never worked for me :/


Ah, well. :-(  Thanks for the info! OK, I'll just have to replace the 
auto-registration with some C++ magic. For which I think I'll simply /require/ 
that the compiler supports mixing of C and C++ linkage, that is, that ...




#include 

extern "C"
{
typedef int (*Callback)( int );
}

void foo( Callback f ) { std::cout << "foo!" << f( 42 ) << std::endl; }

int a( int ) { return 1; }
extern "C" int b( int ) { return 2; }

int main()
{
foo( a );   // Unholy Mix of C++ and C linkage, formally not OK.
foo( b );   // Should be OK with any compiler.
}



... compiles, and works.


Cheers, & thanks,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Cpp + Python: static data dynamic initialization in *nix shared lib?

2010-07-13 Thread Alf P. Steinbach /Usenet

* Robert Kern, on 13.07.2010 17:16:

On 7/13/10 2:34 AM, Alf P. Steinbach /Usenet wrote:


PS: You (the reader) may be wondering, why why why Yet Another Python/C++
binding? Well, because I had this great name for it, "pyni", unfortunately
already in use. But cppy is very different from Boost: Boost is large,  cppy is
tiny; Boost has as main goal to expose arbitrary C++ code to Python, automating
argument conversion etc., while with cppy your Python design is exposed to C++
with no enforced arg conversions and such; Boost relies on canned magic,
difficult to subvert when it doesn't do what you want, while with cppy you are
(or, so far, I am) in control; and I suspect that the Boost Python binding,
relying on dynamic registries and stuff, is not all that efficient, while cppy
is as efficient as using the Python C API to create an extension. And besides,
cppy supports national characters in doc strings etc. And I'm Norwegian. So. :-)


Note that Boost is not the only C++ binding out there. You may want to
take a look at the old SCXX library, which appears to be similar in intent:

  http://davidf.sjsoft.com/mirrors/mcmillan-inc/scxx.html

matplotlib uses it heavily, and their included copy may include some
more recent bugfixes and enhancements:

  http://matplotlib.sourceforge.net/


Thanks! It seems that SCXX does those things that I've been planning to do but 
haven't got around to (wrapping standard Python types), while what it doesn't do 
(abstracting away all those tables etc. and mapping Python calls to C++ calls) 
is what I've been working on. Which could be a Very Nice combination except that 
I'm assuming Py3, while SCXX seems to be Py2 only. :-(



Cheers,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Cpp + Python: static data dynamic initialization in *nix shared lib?

2010-07-13 Thread Alf P. Steinbach /Usenet

* geremy condra, on 09.07.2010 23:43:

On Fri, Jul 9, 2010 at 5:22 PM, Ian Collins  wrote:

On 07/10/10 03:52 AM, Alf P. Steinbach /Usenet wrote:


[Cross-posted comp.lang.python and comp.lang.c++]

I lack experience with shared libraries in *nix and so I need to ask...

This is about "cppy", some support for writing Python extensions in C++
that I just started on (some days ago almost known as "pynis" (not funny
after all)).

For an extension module it seems that Python requires each routine to be
defined as 'extern "C"'. And although e.g. MSVC is happy to mix 'extern
"C"' and C++ linkage, using a routine declared as 'static' in a class as
a C callback, formally they're two different kinds, and I seem to recall
that /some/ C++ compiler balks at that kind of mixing unless specially
instructed to allow it. Perhaps it was the Sun compiler?


Yes, it will (correctly) issue a warning.

As the is a bit OT, contact me directly and we can work through it.  I have
had similar fun and games adding PHP modules!


I'd appreciate it if you'd either leave this on-list or cc me in on this, as
I'm working through a similar issue.


Well, we got no further, but I know of three solutions:

  A) Punting: just say that the compiler has to support C++/C function type
 mingling.
 -> Perhaps the practical solution, but formally unsafe.

  B) On the script side of things, delegate all calls to single Mother Of All
 C func downcaller that supplies as extra arg an id of the C++ function.
 -> Micro-level inefficient but easy to use and formally correct.

  C) Let the user define the C linkage function wrappers via macros.
 -> Efficient and formally correct but exposes ugly macro names.

I chose (C).

I believe Boost's Python binding uses (A), or perhaps (B).


Cheers,

- Alf

PS: You (the reader) may be wondering, why why why Yet Another Python/C++ 
binding? Well, because I had this great name for it, "pyni", unfortunately 
already in use. But cppy is very different from Boost: Boost is large, cppy is 
tiny; Boost has as main goal to expose arbitrary C++ code to Python, automating 
argument conversion etc., while with cppy your Python design is exposed to C++ 
with no enforced arg conversions and such; Boost relies on canned magic, 
difficult to subvert when it doesn't do what you want, while with cppy you are 
(or, so far, I am) in control; and I suspect that the Boost Python binding, 
relying on dynamic registries and stuff, is not all that efficient, while cppy 
is as efficient as using the Python C API to create an extension. And besides, 
cppy supports national characters in doc strings etc. And I'm Norwegian. So. :-)


--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Easy questions from a python beginner

2010-07-12 Thread Alf P. Steinbach /Usenet

* Steven D'Aprano, on 13.07.2010 01:34:

On Mon, 12 Jul 2010 20:28:49 +0200, Alf P. Steinbach /Usenet wrote:


As I see it it doesn't matter whether the implementation is CPython call
frame slots or that mechanism called something else or a different
mechanism called the same or a different mechanism called something
different; what IMO matters is same semantics, that any assignment to a
variable within a routine serves as a compile time declaration, creating
that local variable in advance, unless, with Python 3.x., that name has
been declared as a 'global' or 'nonlocal'.

So, this is a possible point of disagreement.

I say the semantics of local variable creation are part of the language
definition, but I get the /impression/ that maybe you think it's
CPython-specific, that e.g.

def foo():
x
x = 0

might not raise an unassigned variable exception with some conforming
Python implementation, i.e. different effect for same code with
different implementations, that this is at least /unspecified behavior/
in Python?


Almost.

I believe that "any assignment to a variable within a routine serves as a
compile time declaration" is a promise of the language, but what an
implementation does in response to that declaration is unspecified. So
long as foo() raises NameError, or a subclass of it, it will be a
conforming Python implementation.

That's what Python 1.5 does, and I think if some competing implementation
targeted 1.5 we'd still be happy to call it Python. (Although we might
wonder about the author's sanity...) Implementations are free to subclass
NameError, as CPython does with UnboundLocalError, but mustn't raise a
completely unrelated error, or no error at all. E.g. I don't think it
would be acceptable to implicitly create new names and bind them to some
arbitrary default value.

E.g. an implementation might do something like this:

* when parsing the function, prior to compiling the byte-code, tag
   every name with a sigil representing whether it is local or non-local;
* compile a single byte-code for name lookup;
* when executing that instruction, if the name is tagged as a local,
   search only the local namespace, otherwise search the nonlocal,
   global and builtin namespaces;
* when displaying names to the user (say, in tracebacks) suppress
   the sigil.

Under this implementation, no variable actually exists until it is
assigned to.

This is equivalent to shifting the decision to use LOAD_FAST or
LOAD_GLOBAL to runtime rather than compile time, so it would probably
hurt performance rather than increase it, but it would still be a
conforming implementation.

But of course I'm not Guido, and he has the final word on what counts as
acceptable behaviour.


The 3.1.1 docs explicitly require UnboundLocalError (I just checked).

So, at least for 3.x it is not an implementation detail.

Anyway, your phrase "actually exist" presumably refers to storage allocation. 
That is an implementation detail. As a similar implementation scheme, a compiler 
can in certain cases detect that a variable is only assigned once, and 
substitute the value whereever that variable is used, not allocating any storage 
for it. This is the case in Python, in C++ and in almost any language. We don't 
start doubting the existence of variables in general (as some in the Python 
community do) on such grounds. More to the point of this sub-thread, it would be 
impossible to reason about things if one had to take into account the particular 
implementation's details at all times. Doing that renders most terms, including 
"exist", pretty meaningless and useless, since you would have to check whether 
each particular variable was optimized away or not: for the purpose of 
discussing existence in Python, what matters is portable effect.


Summing up, how CPython implements the required semantics, is irrelevant.

:-)


Cheers from Norway,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Easy questions from a python beginner

2010-07-12 Thread Alf P. Steinbach /Usenet

* Steven D'Aprano, on 13.07.2010 01:50:

On Mon, 12 Jul 2010 22:57:10 +0200, Alf P. Steinbach /Usenet wrote:


Existence of a variable means, among other things, that

* You can use the value, with guaranteed effect (either unassigned
exception
  or you get a proper value): in particular, you won't be accessing a
  global if you're using the name of a local declared by a later
  assignment.


That is too strong. Given the global code:

x

(where x doesn't exist in the global namespace, and therefore does not
exist, as you agreed earlier) Python promises to raise NameError. By the
above definition, this counts as "variable x exists".

But surely that is undesirable -- that implies that *all* variables
exist. Even $...@*@( is a variable that exists, as that is guaranteed to
raise SyntaxError.


Hm, I already answered someone else here committing that logic error.

In one case an exception is generated by removing a variable.

In the other case an exception is generated by adding a variable.


Cheers & hth.,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Easy questions from a python beginner

2010-07-12 Thread Alf P. Steinbach /Usenet

* Rami Chowdhury, on 13.07.2010 00:14:

Perhaps I'm misunderstanding, but ...

On Jul 12, 2010, at 13:57 , Alf P. Steinbach /Usenet wrote:


Existence of a variable means, among other things, that

  * You can use the value, with guaranteed effect (either unassigned exception
or you get a proper value)


Surely by that definition any variable in any Python program "exists" -- you
are guaranteed to get one of NameError, UnboundLocalError, or a value. That
seems to argue away the meaning of the word entirely, and renders it not
particularly useful.


No, you're conflating non-existence (NameError) with accessing the value of an 
existing but unassigned variable (UnboundLocalError). It is like arguing that 
vacuum is the same as cement because sticking your head into it for ten minutes 
or so yields an effect  --  you're dead  --  that in many ways is just about the 
same. However, the tangible existence of cement means that one can pour it over 
your head, /adding/ the cement, while it's difficult to pour vacuum over your 
head; rather, for the latter effect one would need to /remove/ the air around 
your head. OK, the analogy halts a little. But I think you'll get it.


Similarly, you can add a variable and thereby cause am UnboundLocalError, and 
you can remove a variable and thereby cause a NameError.




How the Python implementation implements that is an implementation detail.

In short, how CPython does things is completely irrelevant to the language's

semantics, so you're conflating things here.




As I'd understood the previous discussion, it is the CPython implementation
that reserves local names and produces UnboundLocalErrors. The language
semantics don't call for it, and another implementation might choose to handle
function locals the same way as globals, through a namespace dictionary -- in
which case the variable *wouldn't* exist in any way, shape, or form until it
was assigned to.

What am I getting wrong here?


The bit about the language semantics not specifying the effect.

From the 3.1.1 language reference §4.1:

"When a name is not found at all, a NameError exception is raised. If the name 
refers to a local variable that has not been bound, a UnboundLocalError 
exception is raised. UnboundLocalError is a subclass of NameError."


And it goes on to elaborate on that, a little later:

"If a name binding operation occurs anywhere within a code block, all uses of 
the name within the block are treated as references to the current block. This 
can lead to errors when a name is used within a block before it is bound. This 
rule is subtle. Python lacks declarations and allows name binding operations to 
occur anywhere within a code block. The local variables of a code block can be 
determined by scanning the entire text of the block for name binding operations."


In short, Stephen D'Aprano's remarks were technically on the spot, while Rhodri 
James's follow up, that it seems influenced your response, was meaningless 
mumbo-jumbo with strong emphasis added repeatedly to denials of reality.


This is the usual reaction of the religious when exposed to reality.


Cheers & hth.,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Standard distutils package problems with MSVC / lacking functionality?

2010-07-12 Thread Alf P. Steinbach /Usenet

I let the setup.py script talk:



# 03_1__noddy

from distutils.core import setup, Extension
import distutils.ccompiler

compilerName = distutils.ccompiler.get_default_compiler()
options = []
if compilerName == "msvc":
# * distutils sets warning level 3:
#   Overriding with warning level 4 generates command line warning D9025...
#   There's no good away around that, it needs fix/extension of distutils
#   or the config file(s) that distutil uses (perhaps that's a makefile?).
options.append( "/W4" ) # Must be done in this script.
# * distutils forgets to enable exception handling:
options.append( "/EHsc" )   # Could be done via CL env. var.
# * distutils forgets to enable RTTI:
options.append( "/GR" ) # Could be done via CL env. var.
# * distutils forgets to enable standard 'for' loop and 'wchar_t' type:
options.append( "/Zc:forScope,wchar_t" )# Could be done via CL env. var.

module1 = Extension(
name = "noddy",
sources = [ "noddy.cpp" ],
extra_compile_args = options
)

setup(
name= "noddy",
version = '1.0',
description = 'This is a demo package',
ext_modules = [module1]
)



Cheers,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Easy questions from a python beginner

2010-07-12 Thread Alf P. Steinbach /Usenet

* Rhodri James, on 12.07.2010 22:19:

On Mon, 12 Jul 2010 13:56:38 +0100, bart.c  wrote:


"Steven D'Aprano"  wrote in
message news:4c3aedd5$0$28647$c3e8...@news.astraweb.com...

On Mon, 12 Jul 2010 09:48:04 +0100, bart.c wrote:


That's interesting. So in Python, you can't tell what local variables a
function has just by looking at it's code:



def foo(day):
if day=="Tuesday":
x=0
print ("Locals:",locals())

#foo("Monday")

Does foo() have 1 or 2 locals?


That's easy for CPython: it prepares two slots for variables, but only
creates one:


foo("Monday")

('Locals:', {'day': 'Monday'})

foo.func_code.co_varnames

('day', 'x')

foo.func_code.co_nlocals

2

So, the question is, is x a local variable or not? It's not in locals,
but the function clearly knows that it could be.


So Alf P.S. could be right; x exists, but Python pretends it doesn't
until it's assigned to.


CPython, not Python. And as Steven said, x *doesn't* exist. Allowance is
made by that specific implementation of the interpreter because x
*might* exist, but in this particular case it doesn't and a more dynamic
implementation might choose not to reserve a slot just in case. x is
created until it's actually used.


You are conflating existence with space allocation.

It's up to the implementation whether to allocate memory for the variable's 
reference in any particular case where that memory isn't strictly required. This 
is known as "optimization". Optimization depends on the implementation.


Existence of a variable means, among other things, that

  * You can use the value, with guaranteed effect (either unassigned exception
or you get a proper value): in particular, you won't be accessing a global
if you're using the name of a local declared by a later assignment.

  * You can assign to it.

How the Python implementation implements that is an implementation detail.

In short, how CPython does things is completely irrelevant to the language's 
semantics, so you're conflating things here.



Cheers & hth.,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Easy questions from a python beginner

2010-07-12 Thread Alf P. Steinbach /Usenet

* Steven D'Aprano, on 12.07.2010 04:39:

On Mon, 12 Jul 2010 03:12:10 +0200, Alf P. Steinbach /Usenet wrote:


* MRAB, on 12.07.2010 00:37:

[...]

In Java a variable is declared and exists even before the first
assignment to it. In Python a 'variable' isn't declared and won't exist
until the first 'assignment' to it.


That is a misconception.

In Python a variable is declared by having an assignment to it, which
for a local variable may be anywhere within a routine.


Oh, I'm going to regret being sucked into this...

In *CPython*, but not necessarily other implementations, variables which
are local to a function are not kept in a dictionary-based namespace, but
in slots in the code object (not to be confused with __slots__ used for
classes). Python has STORE_FAST and LOAD_FAST byte-codes for accessing
locals.

This is intended as a speed, and possibly memory, optimization. I don't
believe this is a requirement though, so implementations may not do this.

It is true that the slot is created at compile time, and in *that sense*,
local variables exist before they are bound. I'm not entirely convinced
that this is the only sense that matters, but never mind. The error
message given exposes this to the user:


def f():

... print x
... x = 1
...

f()

Traceback (most recent call last):
   File "", line 1, in
   File "", line 2, in f
UnboundLocalError: local variable 'x' referenced before assignment


If you try this with a global, you get this:


def f():

... global x
... print x
...

f()

Traceback (most recent call last):
   File "", line 1, in
   File "", line 3, in f
NameError: global name 'x' is not defined

In this case, there's no doubt that global variable "x" doesn't exist at
all -- there is no key "x" in the global namespace.


Yes.

What I disproved was the statement that every Python variable is created by the 
execution of an assignment.


Some (the global ones) are. :-)



It seems to me that "a slot to hold the variable is created for local
variables" is an implementation detail, not a language feature.


Yes.

However, any Python implementation has to implement the same user level 
semantics in some way (note: use level semantics do not include "space reserved" 
for an unassigned variable, or even for all assigned variables since with single 
assignment a sufficiently smart compiler can optimize away the space, but user 
level semantics do include existence and resultant effect).


As I see it it doesn't matter whether the implementation is CPython call frame 
slots or that mechanism called something else or a different mechanism called 
the same or a different mechanism called something different; what IMO matters 
is same semantics, that any assignment to a variable within a routine serves as 
a compile time declaration, creating that local variable in advance, unless, 
with Python 3.x., that name has been declared as a 'global' or 'nonlocal'.


So, this is a possible point of disagreement.

I say the semantics of local variable creation are part of the language 
definition, but I get the /impression/ that maybe you think it's 
CPython-specific, that e.g.


  def foo():
  x
  x = 0

might not raise an unassigned variable exception with some conforming Python 
implementation, i.e. different effect for same code with different 
implementations, that this is at least /unspecified behavior/ in Python?




CPython
could easily hide the difference by changing the exception from
UnboundLocalError to:

NameError: local name 'x' does not exist

and nobody would be any wiser. (Well, perhaps people who catch
UnboundLocalError, but why would you do that?)

I also note that UnboundLocalError is a subclass of NameError, so
"variable exists but is not bound" is considered to be a special case of
"variable doesn't exist" rather than a completely independent case. In
that sense, I think I'm on solid ground to say that in Python variables
don't exist until they are bound to a value, and leave it to pedants like
you and I to mention that for CPython local variables have space reserved
for them by the compiler before they are bound.


He he. I wouldn't say "space reserved". That is an implementation detail.


Cheers,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Easy questions from a python beginner

2010-07-12 Thread Alf P. Steinbach /Usenet

* sturlamolden, on 12.07.2010 16:59:

On 12 Jul, 07:51, "Alf P. Steinbach /Usenet"  wrote:


We're talking about defining a 'swap' routine that works on variables.


I did not miss the point. One cannot make a swap function that rebinds
its arguments in the calling stack frame. But a swap function can swap
values, given that the type is not immutable:

def swap(a,b):
a[0],b[0] = b[0],a[0]


a,b = [1],[2]
swap(a,b)
print a,b

[2] [1]


OK, that's missing the point.

I thought you were joking.


Cheers & hth.,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Design questions for C++ support for Python extensions (cppy)

2010-07-12 Thread Alf P. Steinbach /Usenet

Hi.

With the current cppy code the Python 3.1.1 doc's spam example extension module 
looks like this (actual working code):




#include 
#include 
using namespace progrock;

namespace {

class Spam: public cppy::Module
{
public:
Spam(): cppy::Module( L"spam", L"blåbærsyltetøy er blått" )
{}

PyObject* system( PyObject* args )
{
const char *command;
if( !PyArg_ParseTuple( args, "s", &command ) )
{
return NULL;
}
int const sts = ::system( command );
return Py_BuildValue( "i", sts );
}
};

}// namespace 

CPPY_MODULE_CROUTINE( Spam, system, L"Execute a shell command" )

PyMODINIT_FUNC PyInit_spam()
{
return cppy::safeInit< Spam >();
}



Issues:

  1. Wide string literals OK?
 The basic Python API often requires UTF-8 encoded byte strings. With C++
 source code encoded using e.g. Windows ANSI Western, string literals with
 national characters such as Norwegian ÆØÅ then become gobbledegook or cause
 outright failure. I balanced the hypothetical need for string literals with
 national characters, versus perceived unnaturalness of wide string literals
 for *nix developers, in favor of the former, i.e. L"wide string literals".

 Related issue here: in Windows MinGW g++ can not compile utf-8 encoded
 source with BOM, while MSVC requires a BOM in order to detect the encoding.

 Is L"this" an acceptable decision if you were to use something like cppy?

  2. Exception translation OK?
 The code within the 'system' member routine could conceivably be reduced to
 a single short line by adding some C++ support, but that would require use
 of exceptions to report errors. Translating C++ exceptions to Python
 exceptions does however add some overhead to every Python -> C++ call.
 Currently I do this only for the module initialization code, but should it
 be done for every exported method? Or perhaps as user choice? Benefit of
 translation e.g. reducing 'system' above to sweet single line. Cost is
 setup of try-block (negligible) and exception translation (inefficient).

  3. Some unsafety OK?
 In 'PyInit_spam' there may be a window of opportunity for client code to
 Mess Things Up. Within the cppy::safeInit the C++ module object is created
 and creates a Python module object, and if anything fails then the C++ side
 frees the Python object. And after PyInit_spam has returned to Python the
 cleanup responsibility resides with the Python interpreter: freeing the
 Python module object causes the C++ object to be destroyed. But if say the
 client code's equivalent of 'PyInit_spam' calls cppy::safeInit and just
 discards the result and returns 0 (say) to Python, then it seems to not be
 documented whether Python will free the Python module, i.e. possible leak.

  4. Threading?
 Is it necessary to make singletons/statics thread safe? Or does Python
 ensure that no other threads execute while PyInit_spam is called? Can it
 be called simultaneously by two or more threads?

  5. Reload of interpreter?
 My impression from the documentation is that finalization and reinit of the
 interpreter is something that an application shouldn't really do, and that
 an extension developer need not worry about that happening. Is it so?


Cheers,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Easy questions from a python beginner

2010-07-11 Thread Alf P. Steinbach /Usenet

* sturlamolden, on 12.07.2010 06:52:

On 11 Jul, 21:37, "Alf P. Steinbach /Usenet"  wrote:


Oh, I wouldn't give that advice. It's meaningless mumbo-jumbo. Python works like
Java in this respect, that's all; neither Java nor Python support 'swap'.


x,y = y,x



We're talking about defining a 'swap' routine that works on variables.

Since Java/Python doesn't support pass by reference of variables it's not 
possible in these languages, i.e., you missed the point, or made a joke. :-)


However, C# is very similar to Java, nearly all the way, except that in C# you 
can pass by reference. Remove that from C# and you have Java. Add that to Java 
and you have C#, roughly. No change in other aspects is needed. E.g. (ignore 
this if you've never heard about it, but it's a subtle point that you might be 
wondering about now) both Java and C# implement the definite assignment rule.


I.e., there's nothing in the core semantics that prevents accessing/passing the 
variables by reference, although for Python and Java it could be a 
terminological nightmare, and for Python compounded to the n'th degree by the 
general confusion of a subset of the Python community about basic concepts.


I don't know how C#'ers resolve the terminology...


Cheers & hth.,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Easy questions from a python beginner

2010-07-11 Thread Alf P. Steinbach /Usenet

* MRAB, on 12.07.2010 04:09:

Alf P. Steinbach /Usenet wrote:

* MRAB, on 12.07.2010 00:37:

Alf P. Steinbach /Usenet wrote:

* Stephen Hansen, on 11.07.2010 21:00:

On 7/11/10 11:45 AM, wheres pythonmonks wrote:

Follow-up:
Is there a way to define compile-time constants in python and have
the
bytecode compiler optimize away expressions like:

if is_my_extra_debugging_on: print ...

when "is_my_extra_debugging" is set to false? I'd like to pay no
run-time penalty for such code when extra_debugging is disabled.


Any code wrapped in a __debug__ guard is utterly ommitted if you run
Python with the -O option. That, and asserts go away.


On #2: My point regarding the impossibility of writing the swap
function for ints is to explicitly understand that this isn't
possible, so as not to look for solutions along those lines when
trying to write python code.


Its impossible because Python's calling and namespace semantics simply
don't work like that. There's no references in the traditional sense,
because there's no variables-- boxes that you put values in. There's
just concrete objects. Objects are passed into the function and given
new names; that those objects have names in the enclosing scope is
something you don't know, can't access, and can't manipulate.. even
the
objects don't know what names they happen to be called.

Check out http://effbot.org/zone/call-by-object.htm


Oh, I wouldn't give that advice. It's meaningless mumbo-jumbo. Python
works like Java in this respect, that's all; neither Java nor Python
support 'swap'.

Of course there are variables, that's why the docs call them variables.


In Java a variable is declared and exists even before the first
assignment to it. In Python a 'variable' isn't declared and won't exist
until the first 'assignment' to it.


That is a misconception.

In Python a variable is declared by having an assignment to it, which
for a local variable may be anywhere within a routine.

If such a variable is used before it's been assigned to, then you get
an uninitialized variable exception. Clearly the variable must exist
in order for the exception to refer to it (not to mention the
exception occurring at all).

def foo():
print( blah )
blah = "this is both an assignment and a declaration causing it to exist"

foo()

Clearly when the exception is raised, referring to the variable, the
variable exists.

Contrary to your statement that is before the assignment.

However, as stated up-thread, I do not expect facts, logic or general
reasoning to have any effect whatsoever on such hard-core religious
beliefs. And I do not care whether I convince you or not. But I *do
not* want the religious subset of the community to succeed too much in
propagating nonsense idiot beliefs to newbies -- hence the concrete
example that any newbie can try.


How about this:

 >>> def foo():
print("Before:", locals())
x = 0
print("After:", locals())


 >>> foo()
Before: {}
After: {'x': 0}


How about it?

Note that you get the same result if you do

x = "blah"
def foo():
# print( x )  # Causes uninitialized variable exception here
print( "Before:", locals() )
x = 0
print( "After:", locals() )

However, if you remove the local assignment to x, then the out-commented print 
statement will no longer cause an exception, it will then refer to the global.


The reason that it does throw an exception when you do have the local 
assignment, is that the local x exists at that point. If it didn't exist it 
could not have any effect. Things that don't exist generally have no effect, 
except in the minds of the religious, like angels and so on.


On the basis of what locals() reports it should be OK to refer to the global x 
as above. Judging by locals(), there's no local x that could get in the way. But 
since it is not OK to refer to the global x, the result of locals() has nothing 
to do with that: it doesn't tell you about the local x  --  and no, the Python 
interpreter does not look forward in time to see that it will appear.


In passing, I should perhaps have told you up front, your argument has nothing 
substantial to do with the article you originally responded to, about the 
semantics of variables. Your argument is the assertion that different languages 
can't have similar or identical semantics for some feature. That's nonsense in 
itself, plus, as you've seen, the difference that you focused on is not there, 
and, third, what you do maintain is not there, doesn't exist, has a real effect.



Cheers & hth.,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Easy questions from a python beginner

2010-07-11 Thread Alf P. Steinbach /Usenet

* Stephen Hansen, on 12.07.2010 04:02:

On 7/11/10 6:12 PM, Alf P. Steinbach /Usenet wrote:

However, as stated up-thread, I do not expect facts, logic or general
reasoning to have any effect whatsoever on such hard-core religious
beliefs.


Grow up, and/or get a grip, and/or get over yourself.

Everyone who disagreed with you, disagreed with you with arguments,
logic, facts, and reasoning. You disputed those facts, disagreed with
the conclusions, but for you to then just dismiss people who don't agree
with you as merely "religious", is childish.

Exactly why I think you're wrong -- you're free to go re-read, I stand
by my statements in this thread, and the others. The same arguments
apply. Its not a religion, dear; my conclusions are not a matter of faith.

That's all I have to say on this subject; the conversation has been had,
at length (repeatedly).

I swear, I'm just going to filter you and Rick out to /dev/null today
and leave it at that at this rate. I'm getting worn out of these kinds
of responses.


Well, the above is flaming, which I predicted.

The alleged facts etc. you're referring are just that, alleged, by you.

In contrast, in debates among non-religious folks facts are /presented/, like 
I've done in this thread, e.g. concrete code, instead of like you alleging that 
facts have been presented, hinting about things, and so on  --  it's pathetic.



Cheers & hth.,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Easy questions from a python beginner

2010-07-11 Thread Alf P. Steinbach /Usenet

* MRAB, on 12.07.2010 00:37:

Alf P. Steinbach /Usenet wrote:

* Stephen Hansen, on 11.07.2010 21:00:

On 7/11/10 11:45 AM, wheres pythonmonks wrote:

Follow-up:
Is there a way to define compile-time constants in python and have the
bytecode compiler optimize away expressions like:

if is_my_extra_debugging_on: print ...

when "is_my_extra_debugging" is set to false? I'd like to pay no
run-time penalty for such code when extra_debugging is disabled.


Any code wrapped in a __debug__ guard is utterly ommitted if you run
Python with the -O option. That, and asserts go away.


On #2: My point regarding the impossibility of writing the swap
function for ints is to explicitly understand that this isn't
possible, so as not to look for solutions along those lines when
trying to write python code.


Its impossible because Python's calling and namespace semantics simply
don't work like that. There's no references in the traditional sense,
because there's no variables-- boxes that you put values in. There's
just concrete objects. Objects are passed into the function and given
new names; that those objects have names in the enclosing scope is
something you don't know, can't access, and can't manipulate.. even the
objects don't know what names they happen to be called.

Check out http://effbot.org/zone/call-by-object.htm


Oh, I wouldn't give that advice. It's meaningless mumbo-jumbo. Python
works like Java in this respect, that's all; neither Java nor Python
support 'swap'.

Of course there are variables, that's why the docs call them variables.


In Java a variable is declared and exists even before the first
assignment to it. In Python a 'variable' isn't declared and won't exist
until the first 'assignment' to it.


That is a misconception.

In Python a variable is declared by having an assignment to it, which for a 
local variable may be anywhere within a routine.


If such a variable is used before it's been assigned to, then you get an 
uninitialized variable exception. Clearly the variable must exist in order for 
the exception to refer to it (not to mention the exception occurring at all).


  def foo():
  print( blah )
  blah = "this is both an assignment and a declaration causing it to exist"

  foo()

Clearly when the exception is raised, referring to the variable, the variable 
exists.


Contrary to your statement that is before the assignment.

However, as stated up-thread, I do not expect facts, logic or general reasoning 
to have any effect whatsoever on such hard-core religious beliefs. And I do not 
care whether I convince you or not. But I *do not* want the religious subset of 
the community to succeed too much in propagating nonsense idiot beliefs to 
newbies  --  hence the concrete example that any newbie can try.



Cheers & hth.,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Easy questions from a python beginner

2010-07-11 Thread Alf P. Steinbach /Usenet

* Stephen Hansen, on 11.07.2010 21:00:

On 7/11/10 11:45 AM, wheres pythonmonks wrote:

Follow-up:
Is there a way to define compile-time constants in python and have the
bytecode compiler optimize away expressions like:

if is_my_extra_debugging_on: print ...

when "is_my_extra_debugging" is set to false?  I'd like to pay no
run-time penalty for such code when extra_debugging is disabled.


Any code wrapped in a __debug__ guard is utterly ommitted if you run
Python with the -O option. That, and asserts go away.


On #2:  My point regarding the impossibility of writing the swap
function for ints is to explicitly understand that this isn't
possible, so as not to look for solutions along those lines when
trying to write python code.


Its impossible because Python's calling and namespace semantics simply
don't work like that. There's no references in the traditional sense,
because there's no variables-- boxes that you put values in. There's
just concrete objects. Objects are passed into the function and given
new names; that those objects have names in the enclosing scope is
something you don't know, can't access, and can't manipulate.. even the
objects don't know what names they happen to be called.

Check out http://effbot.org/zone/call-by-object.htm


Oh, I wouldn't give that advice. It's meaningless mumbo-jumbo. Python works like 
Java in this respect, that's all; neither Java nor Python support 'swap'.


Of course there are variables, that's why the docs call them variables.

We've had this discussion before and I know from that that it is a religious 
issue with a small subset of the Python community, where reason, facts, logic 
does not apply and is not even recognized as such. So be it. So I'm not out to 
convince you or other of that sub-community, or trying to reason with you folks 
on this issue (futile, and generates flames pretty fast), but I do not want 
newbies brainwashed into that non-reasoning nonsense pure faith religion.


For what it's worth, I'm sure that the effbot.org author, whose pages are 
otherwise quite technically meaningful & useful, in this case, after the flame 
war with some Java folks, decided that technical accuracy just wasn't worth it.


So, I believe, he punted, which is an eminently rational choice when one's goals 
require acceptance in a society dominated by a religious clique. And just as I'm 
not out to engage you in any debate on this issue (futile), neither am I calling 
you irrational. Perhaps your choice is the same as that author's.



Cheers,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Naming Conventions, Where's the Convention Waldo?

2010-07-11 Thread Alf P. Steinbach /Usenet

* rantingrick, on 11.07.2010 09:26:


Another source of asininity seems to be the naming conventions of the
Python language proper! True/False start with an upper case and i
applaud this. However str, list, tuple, int, float --need i go
on...?-- start with lowercase.

Q: Well what the hell is your problem Rick. Who cares right?

WRONG, I tell you what my problem is. Now i cannot "wisely" use
variables like...

str="this is a string"
list = [1,2,3]
def make_random_objs(range=10)
def show_message(str)
int = 12

If we would have adopted proper naming conventions from dios numero
uno all this nonsense would be rectified! Str, Float, List, Range,
etc, etc. You think Python 3000 was a hump to climb over just wait for
Python 4000.

Just thoughts.


Just do

  Str = str
  List = list
  Float = float

and so on in module "myBasicTypes", and import that.

:-)

Cheers & hth.,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: integer >= 1 == True and integer.0 == False is bad, bad, bad!!!

2010-07-11 Thread Alf P. Steinbach /Usenet

* Stephen Hansen, on 11.07.2010 09:19:

On 7/10/10 11:50 PM, rantingrick wrote:


It was a typo not an on purpose misspelling


If this had been the first time, perhaps. If you had not in *numerous*
previous times spelled my name correctly, perhaps. If it were at all
possible for "f" to be a typo of "ph", perhaps.


It is a natural mistake to make in some languages. E.g. in Norwegian the Devil 
can be spelled Faen or Fanden (modern) or Phanden (old-fashioned, no longer in 
dictionaries but still used to sort of tone down the expression). It's even 
there in English, like "file" and "philosophy". So it's an error committed not 
by the limbic system but by a slightly higher level sound-to-text translator 
brain circuit. The text is generated from how the word sounds in one's head.



Cheers & hth.,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: integer >= 1 == True and integer.0 == False is bad, bad, bad!!!

2010-07-11 Thread Alf P. Steinbach /Usenet

* rantingrick, on 11.07.2010 08:50:

On Jul 11, 1:22 am, Stephen Hansen  wrote:


Utter nonsense. No one does that unless they are coming from C or some
other language without a True/False and don't know about it, or if they
are using a codebase which is supporting a very old version of Python
before True or False were introduced.


Ah yes, when nothing else seems to work fall back to you default
programming... FUD and ad hominem
attacks


I agree with Stephen, but for a different reason: that given desirability of 
implicit conversion to bool for some elementary types, then for uniformity there 
should be such conversion for all of them (and AFAIK there is), and given that, 
the rule should be the same, namely that default value of each type bool's to 
False, and other values to True, and so it is.


The OP should simply represent "not found" as e.g. integer -1 instead of as a 
value of a different type.


And write e.g.

  not_found = -1

 ...

  if choiceIdx1 == choiceIdx2 == not_found:
  bah, none of them
  elif choice2Idx == not_found:
  use choice 1
  elif choice1Idx == not_found:
  use choice 2
  else:
  determine bestest choice


Cheers & hth.,

- Alf


--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: any issues with long running python apps?

2010-07-10 Thread Alf P. Steinbach /Usenet

* John Nagle, on 10.07.2010 20:54:

On 7/9/2010 12:13 PM, Les Schaffer wrote:

i have been asked to guarantee that a proposed Python application will
run continuously under MS Windows for two months time. And i am looking
to know what i don't know.

The app would read instrument data from a serial port,


If the device you're listening to is read-only, and you're just
listening, make a cable to feed the serial data into two machines,
and have them both log it. Put them on separate UPSs and in
a place where nobody can knock them over or mess with them.


"The Ramans do everything in triplicate" - Old jungle proverb


Cheers,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Not-quite-the-module-name qualified names in extension modules? What?

2010-07-10 Thread Alf P. Steinbach /Usenet

Hi.

I built the [xxmodule.c] from the source distribution, as suggested by the 
Python 3.1.1 docs. I named this [xx.pyd], as I believed the module name was just 
"xx". Indeed importing xx works fine, but when I do help(xx) I get ...




>>> help( xx )
Help on module xx:

NAME
xx - This is a template module just for instruction.

FILE

c:\projects\progrock\lib\progrock\cppy_dev\examples\02_xx_apilevel\xx.pyd

CLASSES
builtins.Exception(builtins.BaseException)
error
builtins.object
xxmodule.Null
builtins.str(builtins.object)
xxmodule.Str

class Null(builtins.object)
 |  Methods defined here:
 |



... with the name "xxmodule" somehow in there as qualification.

Checking the standard "csv" module I similarly get ...



CLASSES
builtins.Exception(builtins.BaseException)
_csv.Error
builtins.object
Dialect
excel
excel_tab
DictReader
DictWriter
Sniffer



... with the name "_csv" in there.

And I'm pretty sure that these not-quite-the-module-name names stem from the 
literal specification of names in the C code in the extension module, assuming 
that the csv module is indeed a C extension module.


Is it really necessary to qualify names in the C code?

And can it do harm when such name qualification is not using the final module 
name but instead something like "xxmodule" or "_csv"?


More to the point, what's the point?


Cheers,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Cpp + Python: static data dynamic initialization in *nix shared lib?

2010-07-09 Thread Alf P. Steinbach /Usenet

* Ian Collins, on 09.07.2010 23:22:

On 07/10/10 03:52 AM, Alf P. Steinbach /Usenet wrote:

[Cross-posted comp.lang.python and comp.lang.c++]

I lack experience with shared libraries in *nix and so I need to ask...

This is about "cppy", some support for writing Python extensions in C++
that I just started on (some days ago almost known as "pynis" (not funny
after all)).

For an extension module it seems that Python requires each routine to be
defined as 'extern "C"'. And although e.g. MSVC is happy to mix 'extern
"C"' and C++ linkage, using a routine declared as 'static' in a class as
a C callback, formally they're two different kinds, and I seem to recall
that /some/ C++ compiler balks at that kind of mixing unless specially
instructed to allow it. Perhaps it was the Sun compiler?


Yes, it will (correctly) issue a warning.

As the is a bit OT, contact me directly and we can work through it. I
have had similar fun and games adding PHP modules!


Thanks. I'm mailing you a zip with the code... 

The question, of course, whether it works in *nix.


Cheers,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Hello

2010-07-09 Thread Alf P. Steinbach /Usenet

* Dani Valverde, on 09.07.2010 18:31:

Hello!
I am new to python and pretty new to programming (I have some expertise
wit R statistical programming language). I am just starting, so my
questions may be a little bit stupid. Can anyone suggest a good editor
for python?
Cheers!


If you're working in Windows the Notepad++ and PSPad and old Crimson Editor (all 
free) all work nicely and are reasonably light-weight.



Cheers & hth.,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Cpp + Python: static data dynamic initialization in *nix shared lib?

2010-07-09 Thread Alf P. Steinbach /Usenet

[Cross-posted comp.lang.python and comp.lang.c++]

I lack experience with shared libraries in *nix and so I need to ask...

This is about "cppy", some support for writing Python extensions in C++ that I 
just started on (some days ago almost known as "pynis" (not funny after all)).


For an extension module it seems that Python requires each routine to be defined 
as 'extern "C"'. And although e.g. MSVC is happy to mix 'extern "C"' and C++ 
linkage, using a routine declared as 'static' in a class as a C callback, 
formally they're two different kinds, and I seem to recall that /some/ C++ 
compiler balks at that kind of mixing unless specially instructed to allow it. 
Perhaps it was the Sun compiler?


Anyway, to be formally correct I cannot generate the required C routines via 
templating, and I ended up using macros that the user must explicitly invoke, 
like, here the Py doc's first extension module example recoded using cppy,



--

#include 
#include 
using namespace progrock;

class Spam: public cppy::Module
{
public:
Spam(): cppy::Module( "spam" )
{
setDocString( L"blåbærsyltetøy er blått" );
}

PyObject* system( PyObject* args )
{
const char *command;
int sts;

if( !PyArg_ParseTuple( args, "s", &command ) )
{
return NULL;
}
sts = ::system( command );
return Py_BuildValue( "i", sts );
}
};

CPPY_MODULE_CROUTINE( Spam, system, "Execute a shell command" )

PyMODINIT_FUNC PyInit_spam()
{
return cppy::init< Spam >();
}

--


It works in Windows.

But here CPPY_MODULE_CROUTINE does three things:

  A Defining the 'extern "C"' routine.
I cannot think of any problem here.

  B Defining installation data for that routine.
Possible problem: initializing a static with address of routine?

  C -> Adding that install data record into a linked list!
Possible problem: are dynamic initialization actions guaranteed
to be performed in *nix shared library?

Problem (C) is outside the realm of the C++ standard, since the C++ standard 
doesn't support shared libraries, and I've never actually used *nix shared 
libraries so I don't /know/...


Is such dynamic initialization guaranteed?

For completeness, the macro definition (the 0 in there is a list next-pointer):



#define CPPY_MODULE_CROUTINE_DEF( cppClassName, name )  \
extern "C"  \
static PyObject* cppClassName##_##name( PyObject*, PyObject* args ) \
{   \
return ::progrock::cppy::module().name( args );   \
}

#define CPPY_MODULE_CROUTINE_INSTALLDATA( cppClassName, name, docString )   \
static ::progrock::cppy::detail::ModuleRoutineDescriptor\
cppClassName##_##name##_descriptor = {  \
0,  \
#name,  \
docString,  \
&cppClassName##_##name  \
};  \
\
static bool cppClassName##_##name##_descriptor_installed =  \
::progrock::cppy::detail::addToList< cppClassName >(\
cppClassName##_##name##_descriptor  \
);

#define CPPY_MODULE_CROUTINE( cppClassName, name, docString )   \
CPPY_MODULE_CROUTINE_DEF( cppClassName, name )  \
CPPY_MODULE_CROUTINE_INSTALLDATA( cppClassName, name, docString )



TIA.,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: How do I add method dynamically to module using C API?

2010-07-08 Thread Alf P. Steinbach /Usenet

* Martin v. Loewis, on 08.07.2010 09:13:

I tried (1) adding a __del__, but no dice, I guess
because it wasn't really an object method but just a free function in a
module; and (2) the m_free callback in the module definition structure,
but it was not called.


m_free will be called if the module object gets deallocated. So if
m_free really isn't called, the module got never deallocated.


Thanks again. I don't know what I did wrong. Now it's called. :-)

But I wasted much time googling to try to find out the /responsibilities/ of the 
m_free callback, and what its void* argument was. E.g., should it deallocate the 
module object, and if so, via what deallocation routine? I found some info, but 
even your PEP, otherwise clear, was silent about this fine point.


Finally I looked at the source code that invokes it and found that it has no 
responsibilities whatsoever, just a use-as-you-wish finalization callback. Nice!


But I think that could be more clear in the docs...

Code, for those who might be interested:



// progrock.cppy  --  "C++ plus Python"
// A simple C++ framework for writing Python 3.x extensions.
//
// Copyright (C) Alf P. Steinbach, 2010.

#ifndef CPPY_MODULE_H
#define CPPY_MODULE_H
#include 


//- Dependencies:

#include "Ptr.h"
#include 
#include 



//- Interface:

namespace progrock{ namespace cppy {

namespace detail {
struct InstanceData
{
std::list< PyMethodDef >methodDefs;
};

inline void* instanceMemoryOf( PyObject* pObject )
{
void* const result = PyModule_GetState( pObject );
assert( result != 0 );
return result;
}

inline InstanceData*& instanceDataPtrOf( PyObject* pObject )
{
return *reinterpret_cast< InstanceData** >(
instanceMemoryOf( pObject )
);
}

inline void on_freeModule( void* p )
{
PyObject* const pModule = reinterpret_cast< PyObject* >( p );
InstanceData* const pData   = instanceDataPtrOf( pModule );

delete pData;
printf( "Deallocated!\n" ); // TODO: Remove.
}

inline PyModuleDef* moduleDefPtr()
{
static PyMethodDef methodDefs[] = {
//...
//{ "system", &pyni_system, METH_VARARGS, "Execute a shell 
command." },

//{ "__del__", &onModuleDestroy, METH_NOARGS, "Destructor" },
//...
{ NULL, NULL, 0, NULL } // Sentinel
};

static PyModuleDef moduleDef = {
PyModuleDef_HEAD_INIT,
"cppy", // name of module
NULL,   // m_doc,   // module documentation in UTF-8
sizeof(void*), // size of per-interpreter state of the 
module,
//or -1 if the module keeps state in global 
variables.

methodDefs,
NULL,   // m_reload
NULL,   // m_traverse
NULL,   // m_clear
&on_freeModule  // m_free
};

return &moduleDef;
}
}

class Module
{
private:
Ptr p_;
detail::InstanceData*   data_;

detail::InstanceData*& instanceDataPtr() const
{
return detail::instanceDataPtrOf( p_.get() );
}

public:
Module()
: p_( ::PyModule_Create( detail::moduleDefPtr() ) )
, data_( 0 )
{
assert( detail::moduleDefPtr()->m_size == sizeof( void* ) );
(p_.get() != 0) || cppx::throwX( "Module::: failed" );
instanceDataPtr() = data_ = new detail::InstanceData();
}

PyObject* rawPtr() const{ return p_.get(); }
PyObject* release() { return p_.release(); }

void setDocString( wchar_t const s[] )
{
Ptr const v = ::PyUnicode_FromWideChar( s, -1 );
(v.get() != 0)
|| cppx::throwX( "Module::setDocString: PyUnicode_FromWideChar 
failed" );


::PyObject_SetAttrString( p_.get(), "__doc__", v.get() )
>> cppx::is( cppx::notMinusOne )
|| cppx::throwX( "Module::setDocString: PyObject_SetAttrString 
failed" );

}

void addRoutine( char const name[], PyCFunction f, char const doc[] = 
"" )
{
PyMethodDef const defData = { name, f, METH_VARARGS, doc };

data_->methodDefs.push_back( defData );
try
{
PyMethodDef* const  pDef= &data_->methodDefs.back();

Ptr const   pyName  = ::PyUnicode_FromString( name );
(pyName.get() != 0)
|| cppx::throwX( "Module::addRoutine: PyUnicode_FromString 
faile

Re: How do I add method dynamically to module using C API?

2010-07-07 Thread Alf P. Steinbach /Usenet

* Martin v. Loewis, on 08.07.2010 07:23:

And since things work for a single method when I declare 'def' as
'static', I suspect that means that the function object created by
PyCFunction_NewEx holds on to a pointer to the PyMethodDef structure?


Correct; it doesn't make a copy of the struct. So when you want the
function object to outlive the setRoutine call, you need to allocate
the PyMethodDef on the heap.


Thanks!

That's the direction I tentatively had started to investigate.

But second problem now is cleanup: I'd like to deallocate when the module is 
freed. I tried (1) adding a __del__, but no dice, I guess because it wasn't 
really an object method but just a free function in a module; and (2) the m_free 
callback in the module definition structure, but it was not called.


Perhaps I don't need to to clean up?

Anyway, current looks like this:



// progrock.cppy  --  "C++ plus Python"
// A simple C++ framework for writing Python 3.x extensions.
//
// Copyright (C) Alf P. Steinbach, 2010.

#ifndef CPPY_MODULE_H
#define CPPY_MODULE_H
#include 


//- Dependencies:

#include "Ptr.h"
#include 
#include 



//- Interface:

namespace progrock{ namespace cppy {

namespace detail {
inline PyModuleDef* moduleDefPtr()
{
static PyMethodDef methodDefs[] = {
//...
//{ "system", &pyni_system, METH_VARARGS, "Execute a shell 
command." },

//{ "__del__", &onModuleDestroy, METH_NOARGS, "Destructor" },
//...
{ NULL, NULL, 0, NULL } // Sentinel
};

static PyModuleDef moduleDef = {
PyModuleDef_HEAD_INIT,
"cppy", // name of module
NULL,   // m_doc,   // module documentation in UTF-8
sizeof(void*), // size of per-interpreter state of the 
module,
//or -1 if the module keeps state in global 
variables.

methodDefs,
NULL,   // m_reload
NULL,   // m_traverse
NULL,   // m_clear
NULL// m_free
};

return &moduleDef;
}
}

class Module
{
private:
struct InstanceData
{
std::list< PyMethodDef >methodDefs;
};

void* instanceMemory() const
{
void* const result = PyModule_GetState( p_.get() );
assert( result != 0 );
return result;
}

InstanceData*& instanceDataPtr() const
{
return *reinterpret_cast< InstanceData** >( instanceMemory() );
}

Ptr p_;
InstanceData*   data_;

public:
Module()
: p_( ::PyModule_Create( detail::moduleDefPtr() ) )
{
assert( def.m_size == sizeof( void* ) );
(p_.get() != 0) || cppx::throwX( "Module::: failed" );
instanceDataPtr() = data_ = new InstanceData();
}

PyObject* rawPtr() const{ return p_.get(); }
PyObject* release() { return p_.release(); }

void setDocString( wchar_t const s[] )
{
Ptr const v = ::PyUnicode_FromWideChar( s, -1 );
(v.get() != 0)
|| cppx::throwX( "Module::setDocString: PyUnicode_FromWideChar 
failed" );

::PyObject_SetAttrString( p_.get(), "__doc__", v.get() )
>> cppx::is( cppx::notMinusOne )
|| cppx::throwX( "Module::setDocString: PyObject_SetAttrString 
failed" );

}

void addRoutine( char const name[], PyCFunction f, char const doc[] = 
"" )
{
PyMethodDef const defData = { name, f, METH_VARARGS, doc };

data_->methodDefs.push_back( defData );
try
{
PyMethodDef*pDef= &data_->methodDefs.back();

Ptr const   pyName  = ::PyUnicode_FromString( name );
Ptr r   = ::PyCFunction_NewEx( pDef, p_.get(), 
pyName.get());


::PyModule_AddObject( p_.get(), name, r.release() )
>> cppx::is( cppx::notMinusOne )
|| cppx::throwX( "Module::addRoutine: PyModule_AddObject 
failed" );

}
catch( ... )
{
data_->methodDefs.pop_back();
throw;
}
}
};

} }  // namespace progrock::cppy


#endif



I changed the module name from "pyni*" to "cppy"... ;-)


Cheers & thanks!, but how to clean up, or must I?

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


How do I add method dynamically to module using C API?

2010-07-07 Thread Alf P. Steinbach /Usenet

The code below, very much work in progress, just trying things, is C++.

Sorry about the formatting, I had to reformat manually for this posting:



class Module
{
private:
Ptr p_;

public:
Module( PyModuleDef const& def )
: p_( ::PyModule_Create( const_cast< PyModuleDef* >( &def ) ) )
{
(p_.get() != 0) || cppx::throwX( "Module::: failed" );
}

PyObject* rawPtr() const{ return p_.get(); }
PyObject* release() { return p_.release(); }

void setDocString( wchar_t const s[] )
{
Ptr const v = ::PyUnicode_FromWideChar( s, -1 );
(v.get() != 0)
|| cppx::throwX( "PyUnicode_FromWideChar failed" );
int const _ = ::PyObject_SetAttrString(
p_.get(), "__doc__", v.get()
);
(_ != -1 )
|| cppx::throwX( "PyObject_SetAttrString failed" );
}

void setRoutine(
char const name[], PyCFunction f, char const doc[] = ""
)
{
PyMethodDef def = { name, f, METH_VARARGS, doc };

Ptr const   pyName  = ::PyUnicode_FromString( name );
Ptr r   = ::PyCFunction_NewEx(
&def, p_.get(), pyName.get()
);

int const _ = ::PyModule_AddObject( p_.get(), name, r.release() );
(_ != -1 )
|| cppx::throwX( "PyModule_AddObject failed" );
}
};



Problem: when a routine installed by 'setRoutine' above is called from Python, 
then it fails with e.g. "SystemError: Bad call flags in PyCFunction_Call. 
METH_OLDARGS is no longer supported!"


And since things work for a single method when I declare 'def' as 'static', I 
suspect that means that the function object created by PyCFunction_NewEx holds 
on to a pointer to the PyMethodDef structure?


I'm unable to find documentation of PyCFunction_NewEx, and more criticially, I'm 
unable to find any documented way to turn a C or C++ function into a Python 
function object?



Cheers,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Argh! Name collision!

2010-07-07 Thread Alf P. Steinbach /Usenet

* Alf P. Steinbach /Usenet, on 08.07.2010 01:47:


 enum DoAddRef { doAddRef };

 class Ptr
 {
 private:
 PyObject*   p_;

 public:
 Ptr( PyObject* p = 0 ): p_( p )
 {}

 Ptr( PyObject* p, DoAddRef ): p_( p )
 {
 assert( p != 0 );
 Py_INCREF( p_ );
 }

 Ptr( Ptr const& other ): p_( other.p_ )
 {
 Py_XINCREF( p_ );
 }

 ~Ptr()
 {
 Py_XDECREF( p_ );
 }

 void swapWith( Ptr& other ) { std::swap( p_, other.p_ ); }
 Ptr& operator=( Ptr other ) { swapWith( other ); return *this; }

 PyObject* get() const   { return p_; }

 PyObject* release()
 {
 PyObject* const result  = p_;
 Py_XDECREF( p_ );


Hark. This Py_XDECREF shouldn't be there, I don't know how it got there. The 
whole point of 'release', with conventional semantics, is to /not/ decrement the 
reference count.




 p_ = 0;
 return result;
 }
 };



Sorry for posting unfinished code,

- Alf


PS: "pyni" was a good name. But in use! When I thought about adding the "s" as 
disambiguation I thought the pure shock value of that was funny in a way, but 
now it doesn't seem funny. Is "pytes" (Python Extension Support) a good name?


--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Argh! Name collision!

2010-07-07 Thread Alf P. Steinbach /Usenet

* rantingrick, on 07.07.2010 07:42:

On Jul 6, 9:11 pm, "Alf P. Steinbach /Usenet"  wrote:


"pyni"! Pronounced like "tiny"! Yay!


hmm, how's about an alternate spelling... "pyknee", or "pynee", or
"pynie" ... considering those are not taken either?


Hm, for pure shock value I think I'll use the acronym PYthon Native Interface 
Support.


pynis! :-)

A set of C++ classes to ease the writing of extensions.

Like,



// progrock.pynis  --  "Python Native Interface Support"
// A simple C++ framework for writing Python 3.x extensions.
//
// Copyright (C) Alf P. Steinbach, 2010.

#ifndef PYNIS_PTR_H
#define PYNIS_PTR_H
#include 


//- Dependencies:

#include 
#include 
#include 



//- Interface:

namespace progrock{ namespace pynis {

enum DoAddRef { doAddRef };

class Ptr
{
private:
PyObject*   p_;

public:
Ptr( PyObject* p = 0 ): p_( p )
{}

Ptr( PyObject* p, DoAddRef ): p_( p )
{
assert( p != 0 );
Py_INCREF( p_ );
}

Ptr( Ptr const& other ): p_( other.p_ )
{
Py_XINCREF( p_ );
}

~Ptr()
{
Py_XDECREF( p_ );
}

void swapWith( Ptr& other ) { std::swap( p_, other.p_ ); }
Ptr& operator=( Ptr other ) { swapWith( other ); return *this; }

PyObject* get() const   { return p_; }

PyObject* release()
{
PyObject* const result  = p_;
Py_XDECREF( p_ );
p_ = 0;
return result;
}
};

} }  // namespace progrock::pynis


#endif



Cheers,

- Alf (shocked)

PS: Darn, forgot to google it. But I think it's unlikely the name's already in 
use!

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Download Microsoft C/C++ compiler for use with Python 2.6/2.7 ASAP

2010-07-07 Thread Alf P. Steinbach /Usenet

* Alf P. Steinbach /Usenet, on 07.07.2010 23:19:


However developing an extension with MSVC 10 the extension will use the
10.0 CRT, which is not necessarily present on the end user's system.

As I see it there are five solutions with different trade-offs:

A Already having Visual Studio 2008 (MSVC 9.0), or coughing up the
money for an MSDN subscription, or visiting trade shows, so as to
obtain that compiler version.
-> Not an option for everybody.

B Linking the CRT statically.
-> Increased size, problems with CRT state such as file descriptors.

C Linking the CRT dynamically and bundling the MSVC redistributables
with the extension.
-> Even more increased size for the download, but smaller total
footprint for extensions in sum; same CRT state problems.

D Linking the CRT dynamically and providing an optional download and
install of the redistributables if they're not present. This would
best be done with some support from the Python installation machinery.
-> Small nice size for extensions, still same CRT state problems.

E As D + a new compiler-independent native code interface that
does not carry dependencies on CRT state such as file descriptors, like
JNI.
-> Really huge effort, and cannot be applied until some new Python version.

And I think the clue here is that the CRT state problems can be avoided
by careful coding.

Hence, for those who cannot do A I think B is a realistic practical
option, and D would be nice...


Wait...

  F Possibly, as the docs say,

"Developer Studio will throw in a lot of import libraries that you do not really 
need, adding about 100K to your executable. To get rid of them, use the Project 
Settings dialog, Link tab, to specify ignore default libraries. Add the correct 
msvcrtxx.lib to the list of libraries."


Can anyone confirm whether this works in practice with MSVC 10?


Cheers,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Download Microsoft C/C++ compiler for use with Python 2.6/2.7 ASAP

2010-07-07 Thread Alf P. Steinbach /Usenet

* Christian Heimes, on 07.07.2010 22:47:

The main problem that the required MSVC redistributables are not necessarily
present on the end user's system.


It's not a problem for Python anymore. It took a while to sort all
problems out. Martin and other developers have successfully figured out
how to install the CRT for system wide and local user installations. A
system wide installation installs the CRT in the side by side cache
(WinSxS). A local installation keeps the msvcrt90.dll and the
Microsoft.VC90.CRT.manifest next to the python.exe. Python extensions no
longer embed a manifest so they share the CRT from the python.exe process.

In order to ship a standalone exe you have to keep the CRT next to your
exe. This should work for py2exe binaries as well. At our company we
install our application stack entirely from subversion including Python
2.6.5, Sun JRE and lots of other stuff. This works perfectly fine for us
even for servers without the MSVCRT redistributable.


I think you're talking about a different problem. The CRT installed along with 
CPython works for extensions using the MSVC 9.0 CRT.


However developing an extension with MSVC 10 the extension will use the 10.0 
CRT, which is not necessarily present on the end user's system.


As I see it there are five solutions with different trade-offs:

  A Already having Visual Studio 2008 (MSVC 9.0), or coughing up the
money for an MSDN subscription, or visiting trade shows, so as to
obtain that compiler version.
-> Not an option for everybody.

  B Linking the CRT statically.
-> Increased size, problems with CRT state such as file descriptors.

  C Linking the CRT dynamically and bundling the MSVC redistributables
with the extension.
-> Even more increased size for the download, but smaller total
   footprint for extensions in sum; same CRT state problems.

  D Linking the CRT dynamically and providing an optional download and
install of the redistributables if they're not present. This would
best be done with some support from the Python installation machinery.
-> Small nice size for extensions, still same CRT state problems.

  E As D + a new compiler-independent native code interface that
does not carry dependencies on CRT state such as file descriptors, like JNI.
-> Really huge effort, and cannot be applied until some new Python version.

And I think the clue here is that the CRT state problems can be avoided by 
careful coding.


Hence, for those who cannot do A I think B is a realistic practical option, and 
D would be nice...



Cheers,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Download Microsoft C/C++ compiler for use with Python 2.6/2.7 ASAP

2010-07-07 Thread Alf P. Steinbach /Usenet

* Martin v. Loewis, on 07.07.2010 21:56:

Perhaps (if it isn't intentional) this is a bug of the oversight type,
that nobody remembered to update the macro?


Update in what way?


I was guessing that at one time there was no PyMem_Malloc. And that it
was introduced to fix Windows-specific problems, but inadvertently
without updating the macro. It's just a guess as to reasons why the
macro uses malloc directly.


It might indeed be that the function version was introduced specifically
for Windows. However, the macro was left intentionally: both for
backwards compatibility, and for use inside Python itself.


Except for the problems with file descriptors I think a practical
interim solution for extensions implemented in C could be to just link
the runtime lib statically.

[...]


When I wrote "link the runtime lib statically" that was an alternative
to the usual link-as-DLL.


Ok, I lost the thread. When you said "a practical interim solution"
you were talking about what problem? I thought the discussion was
about the need to link with the same DLL version as Python.


The main problem that the required MSVC redistributables are not necessarily 
present on the end user's system.




It wouldn't make sense to link the runtime lib statically as an
alternative to linking it statically.


However, it would surely make sense to link with a different DLL than
the one that Python links with, assuming that would actually work.


As for linking to a different /version/ of the CRT, if you really mean
that, I think that's difficult. It's not necessarily impossible, after
all there's STLPort. But I think that it must at the very least be
rather difficult to do with Microsoft's tools, for otherwise people
would have employed that solution before, and so I wouldn't trust the
result, and wouldn't waste the time trying.


It's actually straight-forward (or used to be, until they came up with
the SxS madness). It was actually the case that people did so
unexpectingly, and it seemed to work fine, except that it crashed when
passing FILE*. Then we started explaining that mixing CRTs is risky.


Oh.

Well then. :-)


Cheers,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Download Microsoft C/C++ compiler for use with Python 2.6/2.7 ASAP

2010-07-07 Thread Alf P. Steinbach /Usenet

* sturlamolden, on 07.07.2010 21:46:

On 7 Jul, 21:41, "Alf P. Steinbach /Usenet"  wrote:


You still have two CRTs linked into the same process.


So?


CRT resources cannot be shared across CRT borders. That is the
problem. Multiple CRTs are not a problem if CRT resources are never
shared.


Yeah, but then we're down to file descriptors, C library locales and such as the 
remaining problems.


Cheers,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Download Microsoft C/C++ compiler for use with Python 2.6/2.7 ASAP

2010-07-07 Thread Alf P. Steinbach /Usenet

* sturlamolden, on 07.07.2010 21:12:

On 7 Jul, 06:54, "Alf P. Steinbach /Usenet"  wrote:


PyAPI_FUNC(void *) PyMem_Malloc(size_t);

#define PyMem_MALLOC(n) (((n)<  0 || (n)>  PY_SSIZE_T_MAX) ? NULL \
 : malloc((n) ? (n) : 1))


I was afraid of that :(




Except for the problems with file descriptors I think a practical interim
solution for extensions implemented in C could be to just link the runtime lib
statically.


You still have two CRTs linked into the same process.


So?


Cheers,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Download Microsoft C/C++ compiler for use with Python 2.6/2.7 ASAP

2010-07-07 Thread Alf P. Steinbach /Usenet

* Martin v. Loewis, on 07.07.2010 21:10:

Python 3.1.1, file [pymem.h]:

PyAPI_FUNC(void *) PyMem_Malloc(size_t);

#define PyMem_MALLOC(n)(((n)<  0 || (n)>  PY_SSIZE_T_MAX) ? NULL \
 : malloc((n) ? (n) : 1))

The problem with the latter that it seems that it's intended for safety
but does the opposite...


Why do you say that? It certainly *does* achieve safety, wrt. to certain
errors, specifically:
- passing sizes that are out-of-range
- supporting malloc(0) on all systems


It uses malloc instead of PyMem_Malloc. malloc may well be different and use a 
different heap in an extension DLL than in the Python interpreter and other 
extensions. That's one thing that the docs (rightly) warn you about.




Perhaps (if it isn't intentional) this is a bug of the oversight type,
that nobody remembered to update the macro?


Update in what way?


I was guessing that at one time there was no PyMem_Malloc. And that it was 
introduced to fix Windows-specific problems, but inadvertently without updating 
the macro. It's just a guess as to reasons why the macro uses malloc directly.




Except for the problems with file descriptors I think a practical
interim solution for extensions implemented in C could be to just link
the runtime lib statically. For a minimal extension this increased the
size from 8 KiB to 49 KiB. And generally with MS tools the size is
acceptably small.


If you think that's fine for your extension module (which may well be
the case), go ahead.


I have no comment on that except pointing it out as a somewhat stupid, somewhat 
evil social inclusion/exclusion argument, talking to the audience. Argh. You're 
wasting my time. But anyway, 49 KiB is small by today's standards. For example, 
you get 20 of those in a single MiB, and about 20.000 in a single GiB.




But then, you could also just link with a different
DLL version of the CRT instead.


When I wrote "link the runtime lib statically" that was an alternative to the 
usual link-as-DLL.


It wouldn't make sense to link the runtime lib statically as an alternative to 
linking it statically.


As for linking to a different /version/ of the CRT, if you really mean that, I 
think that's difficult. It's not necessarily impossible, after all there's 
STLPort. But I think that it must at the very least be rather difficult to do 
with Microsoft's tools, for otherwise people would have employed that solution 
before, and so I wouldn't trust the result, and wouldn't waste the time trying.



Cheers,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Download Microsoft C/C++ compiler for use with Python 2.6/2.7 ASAP

2010-07-06 Thread Alf P. Steinbach /Usenet

* sturlamolden, on 06.07.2010 19:35:

On 6 Jul, 19:09, Thomas Jollans  wrote:


Okay, you need to be careful with FILE*s. But malloc and free? You'd
normally only alloc&  free something within the same module, using the
same functions (ie not mixing PyMem_Malloc and malloc), would you not?


You have to be sure PyMem_Malloc is not an preprocessor alias for
malloc (I haven't chaecked).


Python 3.1.1, file [pymem.h]:

PyAPI_FUNC(void *) PyMem_Malloc(size_t);

#define PyMem_MALLOC(n) (((n) < 0 || (n) > PY_SSIZE_T_MAX) ? NULL \
: malloc((n) ? (n) : 1))

The problem with the latter that it seems that it's intended for safety but does 
the opposite...


Perhaps (if it isn't intentional) this is a bug of the oversight type, that 
nobody remembered to update the macro?



  ***


Except for the problems with file descriptors I think a practical interim 
solution for extensions implemented in C could be to just link the runtime lib 
statically. For a minimal extension this increased the size from 8 KiB to 49 
KiB. And generally with MS tools the size is acceptably small.


I think that this would be safe because since the C API has to access things in 
the interpreter I think it's a given that all the relevant functions delegate to 
shared library (DLL) implementations, but I have not checked the source code.


As a more longterm solution, perhaps python.org could make available the 
redistributables for various MSVC versions, and then one could introduce some 
scheme for indicating the runtime lib dependencies of any given extension. Then 
when installing an extension the installer (distutils package functionality) 
could just check whether the required runtime is present, and if not give the 
user the choice of automatically downloading from python.org, or perhaps direct 
from Microsoft. This scheme would support dependencies on new runtime lib 
versions not yet conceived when the user's version of Python was installed.



Cheers,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Argh! Name collision!

2010-07-06 Thread Alf P. Steinbach /Usenet
Donald Knuth once remarked (I think it was him) that what matters for a program 
is the name, and that he'd come up with a really good name, now all he'd had to 
do was figure out what it should be all about.


And so considering Sturla Molden's recent posting about unavailability of MSVC 
9.0 (aka Visual C++ 2008) for creating Python extensions in Windows, and my 
unimaginative reply proposing names like "pni" and "pynacoin" for a compiler 
independent Python native code interface, suddenly, as if out of thin air, or 
perhaps out of fish pudding, the name "pyni" occurred to me.


"pyni"! Pronounced like "tiny"! Yay!

I sat down and made my first Python extension module, following the tutorial in 
the docs. It worked!


But, wait, perhaps some other extension is already named "piny"?

Google.

http://code.google.com/p/pyni/>, "PyNI is [a] config file reader/writer".

Argh!


- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Download Microsoft C/C++ compiler for use with Python 2.6/2.7 ASAP

2010-07-06 Thread Alf P. Steinbach /Usenet

* sturlamolden, on 06.07.2010 17:50:


Just a little reminder:

Microsoft has withdrawn VS2008 in favor of VS2010. The express version
is also unavailable for download.>:((

We can still get a VC++ 2008 compiler required to build extensions for
the official Python 2.6 and 2.7 binary installers here (Windows 7 SDK
for .NET 3.5 SP1):

http://www.microsoft.com/downloads/details.aspx?familyid=71DEB800-C591-4F97-A900-BEA146E4FAE1&displaylang=en

Download today, before it goes away!

Microsoft has now published a download for Windows 7 SDK for .NET 4.
It has the VC++ 2010 compiler. It can be a matter of days before the VC
++ 2008 compiler is totally unavailable.

It is possible to build C and Fortran extensions for official Python
2.6/2.7 binaries on x86 using mingw. AFAIK, Microsoft's compiler is
required for C++ or amd64 though. (Intel's compiler requires VS2008,
which has now perished.)

Remember Python on Windows will still require VS2008 for a long time.
Just take a look at the recent Python 3 loath threads.


Perhaps this all for the good.

There is no *technical* problem creating a compiler-independent C/C++ language 
binding. I believe that Java's JNI works fine no matter what compiler you use, 
although it's many many years since I've done JNI things. Similarly, Python 
should IMHO just have a well defined compiler independent native code interface, 
e.g. "PNI", or "pynacoin", the PYthon NAtive COde INterface :-)



Cheers,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: The real problem with Python 3 - no business case for conversion

2010-07-03 Thread Alf P. Steinbach /Usenet

* Steven D'Aprano, on 03.07.2010 16:24:

On Sat, 03 Jul 2010 08:46:57 -0400, D'Arcy J.M. Cain wrote:


On Fri, 02 Jul 2010 22:40:34 -0700
John Nagle  wrote:

  Not according to Vex's published package list:

http://www.vex.net/info/tech/pkglist/


Hold on.  That *is* the generated list and Python 3.1 is on it.  We have
both 2.6 and 3.1.  The 3.1 version is listed right below the 2.6 one.
The page is generated from pkg_info(1) and includes everything we have
installed from FreeBSD ports.


Pfft! Facts! You can prove anything you like with facts!


:-)

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Decorators, with optional arguments

2010-07-02 Thread Alf P. Steinbach /Usenet

* Stephen Hansen, on 02.07.2010 19:41:

Okay, so!

I actually never quite got around to learning to do deep and useful
magic with decorators. I've only ever done the most basic things with
them. Its all been a little fuzzy in my head: things like what order
decorators end up being called in if there's more then one, etc.

But in my current situation, what I'm wanting to do is have a decorator
that wraps a function but which takes an *optional* argument, and sets
that argument as an attribute on said function if its there.

Here's what some tweaking and playing around has gotten me, as a recipe:

 import functools

 def my_decorator(arg):
 if callable(arg): # Stuck on 2.5. Leavemealone. :)
 protocol = None
 else:
 protocol = arg

 def wrap(fn):
 print "Wrapping."
 fn.protocol = protocol

 @functools.wraps(fn)
 def wrapper(*args, **kwargs):
 print "Calling."
 result = fn(*args, **kwargs)
 print "Called."
 return result

 return wrapper

 if not protocol: # argument-less decorator
 print "Calling wrap."
 return wrap(arg)
 else:
 print "Returning wrap."
 return wrap

To be used as:

 class Thing(object):
 @expose
 def test1(self, arg1):
 return arg1

 @expose("testing")
 def test2(self, arg2):
 return arg2

So, my question: am I doing this right? :) Some play-through testing
appears to work. But, the dizzying array of nested def's up there leaves
me a bit dazed, so I'm wondering if there's a simpler way to accomplish
what I'm trying to do.


If you're willing to have slightly more explicit usage code, consider e.g.



#Py3

import functools

class expose:
def __init__( self, protocol = None ):
self._protocol = protocol

def __call__( self, f ):
print( "Wrapping." )
f.protocol = self._protocol

@functools.wraps( f )
def wrapper( *args, **kwargs ):
print( "Calling." )
result = f( *args, **kwargs )
print( "Called." )
return result

return wrapper

class Thing(object):
@expose()
def test1(self, arg1):
return arg1

@expose( "testing" )
def test2(self, arg2):
return arg2

o = Thing()
print( o.test1( 1.11 ) )
print( o.test2( 2.22 ) )



Cheers & hth.,

- Alf


--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Using Classes

2010-06-24 Thread Alf P. Steinbach /Usenet

* Mag Gam, on 24.06.2010 13:58:

I have been using python for about 1 year now and I really like the
language. Obviously there was a learning curve but I have a programing
background which made it an easy transition. I picked up some good
habits such as automatic code indenting :-), and making my programs
more modular by having functions.

I know that Python is very OOP friendly, but I could not figure out
why and when to use Classes in it. I mostly use it for simple text
parsing  I suppose when a program gets "complicated" I should start
using Classes. Are there any tips or tricks people use to "force" them
into the OOP mentality? I would like to force myself to learn the
Python way but so far I could not figure out WHY I would need a class
for this...


Use whatever paradigm that yields code that you easily understand. 

Having said that, the main use of a class is to model some data with an 
associated set of operations.


For this a class is merely a convenience, but sometimes the convenience can be 
so great that any other approach would be impractical in comparision.


In some cases a non-class approach ends up with a number of routines foo, bar, 
zlopf etc. that all take some argument of a "general" type and all internally 
has some "if it's really a BRACHYKLURB, do A, assuming that it has 
BRACHYKLURB-specific data, but if it's really a KNETCHOFICHUS, then do B, 
assuming that it has KNETCHOFICHUS-specific data, and as default, if it's none 
of those, do C".


This is a maintainance nightmare. You have to be sure that every such routine 
discriminates correctly on type, checking all possibilities and doing the right 
thing for each possibility. And you have to be sure of that in the face of 
possible additions of new subtypes, or removal of a subtype (maintainance).


Then the answer is to introduce some classes and OOP stuff.

In essence, instead of letting general routines awkwardly and error-prone choose 
the right type-specific routines depending on the object, let the object specify 
the right type-specific routines directly. :-)



Cheers & hth.,

- Alf

--
blog at http://alfps.wordpress.com>
--
http://mail.python.org/mailman/listinfo/python-list