Re: [Python-Dev] repeated keyword arguments

2008-06-28 Thread tomer filiba
On Jun 28, 12:56 am, Guido van Rossum [EMAIL PROTECTED] wrote:
 No, it could just be a harmless typo in a long argument list.

to elaborate on this point a little, i came across this error when i
ported my code to 2.4. i used the optparse class which takes 10's of
kwargs, and it turned out i'd given the same parameter twice (the
infamous copy-paste problem).

so on the one hand, it was a harmless typo (because the latest
instance was taken). on the other hand, it's a good thing i tested it
on 2.4, or i'd never notice the repeated argument, which may have led
to weird runtime errors (if the order of the params was changed).

i'd be in favor of fixing this in 2.5, just to eliminate possibly hard-
to-debug runtime errors. since it's a syntax error, it would be early-
noticed when the code is first run/imported, and it wouldn't require
the original author of the code to fix.


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


[Python-Dev] repeated keyword arguments

2008-06-27 Thread tomer filiba
the following code works on python 2.5:

 def f(**kwargs):
... print kwargs
...
 f(a=5,b=7,a=8)
{'a': 8, 'b': 7}


but fails on python2.4, saying that a is given twice.
is this a bug or a feature?


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


[Python-Dev] forceful exit

2008-06-22 Thread tomer filiba
hi

i'm having trouble when forking child processes to serve sockets. the
skeleton is something like the following:

def work():
try:
while True:
s = listener.accept()[0]
log(hello %s, s)
if os.fork() == 0:
try:
serve_client(sock)
finally:
sys.exit()     (1)
else:
log(forked child)
sock.close()
except KeyboardInterrupt:
log(got ctrl+c)
finally:
log(server terminated)
listener.close()

the problem is that sys.exit() raises an exception, which propagates
all the way up and is handled by the finallies... the real code does
more than just printing logs, so i can't allow that.

i'm forced to resort to os._exit, which does the trick but doesn't
perform cleanup, which made me realize there's no clean way in python
to *force* exit.

i think there ought to be something like sys.forcedexit(), which
collects all objects nicely and then exits immediately without letting
anything propagate up. this will also solve another problem i came
across, with threads. turns out only the main thread can kill the
process -- if another thread issues sys.exit, it only kills itself.
there's no clean way for a thread to terminate the process... i think
there must be.

i can contribute a patch in a matter of days... i think it's pretty
straight forward (calling Py_Finalize and then exit). aye or nay?


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


Re: [Python-Dev] misbehaving __contains__

2008-01-23 Thread tomer filiba
On Jan 23, 2008 3:19 AM, Raymond Hettinger [EMAIL PROTECTED] wrote:
 [Steven Bethard]

 We've already lost this if anyone really wants to break it::
 
  class C(object):
 ... def __iter__(self):
 ... return iter(xrange(3))
 ... def __contains__(self, item):
 ... return False
[snip]

 I'm more concerned about introducing an API where well-meaning attempts to 
 code a __contains__ override will implicitly shoot the toes off of client 
 code that innocently assumes a somewhat sensible invariant relation between 
 looping over elements in a container and those elements being in the 
 container.  The code for sets and frozensets makes that assumption, for 
 example.  And, when the code does break, the errors will be darned hard to 
 find.


well, i don't see how limiting __contains__ to returning booleans
solves the problem you mentioned. what you're talking about is
*semantics*, and that's always up to the programmer to get right.
allowing __contains__ to return a FooBar object won't change that a
bit -- but it will allow me to construct expression objects more
easily.

and, statements like

if x in y:
pass

will work as expected, assuming the object returned by
y.__contains__(x) has a proper __bool__/__nonzero__ method. we're just
deferring the type-cast to the point it's actually needed.

as per performance, i don't believe changing a slot method to return
PyObject* instead of int would change anything... am i wrong?



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


[Python-Dev] misbehaving __contains__

2008-01-22 Thread tomer filiba
i'm using python to create expression objects, for more intuitive
usage as
predicates, for instance:
x = (Arg(0)  17)  (Arg(1).foo == bar)
instead of
x = And(Gt(Arg(0), 17), Eq(GetAttr(Arg(1), foo), bar))

so now i can use x.eval(18, spam) and get the result of the
expression.

i'm doing it by overriding all the operators to return expression
objects,
instead of evaluating the result immediately. it works fine, but i
encountered
a problem with making __contains__ behave so.

it turns out __contains__ coerces the return value into a bool. this
might
seem logical at first, but is not consistent with the result of the
language.

consider the following code:

 class Foo(object):
... def __contains__(self, key):
... return 17
... def __eq__(self, other):
... return 19
...

 f=Foo()
 f == 8
19
 8 in f
True

as you can see, __eq__ does not coerces the result to bool, so why
should
__contains__ do that?

i've looked at PySequence_Contains in objects/abstract.c, but i can't
quite
understand where the coercion is made. is because the function is
typed
as int? if so, i believe it should either be changed to PyObject, or
have
cmp_outcome (in ceval.c) not use this API directly, and rather return
the
result as it is returned from __contains__.

i see no reason it should behave differently than __eq__ and the rest
of comparison operators.


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


Re: [Python-Dev] functional continuations

2007-12-16 Thread tomer filiba
yes, well, as i suspected and as PJE pointed out, extension or builtin
functions would
make life difficult, but these are difficulties i would be willing to
accept. however, my attempts
are futile anyways, as the evaluation stack is cleared before the exception
propagates up
to the frames above... which would explain the NULL deref exceptions i was
getting :)


-tomer

On Dec 16, 2007 12:54 AM, Greg Ewing [EMAIL PROTECTED] wrote:

 tomer filiba wrote:
  the idea i came up with is, using exceptions for functional
  continuations: after all, the exception's traceback holds the entire
  context...

 The problem with this is that, if the call chain has passed
 through a C-implemented function at some point, the traceback
 *doesn't* contain the entire context -- some of it is in the
 C stack frames that got unwound during the propagation of
 the exception.

 So you may be able to make this work where all the code
 involved is pure Python, but it can't work in general,
 unless you redesign the whole interpreter the way the
 original Stackless did.

 Having said that, it might still be a useful thing to
 have, as the pure-Python case is probably fairly common.
 But I'd want to know what the failure mode is like when
 the pure-Python case doesn't hold. Do you get a clear
 indication of what is wrong, or does it misbehave in
 some obscure way?

 A test case for this would be to call map() with a
 function that tries to suspend itself using this
 mechanism. What happens when you try to resume it?

 --
 Greg




-- 
An NCO and a Gentleman
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] functional continuations

2007-12-15 Thread tomer filiba
i'm working on some minimalistic asynchronous framework for python,
somewhat like twisted or stackless, but for different purposes. i came
to the conclusion i want to be able to freeze functions, and resume
them later, when some condition is matched.

the idea i came up with is, using exceptions for functional
continuations: after all, the exception's traceback holds the entire
context... so with some help from black magic (i.e., ctypes), i can
resurrect dead stackframes. i will have a reactor in the background
which manages the execution flow, and blocking operations (I/O, etc.)
will be wrapped with a thin wrapper, such as

class socket2(socket):
def recv(self, count = None):
raise WaitFor(self, r)
return socket.recv(self, count)

now, when read()ing from file2 objects, first an exception will
propagate up to the reactor, which will catch it, create a
continuation object (which holds the traceback) and register it with
the desired event.

then, when the event is triggered, the reactor will resurrect the
continuation object to the point where it stopped (f_lasti + 2), and
execution would continue normally from there.

the idea itself is similar to generator objects, and requires some
messing-around with f_back and f_lasti which is quite ugly. on the
other hand, the beauty of it is, it doesn't require any special design
patterns (unlike twisted) or replacing the interpreter (unlike
stackless), so it can be transparently used with any third-party libs.
all it takes is wrapping I/O objects to raise WaitFor(...) prior to
doing blocking I/O.

moreover, unlike generators, i gain the ability to propagate up to
the reactor (like normal exceptions), so the code in between the I/O
and the reactor needn't be aware of anything (only avoiding
unconstrained try-except blocks).

i wanted to get some feedback on the issue (i tried c.l.p, but they
didn't understand me well enough):
* has it been tried before?
* do you suppose it will work? are there any drawbacks i didn't
anticipate?
* is it useful enough to be added to the core interpreter (like
generators)? of course if it is added, it could be implemented with a
dedicated mechanism, rather than abusing exceptions for that.


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


Re: [Python-Dev] functional continuations

2007-12-15 Thread tomer filiba
yeah, i did think native functions wouldn't fit well with it, but then
again, i don't plan to have any c-side functions invoking python
callbacks. i can live with that. but, alas, ceval::EvalFrameEx will
clear the execution stack upon returning [1], so this couldn't work
anyway [2].

[1]
while (STACK_LEVEL()  b-b_level) {
v = POP();
Py_XDECREF(v);
}

[2] hrrrmpff


-tomer

On Dec 15, 2007 6:57 PM, Phillip J. Eby [EMAIL PROTECTED] wrote:
 At 01:04 AM 12/15/2007 -0800, tomer filiba wrote:
 * do you suppose it will work? are there any drawbacks i didn't
 anticipate?

 Yes.  :)

 Specifically, think about what happens when a C function is in the
 call stack, e.g.:

 def f1():
 return map(f2, [1,2,3])

 def f2(ob):
 raise WaitFor(something)
 return ob

 print f1()

 If I understand you correctly, when this program is run, it will
 print 1, rather than [1, 2, 3], because there is no way for you
 to keep track of the internal state of the 'map()' call.

 And this isn't just a problem for map() -- even something as simple
 as a property access passes through C code whose state can get lost.

 I don't think this approach is practical; you'd be better off using a
 co-routine stack and trampoline, since the nature of generators
 naturally forces all the C code out of the picture.





-- 
An NCO and a Gentleman
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] import file extensions

2007-09-14 Thread tomer filiba
On 9/14/07, Martin v. Löwis [EMAIL PROTECTED] wrote:
 The best way would be to not use import, but provide a separate
 function (e.g. calling it require).


yepp, that's probably the cleanest and quickest solution. i needed
to see all the  alternatives to realize this though. sorry.


