[issue4331] Add functools.partialmethod

2013-10-29 Thread alon horev

alon horev added the comment:

I've changed the test according to the code review. Thanks

--
Added file: http://bugs.python.org/file32409/4331.v2.patch

___
Python tracker 
<http://bugs.python.org/issue4331>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue4331] Add functools.partialmethod

2013-10-28 Thread alon horev

alon horev added the comment:

Adding a patch with tests and documentation. Please feel free to comment on 
anything: my English, coding/testing style. 

I'm pretty sure the documentation can be better but it turns out I speak better 
Python than English.

Two decisions I've made and unsure of:
1. I didn't use @wraps or copied attributes from the wrapped function  
(__doc__, __dict__) to the partialmethod object. This is intentionally so 
partial and partialmethod would have similar semantics.
2. I've implemented a __repr__ although in all cases __get__ returns a partial 
object or bound method. I consider it nice for debugging when looking at an 
object's __dict__.

--
Added file: http://bugs.python.org/file32405/4331.v1.patch

___
Python tracker 
<http://bugs.python.org/issue4331>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue4331] Add functools.partialmethod

2013-10-27 Thread alon horev

alon horev added the comment:

I think the following test demonstrates the API we're looking for.
1. Am I missing any functionality?
2. How does partialmethod relate to @absolutemethod?

from functools import partial

class partialmethod(object):

def __init__(self, func, *args, **keywords):
# func could be a descriptor like classmethod which isn't callable,
# so we can't inherit from partial (it verifies func is callable)
if isinstance(func, partialmethod):
# flattening is mandatory in order to place cls/self before all 
other arguments
# it's also more efficient since only one function will be called
self.func = func.func
self.args = func.args + args
self.keywords = {}
self.keywords.update(func.keywords)
self.keywords.update(keywords)
else:
self.func = func
self.args = args
self.keywords = keywords

def _make_unbound_method(self):
def _method(*args, **keywords):
keywords.update(self.keywords)
cls_or_self, *rest = args
call_args = (cls_or_self,) + self.args + tuple(rest)
return self.func(*call_args, **keywords)
return _method

def __get__(self, obj, cls):
get = getattr(self.func, "__get__", None)
if get is None:
if obj is None:
return self._make_unbound_method()
return partial(self._make_unbound_method(), obj) # returns a bound 
method
else:
callable = get(obj, cls)
if callable is self.func:
return self._make_unbound_method()
return partial(callable, *self.args, **self.keywords)

class A(object):
def add(self, x, y):
return self, x + y

add10 = partialmethod(add, 10)
add10class = partialmethod(classmethod(add), 10)
add10static = partialmethod(staticmethod(add), 'self', 10)

return15 = partialmethod(add10, 5) # nested partialmethod

add2partial = partial(add, x=2)
return12 = partialmethod(add2partial, y=10) # partialmethod over partial

def test():
cls = A
instance = cls()

assert instance.add10class(5) == (cls, 15)
assert cls.add10class(5) == (cls, 15)

assert instance.add10static(5) == ('self', 15)
assert cls.add10static(5) == ('self', 15)

assert instance.add10(5) == (instance, 15)
assert cls.add10(instance, 5) == (instance, 15)

assert instance.return15() == (instance, 15)
assert cls.return15(instance) == (instance, 15)

assert instance.return12() == (instance, 12)
assert cls.return12(instance) == (instance, 12)

test()

--

___
Python tracker 
<http://bugs.python.org/issue4331>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue4331] Add functools.partialmethod

2013-10-26 Thread alon horev

alon horev added the comment:

Here's another attempt at a consistent api with regular methods. 
I'm contemplating whether partialmethod should support __call__. Given the fact 
partial is used to bind positional arguments, it will do the 'wrong' thing when 
calling the partialmethod directly and will shift all positional arguments 
(example at the last line of the snippet).

I also think staticmethod in this context is useless but agree consistency is a 
thing (you could just use partial instead).

If consistency hadn't held us back, the first proposal of partialmethod, 
working both for instances and classes, would have been most elegant.

from functools import partial

class partialmethod(object):

def __init__(self, func, *args, **keywords):
self.func = func
self.args = args
self.keywords = keywords

def __call__(self, *args, **keywords):
call_keywords = {}
call_keywords.update(self.keywords)
call_keywords.update(keywords)
return self.func(*(self.args + args), **call_keywords)