-- 
An NCO and a Gentleman
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] classes and cell variables question

2006-12-29 Thread tomer filiba
On 12/29/06, Jeremy Hylton [EMAIL PROTECTED] wrote:
 def spam():
   x = 5
   class eggs(object):
 x = 6
 def spam(self):
   return x
   return eggs

 spam()().spam() should return 5.


the question that arises is -- is this what we wanted?
if i had to read such code, where i can't (easily) tell where x
is bound to, i wouldn't be content, to say the least.


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


Re: [Python-Dev] Non-blocking (asynchronous) timer without thread?

2006-12-23 Thread tomer filiba
 The main goal is to prevent threads overhead and problems with race
 conditions and deadlocks.

check out stackless python -- http://www.stackless.com/


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


[Python-Dev] classes and cell variables question

2006-12-19 Thread tomer filiba
to my understanding of the object model, the code of snippet 1
and snippet 2 should be equivalent. a class is just a special function
that returns its locals automatically and passes them to the metaclass
constructor:

--- snippet 1 ---
class foo(object):
x = 5
def f(self):
print f, x

--- snippet 2 ---
def bar():
x = 5
def g(self):
print g, x
return locals()
barcls = type(barcls, (object,), bar())

but there's one big difference. classes don't create cell variables
to hold bound external variables. the bar version works, because
x is a bound cell variable, but the foo version fails, as it attempts
to access x as a global.

. barcls().g()
g 5

. foo().f()
f
Traceback (most recent call last):
  File stdin, line 1, in module
  File stdin, line 4, in f
NameError: global name 'x' is not defined

for reference, i attached the code of all four functions below.

my question is, how come classes don't create cell variables, like
normal functions? was this done on purpose? does it have to
do with inheritance? if so, what's wrong with my bar version?


[1]
# code of class foo

#  2   0 LOAD_NAME0 (__name__)
#  3 STORE_NAME   1 (__module__)
#  3   6 LOAD_CONST   0 (5)
#  9 STORE_NAME   2 (x)
#
#  4  12 LOAD_CONST   1 (code object f at
009E5608, file stdin, line 4)
# 15 MAKE_FUNCTION0
# 18 STORE_NAME   3 (f)
# 21 LOAD_LOCALS
# 22 RETURN_VALUE

[2]
# code of foo.f:

#  5   0 LOAD_CONST   1 ('f')
#  3 PRINT_ITEM
#  4 LOAD_GLOBAL  0 (x)
#  7 PRINT_ITEM
#  8 PRINT_NEWLINE
#  9 LOAD_CONST   0 (None)
# 12 RETURN_VALUE

[3]
# code of bar:

#  2   0 LOAD_CONST   1 (5)
#  3 STORE_DEREF  0 (x)
#
#  3   6 LOAD_CLOSURE 0 (x)
#  9 BUILD_TUPLE  1
# 12 LOAD_CONST   2 (code object g at
009F6698, file stdin, line 3)
# 15 MAKE_CLOSURE 0
# 18 STORE_FAST   0 (g)
#
#  5  21 LOAD_GLOBAL  0 (locals)
# 24 CALL_FUNCTION0
# 27 RETURN_VALUE

[4]
# code of bar.g:

#  4   0 LOAD_CONST   1 ('g')
#  3 PRINT_ITEM
#  4 LOAD_DEREF   0 (x)
#  7 PRINT_ITEM
#  8 PRINT_NEWLINE
#  9 LOAD_CONST   0 (None)
# 12 RETURN_VALUE
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] classes and cell variables question

2006-12-19 Thread tomer filiba
 If you don't follow this reasoning, please write a counter-proposal
 so that people have something to shoot down.

?

i just wanted to be sure it was done on purpose, and what were the
reasons for that.



-tomer

On 12/20/06, Martin v. Löwis [EMAIL PROTECTED] wrote:
 tomer filiba schrieb:
  my question is, how come classes don't create cell variables, like
  normal functions?

 Not sure what you mean by how come? Why is the implementation
 reacting as it is? Because the body of class is compiled as
 a global code fragment, not as a nested one.
 Or why is the implementation the way it is? For several reasons,
 one being that classes predate nested functions.

  was this done on purpose?

 Yes. Attributes defined inside a class are assumed to be accessed
 through attribute access *only*. So you write

   self.foo()

 to invoke a method, instead of invoking

   foo()

 Python treats methods and data attributes uniformly, so the
 same applies to data variables.

  does it have to
  do with inheritance? if so, what's wrong with my bar version?

 It also has to do with inheritance. If you do self.foo, it looks
 1. in the object itself
 2. in the class of the object
 3. in the bases of the class of the object (recursively)

 It would be counter-intuitive if some things (i.e. things defined
 in the class itself) could be accessed directly, whereas other things
 (ie. attributes of the object itself, and things in the base classes)
 would need to be accessed through qualification. It would also be
 counter-intuitive if you find methods in an unqualified manner,
 but then can't call them because you didn't give a self argument.

 If you don't follow this reasoning, please write a counter-proposal
 so that people have something to shoot down.

 Regards,
 Martin

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


[Python-Dev] infinities

2006-11-26 Thread tomer filiba
i found several places in my code where i use positive infinity
(posinf) for various things, i.e.,

def readline(self, limit = -1):
if limit  0:
limit = 1e1 # posinf
chars = []
while limit  0:
ch = self.read(1)
chars.append(ch)
if not ch or ch == \n:
break
limit -= 1
return .join(chars)

i like the concept, but i hate the 1e1 stuff... why not add
posint, neginf, and nan to the float type? i find it much more readable as:

if limit  0:
limit = float.posinf

posinf, neginf and nan are singletons, so there's no problem with
adding as members to the type.


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


Re: [Python-Dev] infinities

2006-11-26 Thread tomer filiba
 sys.maxint makes more sense there.
no, it requires *infinity* to accomplish x - y == x; y != 0, for example:

while limit  0:
limit -= len(chunk)

with limit = posinf, the above code should be equivalent to while True.

 There is already a PEP 754 for float constants
okay, that would suffice. but why isn't it part of stdlib already?
the pep is three years old... it should either be rejected or accepted.
meanwhile, there are lots of missing API functions in the floating-point
implementation...

besides, all the suggested APIs should be part of the float type, not
a separate module. here's what i want:

 f = 5.0
 f.is_infinity()
False
 float.PosInf
1.#INF


-tomer

On 11/26/06, Bob Ippolito [EMAIL PROTECTED] wrote:
 On 11/26/06, tomer filiba [EMAIL PROTECTED] wrote:
  i found several places in my code where i use positive infinity
  (posinf) for various things, i.e.,
 
  def readline(self, limit = -1):
  if limit  0:
  limit = 1e1 # posinf
  chars = []
  while limit  0:
  ch = self.read(1)
  chars.append(ch)
  if not ch or ch == \n:
  break
  limit -= 1
  return .join(chars)
 
  i like the concept, but i hate the 1e1 stuff... why not add
  posint, neginf, and nan to the float type? i find it much more readable as:
 
  if limit  0:
  limit = float.posinf
 
  posinf, neginf and nan are singletons, so there's no problem with
  adding as members to the type.

 sys.maxint makes more sense there. Or you could change it to while
 limit != 0 and set it to -1 (though I probably wouldn't actually do
 that)...

 There is already a PEP 754 for float constants, which is implemented
 in the fpconst module (see CheeseShop). It's not (yet) part of the
 stdlib though.

 -bob

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


Re: [Python-Dev] infinities

2006-11-26 Thread tomer filiba
 Um, you do realize that you're not going to be able to fit sys.maxint
 strings into a list, right?
i can multiply by four, thank you. of course i don't expect anyone to read
a string *that* long.

besides, this *particular example* isn't important, it was just meant to
show why someone might want to use it. why are people being so picky
about the details of an example code?

first of all, a while True loop is not limited by sys.maxint, so i see no
reason why i couldn't get the same result by subtracting from infinity.
that may seem blunt, but it's a good way have the same code handle
both cases (limited and unlimited reading).

all i was asking for was a better way to express and handle infinity
(and nan), instead of the poor-man's version of nan = 2e/3e.
float.posinf or float.isinf(5.0) seem the right way to me.

for some reference, it seemed the right way to other people too:
http://msdn2.microsoft.com/en-gb/library/system.double_methods.aspx
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Float.html

the third-party fp module is nice, but it ought to be part of the float type,
or at least part of stdlib.

- - - - - -

if it were up to me, *literals* producing infinity would be a syntax error
(of course i would allow computations to result in infinity).

for the reason why, consider this:
 1e1 == 2e2
True


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


Re: [Python-Dev] __dir__, part 2

2006-11-07 Thread tomer filiba
okay, everything's fixed.
i updated the patch and added a small test to:
Lib/test/test_builtins.py::test_dir


-tomer

On 11/7/06, Nick Coghlan [EMAIL PROTECTED] wrote:
 tomer filiba wrote:
  cool. first time i build the entire interpreter, 'twas fun :)
  currently i retained support for __members__ and __methods__,
  so it doesn't break anything and is compatible with 2.6.
 
  i really hope it will be included in 2.6 as today i'm using ugly hacks
  in RPyC to make remote objects appear like local ones.
  having __dir__ solves all of my problems.
 
  besides, it makes a lot of sense of define __dir__ for classes that
  define __getattr__. i don't think it should be pushed back to py3k.
 
  here's the patch:
  http://sourceforge.net/tracker/index.php?func=detailaid=1591665group_id=5470atid=305470

 As I noted on the tracker, PyObject_Dir is a public C API function, so it's
 behaviour needs to be preserved as well as the behaviour of calling dir() from
 Python code.

 So the final form of the patch will likely need to include stronger tests for
 that section of the API, as well as updating the documentation in various
 places (the dir and PyObject_Dir documentation, obviously, but also the list
 of magic methods in the language reference).

 +1 on targeting 2.6, too.

 Cheers,
 Nick.

 --
 Nick Coghlan   |   [EMAIL PROTECTED]   |   Brisbane, Australia
 ---
  http://www.boredomandlaziness.org

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


Re: [Python-Dev] __dir__, part 2

2006-11-07 Thread tomer filiba
 as well as updating the documentation in various
 places (the dir and PyObject_Dir documentation, obviously, but also the list
 of magic methods in the language reference).

oops, i meant everything except that

-tomer

On 11/7/06, tomer filiba [EMAIL PROTECTED] wrote:
 okay, everything's fixed.
 i updated the patch and added a small test to:
 Lib/test/test_builtins.py::test_dir


 -tomer

 On 11/7/06, Nick Coghlan [EMAIL PROTECTED] wrote:
  tomer filiba wrote:
   cool. first time i build the entire interpreter, 'twas fun :)
   currently i retained support for __members__ and __methods__,
   so it doesn't break anything and is compatible with 2.6.
  
   i really hope it will be included in 2.6 as today i'm using ugly hacks
   in RPyC to make remote objects appear like local ones.
   having __dir__ solves all of my problems.
  
   besides, it makes a lot of sense of define __dir__ for classes that
   define __getattr__. i don't think it should be pushed back to py3k.
  
   here's the patch:
   http://sourceforge.net/tracker/index.php?func=detailaid=1591665group_id=5470atid=305470
 
  As I noted on the tracker, PyObject_Dir is a public C API function, so it's
  behaviour needs to be preserved as well as the behaviour of calling dir() 
  from
  Python code.
 
  So the final form of the patch will likely need to include stronger tests 
  for
  that section of the API, as well as updating the documentation in various
  places (the dir and PyObject_Dir documentation, obviously, but also the list
  of magic methods in the language reference).
 
  +1 on targeting 2.6, too.
 
  Cheers,
  Nick.
 
  --
  Nick Coghlan   |   [EMAIL PROTECTED]   |   Brisbane, Australia
  ---
   http://www.boredomandlaziness.org
 

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


[Python-Dev] __dir__, part 2

2006-11-06 Thread tomer filiba
so, if you remember, i suggested adding __dir__ to objects, so as to make
dir() customizable, remove the deprecated __methods__ and __members__,
and make it symmetrical to other built-in functions.

you can see the original post here:
http://mail.python.org/pipermail/python-dev/2006-July/067095.html
which was generally accepted by the forum:
http://mail.python.org/pipermail/python-dev/2006-July/067139.html

so i went on, now that i have some spare time, to research the issue.
the current dir() works as follows:
(*) builtin_dir calls PyObject_Dir to do the trick
(*) if the object is NULL (dir with no argument), return the frame's locals
(*) if the object is a *module*, we're just using it's __dict__
(*) if the object is a *type*, we're using it's __dict__ and __bases__,
but not __class__ (so as not to show the metaclass)
(*) otherwise, it's a normal object, so we take it's __dict__, along with
__methods__, __members__, and dir(__class__)
(*) create a list of keys from the dict, sort, return

we'll have to change that if we were to introduce __dir__. my design is:
(*) builtin_dir, if called without an argument, returns the frame's locals
(*) otherwise, it calls PyObject_Dir(self), which would dispatch self.__dir__()
(*) if `self` doesn't have __dir__, default to object.__dir__(self)
(*) the default object.__dir__ implementation would do the same as
today: collect __dict__, __members__, __methods__, and dir(__class__).
by py3k, we'll remove looking into __methods__ and __members__.
(*) type objects and module objects would implement __dir__ to their
liking (as PyObject_Dir does today)
(*) builtin_dir would take care of sorting the list returned by PyObject_Dir

so first i'd want you people to react on my design, maybe you'd find
flaws whatever. also, should this become a PEP?

and last, how do i add a new method slot? does it mean i need to
change all type-object definitions throughout the codebase?
do i add it to some protocol? or directly to the object protocol?


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


Re: [Python-Dev] __dir__, part 2

2006-11-06 Thread tomer filiba
cool. first time i build the entire interpreter, 'twas fun :)
currently i retained support for __members__ and __methods__,
so it doesn't break anything and is compatible with 2.6.

i really hope it will be included in 2.6 as today i'm using ugly hacks
in RPyC to make remote objects appear like local ones.
having __dir__ solves all of my problems.

besides, it makes a lot of sense of define __dir__ for classes that
define __getattr__. i don't think it should be pushed back to py3k.

here's the patch:
http://sourceforge.net/tracker/index.php?func=detailaid=1591665group_id=5470atid=305470

here's a demo:
 class foo(object):
... def __dir__(self):
... return [kan, ga, roo]
...
 f = foo()
 f
__main__.foo object at 0x00A90C78
 dir()
['__builtins__', '__doc__', '__name__', 'f', 'foo']
 dir(f)
['ga', 'kan', 'roo']
 dir(foo)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__getattribute__
', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__
', '__repr__', '__setattr__', '__str__', '__weakref__']
 class bar(object):
... __members__ = [bow, wow]
...
 b=bar()
 dir(b)
['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash_
_', '__init__', '__members__', '__module__', '__new__', '__reduce__', '__reduce_
ex__', '__repr__', '__setattr__', '__str__', '__weakref__', 'bow', 'wow']


-tomer

On 11/6/06, Guido van Rossum [EMAIL PROTECTED] wrote:
 Sounds like a good plan, though I'm not sure if it's worth doing in
 2.6 -- I'd be happy with doing this just in 3k.

 I'm not sure what you mean by adding a method slot -- certainly it's
 possible to define a method __foo__ and call it directly without
 having a special tp_foo in the type object, and I recommend doing it
 that way since the tp_foo slots are just there to make things fast; in
 this case I don't see a need for dir() to be fast.

 --Guido

 On 11/6/06, tomer filiba [EMAIL PROTECTED] wrote:
  so, if you remember, i suggested adding __dir__ to objects, so as to make
  dir() customizable, remove the deprecated __methods__ and __members__,
  and make it symmetrical to other built-in functions.
 
  you can see the original post here:
  http://mail.python.org/pipermail/python-dev/2006-July/067095.html
  which was generally accepted by the forum:
  http://mail.python.org/pipermail/python-dev/2006-July/067139.html
 
  so i went on, now that i have some spare time, to research the issue.
  the current dir() works as follows:
  (*) builtin_dir calls PyObject_Dir to do the trick
  (*) if the object is NULL (dir with no argument), return the frame's locals
  (*) if the object is a *module*, we're just using it's __dict__
  (*) if the object is a *type*, we're using it's __dict__ and __bases__,
  but not __class__ (so as not to show the metaclass)
  (*) otherwise, it's a normal object, so we take it's __dict__, along with
  __methods__, __members__, and dir(__class__)
  (*) create a list of keys from the dict, sort, return
 
  we'll have to change that if we were to introduce __dir__. my design is:
  (*) builtin_dir, if called without an argument, returns the frame's locals
  (*) otherwise, it calls PyObject_Dir(self), which would dispatch 
  self.__dir__()
  (*) if `self` doesn't have __dir__, default to object.__dir__(self)
  (*) the default object.__dir__ implementation would do the same as
  today: collect __dict__, __members__, __methods__, and dir(__class__).
  by py3k, we'll remove looking into __methods__ and __members__.
  (*) type objects and module objects would implement __dir__ to their
  liking (as PyObject_Dir does today)
  (*) builtin_dir would take care of sorting the list returned by PyObject_Dir
 
  so first i'd want you people to react on my design, maybe you'd find
  flaws whatever. also, should this become a PEP?
 
  and last, how do i add a new method slot? does it mean i need to
  change all type-object definitions throughout the codebase?
  do i add it to some protocol? or directly to the object protocol?
 
 
  -tomer
  ___
  Python-Dev mailing list
  Python-Dev@python.org
  http://mail.python.org/mailman/listinfo/python-dev
  Unsubscribe: 
  http://mail.python.org/mailman/options/python-dev/guido%40python.org
 


 --
 --Guido van Rossum (home page: http://www.python.org/~guido/)

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


Re: [Python-Dev] weakref enhancements

2006-09-29 Thread tomer filiba
this may still be premature, but i see people misunderstood the purpose.

weakattrs are not likely to be used externally, out of the scope of
the object.
they are just meant to provide an easy to use means for not holding cyclic
references between parents and children.

many graph-like structures, i.e., rpyc's node and proxies, are interconnected
in both ways, and weakattrs help to solve that: i don't want a proxy of a node
to keep the node alive.

weakmethods are used very similarly. nodes have a method called
getmodule, that performs remote importing of modules. i expose these
modules as a namespace object, so you could do:
 mynode.modules.sys
or
 mynode.modules.xml.dom.minidom.parseString
instead of
 mynode.getmodule(xml.dom.minidom).parseString

here's a sketch:

def ModuleNamespace:
def __init__(self, importerfunc):
self.importerfunc = importerfunc

class Node:
def __init__(self, stream):

self.modules = ModuleNamespace(self.getmodule)

@ weakmethod
def getmodule(self, name):
 

i define this getmodule method as a *weakmethod*, so the mere existence
of the ModuleNamespace instance will not keep the node alive. when the
node loses all external references, the ModuleNamespace should just
commit suicide, and allow the node to be reclaimed.

yes, you can do all of these with today's weakref, but it takes quite
a lot of hassle to manually set up weakproxies every time.


-tomer

On 9/29/06, Raymond Hettinger [EMAIL PROTECTED] wrote:
 [Alex Martelli]

 I've had use cases for weakrefs to boundmethods (and there IS a
 Cookbook recipe for them),
 
 Weakmethods make some sense (though they raise the question of why bound
 methods are being kept when the underlying object is no longer in use --
 possibly as unintended side-effect of aggressive optimization).

 I'm more concerned about weakattr which hides the weak referencing from
 client code when it is usually the client that needs to know about the
 refcounts:

n = SomeClass(x)
obj.a = n
del n  # hmm, what happens now?

 If obj.a is a weakattr, then n get vaporized; otherwise, it lives.

 It is clearer and less error-prone to keep the responsibility with the
 caller:

n = SomeClass(x)
obj.a = weakref.proxy(n)
del n # now, it is clear what happens

 The wiki-space example shows objects that directly assign a copy of self
 to an attribute of self. Even in that simplified, self-referential
 example, it is clear that correct functioning (when __del__ gets called)
 depends knowing whether or not assignments are creating references.
 Accordingly, the code would be better-off if the weak-referencing
 assignment was made explicit rather than hiding the weak-referencing
 wrapper in a descriptor.



 Raymond

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


[Python-Dev] weakref enhancements

2006-09-28 Thread tomer filiba
i'd like to suggest adding weak attributes and weak methods to the std weakrefmodule. weakattrs are weakly-referenced attributes. when the value they reference is no longer strongly-referenced by something else, the weakattrs nullify themselves.
weakmethod is a method decorator, like classmethod et al, that returns weaklybound methods. weakmethod's im_self is a weakref.proxy to `self`, which meansthe mere method will not keep the entire instance alive. instead, you'll get a 
ReferenceError.i think these two features are quite useful, and being part of the stdlib, would provide programmers with easy-to-use solutions to object-aliveness issues.more info, examples, and suggested implementation:
* http://sebulba.wikispaces.com/recipe+weakattr* http://sebulba.wikispaces.com/recipe+weakmethod
-tomer
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] weakref enhancements