def __get__(self, obj, cls):
return partial(self.func.__get__(obj, cls), *self.args, **self.keywords)

class A(object):
def add(self, x, y):
print(self)
return x + y
add10 = partialmethod(add, 10)
add10class = partialmethod(classmethod(add), 10)
add10static = partialmethod(staticmethod(add), 'self', 10)

assert A().add10(5) == 15 # prints <__main__.A object at 0x1097e1390>
assert A.add10class(5) == 15 # prints 
assert A.add10static(5) == 15 # prints self
assert A.add10(2, 3) == 5 # prints 10 because the first positional argument is 
self..

Once we approve of the API I'll provide a full fledged patch.

--

___
Python tracker 
<http://bugs.python.org/issue4331>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue4331] Add functools.partialmethod

2013-10-25 Thread alon horev

alon horev added the comment:

I just want to make sure I understand the semantics concerning class methods, 
the following example demonstrates a usage similar to regular methods as much 
as possible:

class A(object):
def add(self, x, y):
print(self)
return x + y
add10 = partialmethod(add, 10)
add10class = classmethod(partialmethod(add, 10))

assert A().add10(5) == 15 # prints <__main__.A object at 0x1097e1390>
assert A.add10class(5) == 15 # prints 

Another option would be to return a class-bound partial from the __get__ 
method. It's not as consistent as the first example but perhaps nicer:

class A(object):
def add(self, x, y):
print(self)
return x + y
add10 = partialmethod(add, 10)

assert A().add10(5) == 15 # prints <__main__.A object at 0x1097e1390>
assert A.add10(5) == 15 # prints 

Is the first option what you had in mind?

--
nosy: +alonho

___
Python tracker 
<http://bugs.python.org/issue4331>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue19080] Enrich SyntaxError with additional information

2013-09-23 Thread alon horev

New submission from alon horev:

Some context for this feature request:
I'm using the wonderful ast module for a library that translates python code to 
MongoDB queries (https://github.com/alonho/pql). I also did the same for SQL 
queries using sqlalchemy as a part of another project 
(https://github.com/alonho/pytrace).

One of the things I find lacking in python's parser is additional information 
about SyntaxErrors. This could help users of the 'ast' module, IDE and 
developers.

Here are some examples of what I'd like to see
1. ast.parse('* 2') -> SyntaxError('Unexpected operator at start of an 
expression')
2. ast.parse('2 *') -> SyntaxError('Missing right hand side operand')
3. ast.parse('if a = 1: pass') -> SyntaxError('Cannot assign inside an 
expression')

There are several challenges here:
1. Does the parser have this information and doesn't surface it?
2. Can such messages be automatically generated without filling the code with 
error handling code? 3. Which part of the code could be responsible for this 
kind of a task? I've looked at the BNF and it contains more than just syntax 
legality but operator precedence and such. Perhaps there's another (simpler) 
grammar definition somewhere?

I was curious to see what Ruby does, and it uses a simple solution of providing 
raw information along with the exception:
>> a == * 1
SyntaxError: compile error
(irb):17: syntax error, unexpected tSTAR
a == * 1
  ^
from (irb):17

--
components: Interpreter Core
messages: 198341
nosy: alonho
priority: normal
severity: normal
status: open
title: Enrich SyntaxError with additional information
type: enhancement

___
Python tracker 
<http://bugs.python.org/issue19080>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue7317] Display full tracebacks when an error occurs asynchronously

2012-10-31 Thread alon horev

alon horev added the comment:

Hi Antoine, can you please have a look at the patch? It's been over a year 
since it's submitted. (-: thanks!

--

___
Python tracker 
<http://bugs.python.org/issue7317>
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue14963] Use an iterative implementation for contextlib.ExitStack.__exit__

2012-06-02 Thread alon horev

alon horev  added the comment:

after #14969 has closed, can this be closed? any more action items?

--

___
Python tracker 
<http://bugs.python.org/issue14963>
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue14969] Use __suppress_context__ in contextlib.ExitStack.__exit__

2012-06-01 Thread alon horev

alon horev  added the comment:

Ok, so turns out this was just a stupid bug: we set the __context__ attr only 
if an exception is raised, but not when an exception has been previously 
'cleared'. so the context is filled (by python) with the last exception raised 
which is the outer one.
deleting the 'if last context is an exception' solved it.

This is how I understood it:
the exception's __context__ is set when it's raised and not in its except 
clause, meaning there is no way the outer with is mutating our inner 
exceptions. using pdb I saw the outer exception being explicitly set.

--
keywords: +patch
Added file: http://bugs.python.org/file25785/14963.3.patch

___
Python tracker 
<http://bugs.python.org/issue14969>
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue14969] Restore sys.exc_clear()?

2012-05-31 Thread alon horev

alon horev  added the comment:

Another possible solution is to explicitly set an exception's 
__supress_context__ attribute to False (right now impossible because it's the 
default value). 
If a user can 'turn on' the flag when attaching a different exception (raise X 
from Y), why not allow 'turning it off'? (symmetry anyone?) right now it is set 
to False by default and changed to true when 'raising from'.
I suggest changing the default to None, allowing the user to explicitly say: 
I'm no longer in the previous exception's context.

Feels a bit like solving our hack with another hack (:

And about the PSF contrib agreement, I'll do it as soon as I'm near a printer. 
too bad we're using pens and not RSA private keys for signatures (-:

   thanks, Alon

--
nosy: +alonho

___
Python tracker 
<http://bugs.python.org/issue14969>
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue14963] Use an iterative implementation for contextlib.ExitStack.__exit__

2012-05-31 Thread alon horev

alon horev  added the comment:

that was indeed trickier, but overriding the __context__ attribute did the 
trick.

--
Added file: http://bugs.python.org/file25770/14963.2.patch

___
Python tracker 
<http://bugs.python.org/issue14963>
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue14963] Use an iterative implementation for contextlib.ExitStack.__exit__