2006-09-28 Thread tomer filiba
 I'm sceptical that these would find use in practice. [..] Also, I question the utility of maintaining a weakref to a method or attribute instead of holding one for the object or class. As long as
 the enclosing object or class lives, so too will their methods and attributes. So what is the point of a tighter weakref granualarity?i didn't just came up with them out of boredom, i have had specific 
use cases for these, mainly in rpyc3000... but since the rpyc300 code base is still far from completion, i don't want to give examples at this early stage.however, these two are theoretically useful, so i refactored them out
of my code into recipes.-tomerOn 9/28/06, Raymond Hettinger [EMAIL PROTECTED] wrote:
 Also, I question the utility of maintaining a weakref to a method or attribute instead of holding one for the object or class.Strike that paragraph -- the proposed weakattrs have references away from the
object, not to the object.Raymond
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] dict containment annoyance

2006-08-12 Thread tomer filiba
 a={1:2, 3:4} [] in aTraceback (most recent call last): File stdin, line 1, in ?TypeError: list objects are unhashableimo, the _expression_ should just evaluate to False instead of raising an exception.
it's a question of semantics -- i asked whether the object (a list, in this case)is contained in the dict. i didn't ask whether it's hashable or not. if the object isunhashable, then surely it's not contained in the dict, therefore the answer is
False, rather than an exception.dict.__contains__ should just swallow these exceptions, and return False.-tomer
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] PyThreadState_SetAsyncExc bug?

2006-08-11 Thread tomer filiba
while working on a library for raising exceptions in the context
of another thread, i've come across a bug in PyThreadState_SetAsyncExc.
if i raise an instance, sys.exc_info() confuses the exception value for
the exception type, and the exception value is set None. if i raise the
type itself, the interpreter creates an instance internally, but then i can't
pass arguments to the exception.

code:
=
import threading
import ctypes


def _async_raise(tid, excobj):
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid,
ctypes.py_object(excobj))
if res == 0:
raise ValueError(nonexistent thread id)
elif res  1:
# if it returns a number greater than one, you're in trouble,
# and you should call it again with exc=NULL to revert the effect
ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
raise SystemError(PyThreadState_SetAsyncExc failed)

class Thread(threading.Thread):
def raise_exc(self, excobj):
assert self.isAlive(), thread must be started
for tid, tobj in threading._active.items():
if tobj is self:
_async_raise(tid, excobj)
break

# the thread was alive when we entered the loop, but was not found
# in the dict, hence it must have been already terminated.
should we raise
# an exception here? silently ignore?

def terminate(self):
self.raise_exc(SystemExit())

if __name__ == __main__:
import time
import sys

i_am_active = False

def f():
global i_am_active
i_am_active = True
try:
try:
while True:
time.sleep(0.01)
except IOError, ex:
print IOError handler
except TypeError, ex:
print TypeError handler
print ex=, repr(ex)
typ, val, tb = sys.exc_info()
print typ=, repr(typ)
print val=, repr(val)
print tb=, tb
finally:
i_am_active = False

t1 = Thread(target = f)
t1.start()
time.sleep(1)
t1.raise_exc(TypeError(blah blah))
while i_am_active:
time.sleep(0.01)
print !! thread terminated

output:
=
TypeError handler
ex= None
typ= exceptions.TypeError instance at 0x00C15D28  # should be the type
val= None # should be the instance
tb= traceback object at 0x00C159E0
!! thread terminated

if i change:
t1.raise_exc(TypeError(blah blah))

to:
t1.raise_exc(TypeError)

i get:
=
TypeError handler
ex= exceptions.TypeError instance at 0x00C159B8
typ= class exceptions.TypeError at 0x00B945A0
val= exceptions.TypeError instance at 0x00C159B8
tb= traceback object at 0x00C15D00
!! thread terminated

but then of course i can't pass arguments to the exception



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


Re: [Python-Dev] PyThreadState_SetAsyncExc bug?

2006-08-11 Thread tomer filiba
so it should be fixed, or at least checked for conformness by the code.-tomerOn 8/11/06, Tim Peters 
[EMAIL PROTECTED] wrote:[tomer filiba] while working on a library for raising exceptions in the context
 of another thread, i've come across a bug in PyThreadState_SetAsyncExc. if i raise an instance, sys.exc_info() confuses the exception value for the exception type, and the exception value is set None. if i raise the
 type itself, the interpreter creates an instance internally, but then i can't pass arguments to the exception.That appears to be the way it was designed; i.e., AFAICT, it's workingas intended.This follows from the code in 
ceval.c that raises theexception:if (tstate-async_exc != NULL) {x = tstate-async_exc;tstate-async_exc = NULL;
PyErr_SetNone(x);Py_DECREF(x);why = WHY_EXCEPTION;goto on_error;
}PyErr_SetNone(x) there gives no possibility that setting an /instance/could work as you hope -- `x` has to be an exception type, andtstate-async_exc is simply the `exc` argument that was passed to
PyThreadState_SetAsyncExc().
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] patching pydoc?

2006-07-28 Thread tomer filiba
i have a problem with pydoc in rpyc. i wanted help(obj), where obj
is a NetProxy object, to work as if it were local.

i followed the code starting from site.help to pydoc.doc, which is the
ultimate function that generates and prints the text. i expected there
would be some function in the middle that prepares the text, and
another that writes it to the pager, but to my disappointment pydoc.doc
does both.

this means i can't transfer the document to my local machine (it's
printed directly to the remote console).

therefore, i would like to split this behavior into two parts:
* render_doc - a function that returns the document text
* doc - a function that calls render_doc and sends it to the pager

this way no existing code breaks (no existing function signatures
are changed) and i gain help on remote objects.
i hope people would be in favor, as it's not such a big change anyway.


is it possible to add to 2.5?

-tomer



this is the code of pydoc, starting at line 1457


def doc(thing, title='Python Library Documentation: %s', forceload=0):
Display text documentation, given an object or a path to an object.
try:
object, name = resolve(thing, forceload)
desc = describe(object)
module = inspect.getmodule(object)
if name and '.' in name:
desc += ' in ' + name[:name.rfind('.')]
elif module and module is not object:
desc += ' in module ' + module.__name__
if not (inspect.ismodule(object) or
inspect.isclass(object) or
inspect.isroutine(object) or
isinstance(object, property)):
# If the passed object is a piece of data or an instance,
# document its available methods instead of its value.
object = type(object)
desc += ' object'
pager(title % desc + '\n\n' + text.document(object, name))
except (ImportError, ErrorDuringImport), value:
print value


this is the suggested code


 def render_doc(thing, title='Python Library Documentation: %s', forceload=0):
generate the text
object, name = resolve(thing, forceload)
desc = describe(object)
module = inspect.getmodule(object)
if name and '.' in name:
desc += ' in ' + name[:name.rfind('.')]
elif module and module is not object:
desc += ' in module ' + module.__name__
if not (inspect.ismodule(object) or
inspect.isclass(object) or
inspect.isroutine(object) or
isinstance(object, property)):
# If the passed object is a piece of data or an instance,
# document its available methods instead of its value.
object = type(object)
desc += ' object'
return title % desc + '\n\n' + text.document(object, name)

def doc(*args, **kwargs):
Display text documentation, given an object or a path to an object.
try:
text = render_doc(*args, **kwargs)
pager(text)
except (ImportError, ErrorDuringImport), value:
print value

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


[Python-Dev] Fwd: patching pydoc?

2006-07-28 Thread tomer filiba
submitted patch:
https://sourceforge.net/tracker/?func=detailatid=305470aid=1530482group_id=5470

-tomer

-- Forwarded message --
From: tomer filiba [EMAIL PROTECTED]
Date: Jul 28, 2006 3:35 PM
Subject: patching pydoc?
To: python-dev@python.org


i have a problem with pydoc in rpyc. i wanted help(obj), where obj
is a NetProxy object, to work as if it were local.

i followed the code starting from site.help to pydoc.doc, which is the
ultimate function that generates and prints the text. i expected there
would be some function in the middle that prepares the text, and
another that writes it to the pager, but to my disappointment pydoc.doc
does both.

this means i can't transfer the document to my local machine (it's
printed directly to the remote console).

therefore, i would like to split this behavior into two parts:
* render_doc - a function that returns the document text
* doc - a function that calls render_doc and sends it to the pager

this way no existing code breaks (no existing function signatures
are changed) and i gain help on remote objects.
i hope people would be in favor, as it's not such a big change anyway.


is it possible to add to 2.5?

-tomer



this is the code of pydoc, starting at line 1457


def doc(thing, title='Python Library Documentation: %s', forceload=0):
Display text documentation, given an object or a path to an object.
try:
object, name = resolve(thing, forceload)
desc = describe(object)
module = inspect.getmodule(object)
if name and '.' in name:
desc += ' in ' + name[:name.rfind('.')]
elif module and module is not object:
desc += ' in module ' + module.__name__
if not (inspect.ismodule(object) or
inspect.isclass(object) or
inspect.isroutine(object) or
isinstance(object, property)):
# If the passed object is a piece of data or an instance,
# document its available methods instead of its value.
object = type(object)
desc += ' object'
pager(title % desc + '\n\n' + text.document(object, name))
except (ImportError, ErrorDuringImport), value:
print value


this is the suggested code


 def render_doc(thing, title='Python Library Documentation: %s', forceload=0):
generate the text
object, name = resolve(thing, forceload)
desc = describe(object)
module = inspect.getmodule(object)
if name and '.' in name:
desc += ' in ' + name[:name.rfind('.')]
elif module and module is not object:
desc += ' in module ' + module.__name__
if not (inspect.ismodule(object) or
inspect.isclass(object) or
inspect.isroutine(object) or
isinstance(object, property)):
# If the passed object is a piece of data or an instance,
# document its available methods instead of its value.
object = type(object)
desc += ' object'
return title % desc + '\n\n' + text.document(object, name)

def doc(*args, **kwargs):
Display text documentation, given an object or a path to an object.
try:
text = render_doc(*args, **kwargs)
pager(text)
except (ImportError, ErrorDuringImport), value:
print value

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


Re: [Python-Dev] patching pydoc?

2006-07-28 Thread tomer filiba
 Giving the amount of hair-tearing over uuid and __index__, this seems like
 an especially bad day to ask for a new-feature variance in a time of
 feature freeze ;-).

yeah, i guess so.

 * Would making pager() a parameter of doc() make sense?

not at all.

 * I presume you gain the new functionality by directly calling the
 factored-out render_doc and printing thru your own pager.  Does everyone?

i don't quite get the question, but yes, i plan to call render_doc
instead of doc, getting the doc text, and printing it on my own console
using a pager/whatever.

about the signature, okay, it can easily be fixed. i didn't think about that
too much. about the other point -- ImportError etc -- i tried to go dumb
as much as possible and not make any change that would break
something. pydoc is poorly written anyway, and as ron adam noted,
there is a need for at least a cleaned-up version of pydoc, or even a
redesigned package. and it ought to be a package. it's a module of
~2000 lines. that's way too much for a module.

i made the minimal changes needed to separate the generate text part
from the generate and display part. and i kept all the semantics in tact
(including who handles the errors)

and therefore, i don't expect it to break any tests (after restoring the
original doc signature, that is). i'd hate to wait for 2.6 for such a small
change.

today my solution is to replace pydoc.pager by a fake pager that hands
over the result. this is of course not thread safe, as multiple threads
calling help() would mix their outputs. not very likely, but i'd love to
see this code go away asap.


thanks for the comments,
-tomer

 From: Terry Reedy tjreedy at udel.edu
 Subject: Re: patching pydoc?
 Newsgroups: gmane.comp.python.devel
 Date: 2006-07-28 18:29:50 GMT (5 hours and 27 minutes ago)

 tomer filiba tomerfiliba at gmail.com wrote in message
 news:1d85506f0607280635q3a693682l230c7821dc6f408f at mail.gmail.com...
 ...
  therefore, i would like to split this behavior into two parts:
  * render_doc - a function that returns the document text
  * doc - a function that calls render_doc and sends it to the pager
 
  this way no existing code breaks (no existing function signatures
  are changed) and i gain help on remote objects.
  i hope people would be in favor, as it's not such a big change anyway.
  is it possible to add to 2.5?

 Giving the amount of hair-tearing over uuid and __index__, this seems like
 an especially bad day to ask for a new-feature variance in a time of
 feature freeze ;-).

 Some quick questions:
 * I presume you gain the new functionality by directly calling the
 factored-out render_doc and printing thru your own pager.  Does everyone?
 * Would making pager() a parameter of doc() make sense?
 * Is pager() the only part of the original doc() that can generate
 ImportError, ErrorDuringImport?  If not, the try/except should be in
 render_doc also or instead.
 * Why generalize the doc() signature?  Bad calls will be traced as caught
 in render_doc instead of doc.  Couldn't that potentially break a bad_call
 test?

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


[Python-Dev] exception too expensive?

2006-07-08 Thread tomer filiba
i thought avoiding a second dict lookup should be faster, but it turned out to be completely wrong. it's only marginally faster, but if an exception occurs,it's x10 slower.## the code# import time
 b = dict((i, 7) for i in range(1000))
 def try_lookup(k):... try:... return b[k]... except KeyError:... return 17... def if_lookup(k):... if k in b:... return b[k]... return 17
... def test(f, k, count=10):... t=time.time()... while count:... count -=1... f(k)... return time.time()-t...## try_lookup with valid key
# test(try_lookup, 56, 100)0.608950958252 test(try_lookup, 56, 100)0.6086757507324 test(try_lookup, 56, 100)0.608950958252~0.61 sec
## if_lookup with valid key# test(if_lookup, 56, 100)0.6876376037598 test(if_lookup, 56, 100)0.6873623962402 test(if_lookup, 56, 100)
0.67200016975402832~0.68 sec## try_lookup with invalid key# test(try_lookup, 9456, 100)7.06236239624 test(try_lookup, 9456, 100)6.81236239624
 test(try_lookup, 9456, 100)6.8440001010894775~6.90 sec## if_lookup with invalid key# test(if_lookup, 9456, 100)0.625 test(if_lookup, 9456, 100)
0.6413242492676 test(if_lookup, 9456, 100)0.65599989891052246~0.64 sec==before someone says why don't you use dict.get, it's not applicable inmy code. i have a cache -- either object already exists in the cache, or i
create and store it in the cache -- so get() and setdefault() are not useful.so first of all, i'd recommend not using the try_lookup method; use the if_lookup instead... unless you can be sure the changes a KeyError
will be raised are marginal.second, isn't there anything that can be done to improve the performanceof exceptions? imo, exceptions should be cheap. i understand it has to do with creating the exception instance everytime, but can't something 
be done to improve that? for example, hold a cache exception instances and just memcpy them when needed (just a wild idea)?-tomer
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] weakattr

2006-07-03 Thread tomer filiba
 I like the added functionality offered with weakattrs as defined.  I'm
 not terribly in love with the syntax of their creation, and I'm curious
 as to how it plays with __slots__
weakattrs are data descriptors, just like properties etc. they are part
of the class, not the instance, so there shouldn't be any trouble with
mixing those with __slots__

moreover, adding those to stdlib is very staight-forward. we don't even
need to introduce a new module. if people show interest, i'll write a
bit of a longer doc string and add some unit tests (although there's
not much to test :) )

 Toss it out in python-list, I think some people over there would be able
 to offer more feedback.
will do... although i doubt they will offer any



-tomer

On 7/2/06, Josiah Carlson [EMAIL PROTECTED] wrote:

 tomer filiba [EMAIL PROTECTED] wrote:
  weakattr (weak attributes) are attributes that are weakly referenced
  by their containing object. they are very useful for cyclic references --
  an object that holds a reference to itself.

 I like the added functionality offered with weakattrs as defined.  I'm
 not terribly in love with the syntax of their creation, and I'm curious
 as to how it plays with __slots__ (not quite having the time to look at
 its implementation right now), but it is quite explicit, so I can get
 past that. It would allow us to say, stop using __del__, use weakattrs,
 but I'm not sure how well that would work, generally.

 Toss it out in python-list, I think some people over there would be able
 to offer more feedback.

  - Josiah


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


[Python-Dev] weakattr

2006-07-01 Thread tomer filiba
weakattr (weak attributes) are attributes that are weakly referencedby their containing object. they are very useful for cyclic references --an object that holds a reference to itself. when a cyclic reference is found by the GC, the memory may be 
freed, but __del__ is not called, because it's impossible to tell which __del__ to call first. this is an awkward asymmetry with no clean solution: most such objects provide a close or dispose method
that must be called explicitly.weakattrs to solve this problem, by providing a magical attributethat disappears when the attribute is no longer strongly-referenced. you can find the code, as well as some examples, on this link
http://sebulba.wikispaces.com/recipe+weakattr
since the stdlib already comes with weakref.py, which provideshigher level concepts over the builtin _weakref module, i'd like tomake weakattr a part of it. it's only ~20 lines of code, and imho saves the trouble of explicitly 
releasing the resource of un__del__able objects.i think it's useful. here's a snippet: from weakref import weakattr  class blah(object):...  yada = weakref()
... o1 = blah() o2 = blah() o1.yada = o2 o2.yada = o1o1.yada is a *weakref* to o2, so that when o2 is no longer strongly-referenced... del o2
o1.yada magically disappears as well.  o1.yada... AttributeError(...)since the programmer explicitly defined yada as a weakatt, he/she knows it might disappear. it might look awkward at first, but that's 
exactly the *desired* behavior (otherwise we'd just use the regular strong attributes).another thing to note is that weakattrs are likely to be gone onlywhen the object's __del__ is already invoked, so the only code that
needs to take such precautions is __del__ (which already has some constraints)for example: class blah(object):... me = weakattr().. def __init__(self):... 
self.me = self.. def something(self):... # we can rest assure me exists at this stage... print self.me.. def __del__(self):... # by the time __del__ is called, me is removed
... print me exists?, hasattr(self, me)... b = blah() b.me__main__.blah object at 0x00C0EC10 b.something()__main__.blah object at 0x00C0EC10
 del b import gc gc.collect()me exists? False0-tomer
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] suggestion: except in list comprehension

2006-04-26 Thread tomer filiba
a friend of mine suggested this, and i thought i should share it with the mailing list.many times when you would want to use list/generator comprehensions, you have tofall back to the old for/append way, because of exceptions. so it may be a good idea
to allow an exception handling mechanism in these language constructs.since list comprehensions are expressions, an exceptions thrown inside one meansthe entire list is discarded. you may want to provide some, at least fundamental,
error handling, like if this item raises an exception, just ignore it, or terminate theloop in that case and return whatever you got so far.the syntax is quite simple:[ expr for expr in expr [if cond] [except exception-class-or-tuple: action] ]
where action is be one of continue or break:* continue would mean ignore this item* break would mean return what you got so farfor example:
a = [i, fart, in, your, general, 5, direction, you, silly, english, kniggits]give me every word that starts with y, ignoring all errors
b = [x for x in a if x.startswith(y) except: continue]# returns [your, you]