2012-05-30 Thread alon horev

alon horev  added the comment:

The iterative approach turned out elegant and concise.
It actually now resembeles the implementation of nested's __exit__.

--
keywords: +patch
nosy: +alonho
Added file: http://bugs.python.org/file25763/14963.patch

___
Python tracker 
<http://bugs.python.org/issue14963>
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue7317] Display full tracebacks when an error occurs asynchronously

2012-05-12 Thread alon horev

alon horev  added the comment:

how does one get his patch reviewed? (it's been 6 months)

--

___
Python tracker 
<http://bugs.python.org/issue7317>
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue7317] Display full tracebacks when an error occurs asynchronously

2011-10-15 Thread alon horev

alon horev  added the comment:

Here's the next attempt (took your advice about the convention):

Exception ignored in: >
Traceback (most recent call last):
  File "/tmp/bla.py", line 4, in __del__
None.someattr
AttributeError: 'NoneType' object has no attribute 'someattr'

reminder of the current format for comparison:

Exception AttributeError: "'NoneType' object has no attribute 'someattr'" in 
> ignored

I thought about a more elaborate explanation than "Exception ignored" but 
grepping this function through the code shows it can be called from various 
places making it too generic.

The reason I wanted to add a header/footer is for stating the message and the 
traceback go together (I print tracebacks to screen all the time), but it might 
be TMI..

--
Added file: http://bugs.python.org/file23414/7317.patch

___
Python tracker 
<http://bugs.python.org/issue7317>
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue7317] Display full tracebacks when an error occurs asynchronously

2011-10-15 Thread alon horev

alon horev  added the comment:

Submitting a patch proposing this format:

-BEGIN UNRAISABLE EXCEPTION-
Class: AttributeError
Instance: "'NoneType' object has no attribute 'someattr'"
Function: >
Traceback (most recent call last):
  File "/tmp/bla.py", line 4, in __del__
None.someattr
-END UNRAISABLE EXCEPTION-

I've wrapped the exception information with header/footer differentiating it 
from a user's error handling code that also prints tracebacks (is it too much?).

I've considered using the warnings module, But I dislike the suppression of 
already warned messages. (2 instances will raise exception in __del__ but only 
one message will be printed) 

This is my first patch submission so feel free giving me a hard time.

--
keywords: +patch
nosy: +alonho
Added file: http://bugs.python.org/file23413/7317.patch

___
Python tracker 
<http://bugs.python.org/issue7317>
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue8733] list type and UserList do not call super in __init__ and therefore, they cannot be parents in a multiple inheritence scheme

2010-05-16 Thread alon horev

Changes by alon horev :


--
components: Extension Modules
nosy: alonho
priority: normal
severity: normal
status: open
title: list type and UserList do not call super in __init__ and therefore, they 
cannot be parents in a multiple inheritence scheme
type: behavior
versions: Python 3.3

___
Python tracker 
<http://bugs.python.org/issue8733>
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com