or only AttributeError to be more speciifcb = [x for x in a if x.startswith(y) except AttributeError: continue]# returns [your, you]and with break
b = [x for x in a if x.startswith(y) except AttributeError: continue]
# returns only [your] -- we didn't get past the 5
in order to do something like this today, you have to resort to the old way,b = []for x in a: try: if x.startswith(y):b.append(x) except ...: pass
which really breaks the idea behind list comprehension. so it's true that this example i provided can be done with a more complex if condition (first doing hasattr), but it's not always possible, and how would you do it if the error 
occurs at the first part of the _expression_? y = [4, 3, 2, 1, 0, -1, -2, -3] [1.0 / x for x in y except ZeroDivisionError: break][0.25, 0.333, 0.5, 1.0] [1.0 / x for x in y except ZeroDivisionError: continue]
[0.25, 0.333, 0.5, 1.0, -1.0, -0.5, -0.333]again, in this example you can add if x != 0, but it's not always possible to tell whichelement will fail. for example:filelist = [a, b, c, \\/invalid file name:?*, e]
openfiles = [open(filename) for filename in filelist except IOError: continue]the example is hypothetical, but in this case you can't tell *prior to the exception*that the operation is invalid. the same goes for generator expressions, of course.
-tomer
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] suggestion: except in list comprehension

2006-04-26 Thread tomer filiba
first, i posted it two days ago, so it's funny it got posted only now... the moderators are sleeping on the job :)anyway. Note that of the continue cases you offer, all of them are merely simple
 if conditionyes, i said that explicitly, did you *read* my mail?but i also said it's not always possible. you *can't* always tell prior to doing somethingthat it's bound to fail. you may have os.path.isfile
, but not an arbitrary is_this_going_to_fail(x)and doing  [1.0 / x for x in y if z(x != 0)]is quite an awkward way to say break... if then_break(cond) instead of 
if cond then break- - - - -anyway, i guess my friend may have better show-cases, as he's the one who found theneed for it. i just thought i should bring this up here. if you think better show cases
would convince you, i can ask him. If you couldn't guess; -1, you can get equivalent behavior without complicating the generator _expression_/list comprension syntax.so how come list comprehensions aren't just a complication to the syntax?

you can always do them the old way,x = []for : x.append(...)but i since people find {shorter / more to-the-point / convenience} reason enough to have introduced the list-comprehension syntax in the first place, there's also a case 
for adding exception handling to it.if the above snippet deserves a unique syntax, why not extend it to cover this as well?x = []
for : try:   x.append(...) except: ...and it's such a big syntactic change.don't worry, i'm not going to argue it past this.-tomer
On 4/26/06, Josiah Carlson [EMAIL PROTECTED] wrote:
tomer filiba [EMAIL PROTECTED] wrote: [ expr for expr in expr [if cond] [except exception-class-or-tuple: action] ]
Note that of the continue cases you offer, all of them are merely simpleif condition (though the file example could use a better test thanos.path.isfile).[x for x in a if x.startswith(y) except AttributeError: continue]
[x for x in a if hasattr(x, 'startswith') and x.startswith(y)][1.0 / x for x in y except ZeroDivisionError: continue][1.0 / x for x in y if x != 0][open(filename) for filename in filelist except IOError: continue]
[open(filename) for filename in filelist if os.path.isfile(filename)]The break case can be implemented with particular kind of instanceobject, though doesn't have the short-circuiting behavior...
class StopWhenFalse:def __init__(self):self.t = 1def __call__(self, t):if not t:self.t = 0return 0return self.tz = StopWhenFalse()
Assuming you create a new instance z of StopWhenFalse before doing thelist comprehensions...[x for x in a if z(hasattr(x, 'startswith') and x.startswith(y))][1.0 / x for x in y if z(x != 0)]
[open(filename) for filename in filelist if z(os.path.isfile(filename))]If you couldn't guess; -1, you can get equivalent behavior withoutcomplicating the generator _expression_/list comprension syntax.
 - Josiah
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] proposal: evaluated string

2006-04-20 Thread tomer filiba
many times, templating a string is a tidious task. using the % operator, either with tuples or dicts,is difficult to maintain, when the number of templated arguments is large. and string.Template,although more easy to read, is less intutive and cumbersome:
import stringt = string.Template(hello $name)print t.substitute({name : john})as you can see, it is is redundant, as you must repeat the dict keys in two places, and imagine 
maintaining such a template with 20 parameters! if you change the one argument's name in the template, you must go and fix all locations that use that template. not nice at all.i'm suggesting something like boo's string interpolation: 
http://boo.codehaus.org/String+Interpolationbut i chose to call it evaluated string.like raw strings (r), which are baiscally a syntactic sugar, evaluated strings will be marked by 'e',
for instance, e, which may be combined with the 'r' or 'u', that exist today.the evaluated string will be evaluated based on the current scope (locals and globals), just likenormal expressions. the difference is, the results of the expressions will be str()ed into the 
evaluated string directly. these expressions will be embedded into the string surrounded byspecial delimiters, and an unclosed delimited or a syntax error will be reported at just like \x??raises ValueError: invalid \x escape.
i'm not sure which delimiters to use, but i think only { } is sufficient (no need for ${ } like in boo)some examples:===name = johnprint ehello {name}
a = 3b = 7print ethe function is y = {a}x + {b}for x in range(10): print ey({x}) = {a*x+b}import time, sysprint ethe time is {time.asctime()} and you are running on {
sys.platform}===in order to implement it, i suggest a new type, estr. doing a = ehellowill be equivalent to a = estr(hello, locals(), globals()), just like
uhellois equivalent tounicode(hello) (if we ignore \u escaping for a moment)and just like unicode literals introduce the \u escape, estr literals would introduce \{ and \} 
to escape delimiters.the estr object will be evaluated with the given locals() and globals() only at __repr__ or __str__,which means you can work with it like a normal string:a = ehello {name}  
b = ehow nice to meet you at this lovely day of {time.localtime().tm_year}c = a + bc is just the concatenation of the two strings, and it will will be evaluated as a whole when youstr()/repr() it. of course the internal representation of the object shouldnt not as a string,
rather a sequence of static (non evaluated) and dynamic (need evaluation) parts, i.e.:[hello, name, how nice to meet you at this lovely day of, time.localtime().tm_year],
so evaluating the string will be fast (just calling eval() on the relevant parts)also, estr objects will not support getitem/slicing/startswith, as it's not clear what the indexes are...
you'd have to first evaluate it and then work with the string:str(ehello)[2:]estr will have a counterpart type called eunicode. some rules:estr + str = estrestr + estr = estrestr + unicode = eunicode
estr + eunicode = eunicodeeunicode + eunicode = eunicodethere are no backwards compatibility issues, as e is an invalid syntax today, and as for clarity, i'm sure editors like emacs and the like can be configured to highlight the strings enclosed by {} 
like normal expressions.i know it may cause the perl-syndrome, where all the code of the program is pushed into strings,but templating/string interpolation is really a fundamental requirement of scripting languages,
and the perl syndrome can be prevented with two precautions:* compile the code with eval flag instead of exec. this would prevent abominations likee{import time\ndef f(a):\n\tprint 'blah'}
* do not allow the % operator to work on estr's, to avoid awful things likeehow are %s {%s} % (you, name)one templating mechanism at a time, please :)perhaps there are other restrictions to impose, but i couldnt think of any at the moment. 
here's a proposed implementation:class estr(object): # can't derive from basestring! def __init__(self, raw, locals, globals): self.elements = self._parse(raw) self.locals = locals
 self.globals = globals  def _parse(self, raw): i = 0 last_index = 0 nesting = 0 elements = [] while i  len(raw): if raw[i] == {:
 if nesting == 0: elements.append((False, raw[last_index : i])) last_index = i + 1 nesting += 1 elif raw[i] == }:
 nesting -= 1 if nesting == 0: elements.append((True, raw[last_index : i])) last_index = i + 1 if nesting  0: raise ValueError(too many '}' (at index %d) % (i,))
 i += 1 if nesting  0: raise ValueError(missing '}' before end) if last_index  i: elements.append((False, raw[last_index : i])) return elements
  def __add__(self, obj): if type(obj) == estr: elements = self.elements + obj.elements else: elements = self.elements + [(False, obj)] # the new object inherits the current one's namespace (?)
 newobj = estr(, self.locals, self.globals) newobj.elements = elements return newobj  def __mul__(self, count): newobj = 

Re: [Python-Dev] proposal: evaluated string

2006-04-20 Thread tomer filiba
just like r does the escaping for you.but estr types must be implemented so the evaluate with the current scope (locals and globals),not the score they were defined it, so unless you want to do nasty tricks with sys._getframe,
which doesn't work on all implementations of python, you'll need it as a builtin-tomerOn 4/20/06, Josiah Carlson 
[EMAIL PROTECTED] wrote:tomer filiba 
[EMAIL PROTECTED] wrote: the evaluated string will be evaluated based on the current scope (locals and globals), just like normal expressions. the difference is, the results of the expressions will
 be str()ed into the evaluated string directly. these expressions will be embedded into the string surrounded by-1You are basically suggesting that e... be a replacement for
...%locals() .That doesn't seem to me to be sufficiently compelling(yes, I do use string interpolation). - Josiah
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] proposal: evaluated string

2006-04-20 Thread tomer filiba
We already have a slew of templating utilities (see Cheetah for example).first of all -- i know there's a bunch of templating engines, but i think it should be a
built-in feature of the language. like boo does. and estr is stronger than simple $name substitution, like Template does.
Be sure to stay aware of the security risks if the fill-in values are user specified.that's one major benefit of having it as a builtin type -- you dont have security risks,as the _expression_ itself is embedded in your code, not something you get from the
outside:name = raw_input(what's you name?)print ehello {name}does not get the *_expression_* from the user, only the *values*, so unless the usercauses a buffer overflow with a huge string, he can't run code. the estr object is part 
of *your* code, which you trust. If you need this, then consider using a third-party templating module.
that 50-liner estr class i presented does just that.Using the key twice is basic to templating (once of specify where to
make the substitution and once to specify its value). This is nodifferent from using variable names in regular code:  a=1; ... ; b =a+2 # variable-a is used twice.but when it's defined once as an argument to a function, once in the template,
and once in the dict, that's three times, where it can be only two.def f(name): print ehello {name}
Also, the example is misleading because real-apps are substitutevariables, not constants. IOW, the above code fragment is sematicallyequivalent to: print hello john.what do you mean by that?
3) it is lessflexible than the class constructor which can be subclassed and
extended as needed.do you often subclass str? it's a built-in type, part of the language, subclassing it doesntmake much sense. after all it's the language compiler that instanciates these types, 
i.e.,when you do hello, the compiler creates an instance of str() with that value, not youdirectly, and that's the case here.-tomerOn 4/20/06, 
Raymond Hettinger [EMAIL PROTECTED] wrote:
If you don't like the $name style of template markup and preferdelimiters instead, then check-out the recipe at:
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/3053The link should have been: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/305306

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


Re: [Python-Dev] adding Construct to the standard library?

2006-04-19 Thread tomer filiba
Giovanni Bajo: Both ctypes and construct provide a way to describe a binary-packed structure in Python terms: and this is an overload of functionalityso does struct, so why not just use struct? there's a receipe at the python 
cookbook that adds naming ability to fields, i.e.6s.destincation 6s.source H.typesomething like that, so when you parse you get named attributes instead ofa tuple. so why did ctypes wrote another mechanism? because you can't extend 
it and you can't nest it. but ctypes, just as well, provides the mechanisms for its requirements -- defining C structs, not arbitrarily complex structures. so of courseit doesnt, and shouldnt, support variable-length fields or data pointers, which are 
common in file formats, protocols, and other complex data structures -- whatyou can't do with a C struct you don't need to do with ctypes.now i'll save me a mail and put this also here:
Greg Ewing: It does seem rather silly to have about 3 or 4 different incompatible ways to do almost exactly the same thing (struct, ctypes, NumPy and now Construct).* struct is designed for packing and unpacking, but is very limited
* ctypes is not oriented at packing/unpacking, it only provided amechanism to handle its requirements, which are domain specificand not general purpose.* i never checked how NumPy packs arrays, etc., but it's also 
domain-specific, as it's a math library, not a generic packer/unpacker.and trust me those are not the only ones. the reason people have to *reinvent the wheel* every time is the lack of a *generic* parsing/building
library. (i prefer the term parsing over unpacking. check my blog for moredetails)yes, putting bytes together isn't too complicated, and because peopledon't have a built-in mechanism for that, they tend to just oh, well,
it can't be too complicated, i'll just write one for me, and this yields manyflavors of packers/unpackers, all incompatible.Construct is the first library, that i'm aware of, that is dedicated to
parsing/building, instead of doing it as a side-kick domain-specificmechanism.Construct is a *superset* of all those packers and unpackers, andhad it been part of stdlib, people would have used it instead.
of course it's only been released a month ago, and couldnt have been already included in the stdlib, i still think it has a room there. existing projects can be ported without too much effort, and new ones could 
benefit from it as well.-tomerOn 4/19/06, Giovanni Bajo [EMAIL PROTECTED] wrote:
tomer filiba [EMAIL PROTECTED] wrote:
 the point is -- ctypes can define C types. not the TCP/IP stack. Construct can do both. it's a superset of ctype's typing mechanism. but of course both have the right to *coexist* -- ctypes is oriented at interop with dlls, and provides the mechanisms
 needed for that. Construst is about data structures of all sorts and kinds. ctypes is a very helpful library as a builtin, and so is Construct. the two don't compete on a spot in the stdlib.
I don't agree. Both ctypes and construct provide a way to describe abinary-packed structure in Python terms: and this is an overload offunctionality. When I first saw Construct, the thing that crossed my head was:
hey, yet another syntax to describe a binary-packed structure in Python.ctypes uses its description to interoperate with native libraries, whileConstruct uses its to interoperate with binary protocols. I didn't see a good
reason why you shouldn't extend ctypes so to provide features that it iscurrently missing. It looks like it could be easily extended to do so.Giovanni Bajo
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] bug with __dict__?

2006-04-19 Thread tomer filiba
overriding __getattr__ and __setattr__ has several negative side effects, for example:* inside__getattr__/__setattr__ you have to use self.__dict__[attr] instead of 
self.attr* it's easy to get stack overflow exceptions when you do something wrong
* you must remember to call the super's [get/set]attr or the MRO is broken* when deriving from a class that overrides one of the speical methods, you usuallyneed to override the special function of your class as well, to allow some local storage
for yourselfso i had an idea -- why not just replace __dict__? this does not affect the MRO. i wrote an AttrDict class, which is like dict, only it allows you to acces its keys as attributes. i later 
saw something like this on the python cookbook as well.
class AttrDict(dict): def __init__(self, *a, **k): dict.__init__(self, *a, **k) self.__dict__ = selfthis code basically causes __getattr/setattr__ to use __getitem/setitem__:

a =AttrDict()a[blah] = 5a.yadda = 6print a.blahprint a[yadda]which is exactly what i wanted. now, i thought, instead of overriding __getattr/setattr__, i'd just write a class that overrides __getitem/setitem__. for example:
# old wayclass A(object): def __getattr__(self, name): return 5a = A()print a.xyz # 5# new wayclass mydict(dict): def __getitem__(self, key): return 5

class A(object): def __init__(self): self.__dict__ = mydict()a = A()print a.xyz # should print 5but lo and behold, python does not call my overriden method. it just bypasses it and always
calls the original dict's method. i made several tests, trying to see if it calls __contains__,placed hooks on __getattribute__, but nothing from *my* overriden methods is ever called. this is probably because the C implementation calls PyDict_GetItem or whatever directly... 
i think it's a bug. i should be able to override the __getitem__ of my __dict__. it breaks the polymorphism of python-level objects! on the one hand, i'm allowed to change __dict__ to anyobject that derives from dict, but i'm not allowed to override it's methods! 
python must either disable assigning to __dict__, or be willing to call overriden methods, notsilently ignore mine.-tomer


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


Re: [Python-Dev] adding Construct to the standard library?

2006-04-18 Thread tomer filiba
Indeed, I wish I had known about this a year ago; it would have saved
me a lot of work. Of course it probably didn't exist a year ago... :(
well, yeah. many people need parsing-abilities, but they resort to ad-hoc parsers using struct/some ad-hoc implementation of their own. there clearly is a need for a generic, strong, and extensible parsing/building mechanism.
Well, declarative is less flexible. OTOH declarative is nice in the way it is more readable and allows more optimisations.
i don't think less flexible is the term. it's certainly different, but if you need something specific, you can always subclass a construct on your own. other than that, being declarative means easy to read/write/maintain/debug/upgrage (to a newer version of the library). 
 IMHO, at least in theory Construct could have small but fast C
extension to take care of the encoding and decoding, which is the
critical path. Everything else, like the declaration part, can be
python, as it is usually done once on application startup.
well, i expected the encodings package to have a str.encode(bin) and str.decode(bin)... for some reason there's no such codec. it's a pity.
This is a very nice library indeed. But the number one feature that I
need in something like this would be to use C. That's because of my
application specific requirements, where i have observed that
reapeatedly using struct.pack/unpack and reading bytes from a stream
represents a considerable CPU overhead, whereas the same thing in C
would be ultra fast.well, you must have the notion of a stream, i.e., go back and forth, be able to read/write bits/bytes at arbitrary locations, etc. i thought of moving the library to pyrex, and compiling it, but the number of critical parts is very small -- basically only the Repeater class could be improved by writing it in C. 
i mean, most of the time is consumed at creating objects in the objects tree, etc. for example, the Struct class simply iterates over the nested construsts and parses each of the in that sequence. doing a pythonic iteration of a C-level iteration over a pythonic object is practically the same. 
 If you agree to go down this path I might even be able to volunteer some of my time to help, but it's not my decision.
well, mainly i'm looking for ideas. just moving it to c wouldnt be too helpful. some ideas i have:* making the stream work with bytes instead of bits, so that memory consumption would decrease 8-fold... but then parsing unaligned fields (either by size of position) is gonna be a headache
* unifying the context tree with the parsing/building tree, to create less objects on the fly (but it has some issues)* using lambda functions for meta expressions, instead of eval(string) -- perhaps it's faster, but lambda is getting deprecated by python3k :(
apart from that, i'm rely on inheritance in many places. if some classes are written in C and some in python, i'm not sure how it could work (can a C class inherit a pythonic one? would it be easy to extend?). and, that means users would have to compile the C sources, while now all they have to do is extract a zip file. and then i'd have to write makefiles, and maintain those also... it's getting dirty. i like the painless unzip-and-use installation.
so if you have ideas, i'd be happy to hear those.thanks,-tomerOn 4/18/06, Gustavo Carneiro 
[EMAIL PROTECTED] wrote:
why include Construct?* the struct module is very nice, but very limited and non-pythonic as well
* pure python (no platform/security issues) IMHO this is a drawback. More on this below.

* lots of people need to parse and build binary data structures, it's not an esoteric library
* license: public domain* quite a large user base for such a short time (proves the need of the community) Indeed, I wish I had known about this a year ago; it would have saved me a lot of work. Of course it probably didn't exist a year ago... :(

* easy to use and extend (follows the componentization pattern)
* declarative: you don't need to write executable code for most cases
 Well, declarative is less flexible. OTOH declarative is nice in the way it is more readable and allows more optimisations.

why not:* the code is (very) young. stable and all, but less than a month on the loose. * new features may still be added / existing ones may be changed in a non-backwards-compatible manner
so why am i saying this now, instead of waiting a few months for it to maturet? 
well, i wanted to get feedback.
those of you who have seen/used the library, please tell me what you think:* is it suitable for a standard library?

* what more features would you want?* any changes you think are necessary? This is a very nice library indeed. But the number one feature that I need in something like this would be to use C. That's because of my application specific requirements, where i have observed that reapeatedly using 
struct.pack/unpack and reading bytes from a stream represents a considerable CPU overhead, whereas the same thing in C would be 

Re: [Python-Dev] adding Construct to the standard library?

2006-04-18 Thread tomer filiba
ctypes, as the name implies, is relevant to *C data structures* only.you cannot extend it and you cannot define complex things with it, at least noteasily.

* ctypes doesn't have a way (that I'm aware of) to specify theendianness of types like c_short - so my example, when run on Windows(intel architecture) gives type = 8, rather than type = 2048 (from thewiki). But the wiki example doesn't explicitly specify endianness, so
maybe that's a limitation in Construct as well?in ctypes, the endianness of numbers is determined by the platform, since
they are passed to a C (platform-dependent) function. you share your addressspace with the dll you load -- so both python and the dll live on the same platform.so except of writing data to files or sockets, you shouldn't care about the byte
ordering.
in Construct you have UBInt16 and ULInt16, for big and little ordering. and UInt16 is an alias to UBInt16 (because network ordering is more common in protocols)

* ctypes doesn't have an easy way to parse a string based on astructure definition - hence my str_to_ctype function. But that's atrivial helper function to write, so that's not a big issue.sorry, but if you mean people must use memmove in order to parse string,
you better slap yourself. this is a python mailing list, not a C one. we don't have a concept of addressof() or physically moving data. we use objects andreferences. no offense, but so that's not a big issue makes me think you 
don't belong to this mailing list.I'm not sure I understand the other wiki examples - but the ones I do,
look doable in ctypes.i gues you should also look at http://pyconstruct.wikispaces.com/demos
 to geta better understanding, but i only uploaded it a couple of hours ago. sorry for that. anyway, on the projects page i explain thoroughly why there is room for yet anotherparsing/building library.
but for the example you mentioned above, the ethernet header, struct is good enough:struct.pack(6s6sH, 123456, ABCDEF, 0x0800)
but --how would you parse a pascal-string (length byte followed by data of that length)using ctypes? how would you read a 61 bit, unaligned field? how would you convert \x00\x11P\x88kW to 00-11-50-88-6B-57, the way people would like to see MAC 
addresses? yeah, the MAC address is only a representation issue, but adapters can do much more powerful things. plus, people usually prefer seeing IP instead of 0x0800 in their parsed objects. how would you define mappings in ctypes? 
Personally, I'd rather see the ctypes facilities for structure packingand unpacking be better documented, and enhanced if necessary, rather
than having yet another way of doing the same thing added to thestdlib.the stdlib is too messy already. it must be revised anyway, since it's full of shitnobody uses. the point is -- ctypes can define C types. not the TCP/IP stack. Construct can do both.

it's a superset of ctype's typing mechanism. but of course both have the right to *coexist* -- 
ctypes is oriented at interop with dlls, and provides the mechanisms needed for that. 
Construst is about data structures of all sorts and kinds. ctypes is a very helpful library as a builtin, and so is Construct. the two don't competeon a spot in the stdlib.-tomer
On 4/18/06, Paul Moore [EMAIL PROTECTED]
 wrote:
On 4/17/06, tomer filiba [EMAIL PROTECTED] wrote: after several people (several  10) contacted me and said IMHO 'construct'
 is a good candidate for stdlib,
 i thought i should give it a try. of course i'm not saying it should be included right now, but in 6 months time, or such a timeframe (aiming at python 2.6? some 2.5.x release?)Now that ctypes is part of the standard library, that provides a
structured datatype facility. Here's an example demonstrating thefirst example from the Construct wiki: from ctypes import * def str_to_ctype(s, typ):...t = typ()

...memmove(addressof(t), s, sizeof(t))...return t... class ethernet_header(Structure):..._fields_ = [(destination, c_char * 6),...(source, c_char * 6),
...(type, c_short)]... s = ABCDEF123456\x08\x00 e = str_to_ctype(s, ethernet_header) e.source'123456' 
e.destination
'ABCDEF' e.type8I'm not sure I understand the other wiki examples - but the ones I do,look doable in ctypes.There are a couple of things to note:* ctypes doesn't have a way (that I'm aware of) to specify the
endianness of types like c_short - so my example, when run on Windows(intel architecture) gives type = 8, rather than type = 2048 (from thewiki). But the wiki example doesn't explicitly specify endianness, so

maybe that's a limitation in Construct as well?* ctypes doesn't have an easy way to parse a string based on astructure definition - hence my str_to_ctype function. But that's atrivial helper function to write, so that's not a big issue.
Personally, I'd rather see the ctypes facilities for structure packingand unpacking be better documented, and enhanced if necessary, ratherthan having yet another way of doing the same thing added to the

stdlib.Paul

[Python-Dev] a flattening operator?

2006-04-18 Thread tomer filiba
DISCLAIMERi'm not going to defend and fight for this idea too much. i only bringit up because it bothers me. i'm sure some people here would kill me for
even suggesting this, and i really don't want to be killed right now,so i bring it up as something you should think about. nothing more./DISCLAIMERNOTEPEP-225 has some weird ideas which may or may not be related to this, but i don't understand how this magical ~ operator can do everything from tuple flattening to list arithmetics, replacing map(), changing the order of operations, deep-copying, list comprehension, rich comparison, and whatever not. so i don't consider this a serious PEP. looks more like an april fool's joke to me, and it seems those japanese celebrate it on september for some reason.
/NOTE[reposted from comp.lang.python]as we all know, * (asterisk) can be used to inline or flatten a 
  tuple into an argument list, 
i.e.:  def f(a, b, c):...  x = (1,2,3)  f(*x)  so... mainly for symmetry's sake, why not make a flattening operator 
 that also works outside the context of function calls? for example:  a = (1,2,3)  b = (4,5)  c = (*a, *b) # == (1,2,3,4,5)  
yeah, a + b would also give you the same result, but it could be used   like format-strings, for templating tuples, i.e.  

c = (*a, 7, 8, *b)  i used to have a concrete use-case for this feature some time ago, but  i can't recall it now. sorry. still, the main argument is symmetry: 
 it's a syntactic sugar, but it can be useful sometimes, so why limit it  to function calls only?  allowing it to be a generic operator would make things like this 
 possible:  f(*args, 7) # an implied last argument, 7, is always passed to the  function  
today you have to do  f(*(args + (7,)))  which is quite ugly.  
and if you have to sequences, one being a list and the other being a   tuple, e.g.  x = [1,2]  y = (3,4)  
you can't just x+y them. in order to concat them you'd have to use  casting like   f(*(tuple(x) + y))  instead of  f(*x, *y) 
 isn't the latter more elegant?  just an idea. i'm sure people could come up with more creative 
 use-cases of a standard flattening operator. but even without the creative use cases -- isn't symmetry strong enough an argument? why are  function calls more important than regular expressions? 

 and the zen supports my point:   (*) Beautiful is better than ugly -- f(*(args + (7,))) is ugly  (*) Flat is better than nested -- less parenthesis 
 (*) Sparse is better than dense -- less noise  (*) Readability counts -- again, less noise  (*) Special cases aren't special enough to break the rules -- then why  are function calls so special to add a unique syntactic sugar for them? 
 the flattening operator would work on any sequence (having __iter__ or   __next__), not just tuples and lists. one very useful feature i can 
  think of is expanding generators, i.e.:  print xrange(10) # == xrange(10)   print *xrange(10) # == (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) 
 i mean, python already supports this half-way:  
 def f(*args): ...   print args  ...  
 f(*xrange(10)) (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)  so... why can't i just do print *xrange(10) directly? defining a
 function just to expand a generator? well, i could use   list(xrange(10))to expand it, but it's less intuitive. the other way is with list-comprehension,[x for x in xrange(10)]which is just, but isn't *xrange(10) more to-the-point? 
 also, There should be one-- and preferably only one --obvious way to  do it... so which one?   (*) list(xrange(10))   (*) [x for x in xrange(10)] 
  (*) mylist.extend(xrange(10))   (*) f(*xrange(10))  they all expand generators, but which is the preferable way?  

and imagine this:  f(*xrange(10), 7)  this time you can't do *(xrange(10) + (7,)) as generators do not 
  support addition... you'd have to do *(tuple(xrange(10)) + (7,)) which  is getting quite long already.  so as you can see, there are many inconsistencies between function-call 
 expressions and regular expressions, that impose artificial limitations  on the language. after all, the code is already in there to support the function-call version... all it takes is adding support for regular 
  expressions.so, what do you think? isn't symmetry worth it?-tomer

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


[Python-Dev] adding Construct to the standard library?

2006-04-17 Thread tomer filiba
hello folksafter several people (several  10) contacted me and said IMHO 'construct' is a good candidate for stdlib,i thought i should give it a try. of course i'm 
not saying it should be included right now, but in 6 months time, or such a
timeframe (aiming at python 2.6? some 2.5.x release?)a little intro:Construct (


http://pyconstruct.sourceforge.net/) is a library for declaratively defining data structures at the bit-level. 
these constructs can be used to parse raw data into objects, or build objects into raw data. you can see a couple of examples at 


http://pyconstruct.wikispaces.com/examples
being data structures they are not limited to simple structures -- they can be linked lists, for example, or an enitreefl32 file, with sections and pointers (included in the distribution). currently i'm writing  a parser of ext2 file systems, 
to allow inspecting file systems without mounting.why include Construct?* the struct module is very nice, but very limited and non-pythonic as well* pure python (no platform/security issues)* lots of people need to parse and build binary data structures, it's not an esoteric library
* license: public domain* quite a large user base for such a short time (proves the need of the community)* easy to use and extend (follows the componentization pattern)* declarative: you don't need to write executable code for most cases
why not:* the code is (very) young. stable and all, but less than a month on the loose. * new features may still be added / existing ones may be changed in a non-backwards-compatible mannerso why am i saying this now, instead of waiting a few months for it to maturet? 
well, i wanted to get feedback.
those of you who have seen/used the library, please tell me what you think:* is it suitable for a standard library?* what more features would you want?* any changes you think are necessary?i'm starting this now, in order to have a mature version in the (near) future.
thanks,-tomer



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