Re: [Python-Dev] Submitting PEP 422 (Simple class initialization hook) for pronouncement
On Sun, Feb 10, 2013 at 5:48 PM, Stefan Behnel stefan...@behnel.de wrote: However, it's hard to say if this new way of doing it doesn't come with its own can of worms. For example, would cooperative calls to __init_class__ work if a superclass already defines it? Do implementors have to remember that? And is it clear how this should be done, e.g. what should normally go first, my own code or the superclass call? Supporting cooperative __init_class__() calls properly might actually be a good thing. Currently, there's only one metaclass, plus a sequence of decorators, which makes the setup rather static and sometimes tedious for subclasses that need to do certain things by themselves, but in addition to what happens already. Cooperative multiple inheritance of __init_class__ would work exactly the same way as it works e.g., for __init__ of any other method (actually it is easier, since as Nick mentioned, the signature is always the same): __init_class__ can simply use the zero argument form of super. There is a simple example in the tests at http://bugs.python.org/issue17044. Daniel ___ 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] PEP 362: 4th edition
On Sat, Jun 16, 2012 at 5:56 AM, Jim J. Jewett jimjjew...@gmail.com wrote: I think it should be explicit that this mapping does not include parameters which would be filled by default arguments. In fact, if you stick with this interface, I would like a 3rd method that does fill out everything. +1 Daniel ___ 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] PEP 362 implementation issue: C callables
On Fri, Jun 15, 2012 at 11:24 PM, Larry Hastings la...@hastings.org wrote: There are four more candidates I found with the grep but couldn't figure out how to instantiate and test. They have to do with the descriptor protocol, aka properties, but the types aren't directly exposed by Python. They're all defined in Object/descrobject.c. The internal class names are: method_descriptor classmethod_descriptor wrapper_descriptor method-wrapper (you get one of these out of a wrapper_descriptor) 'method_descriptor' is apparently used for the methods of built-in (implemented in C) objects: set.__dict__['union'].__class__ class 'method_descriptor' 'classmethod_descriptor' is similarly for the classmethods of built-in classes: import itertools itertools.chain.__dict__['from_iterable'].__class__ class 'classmethod_descriptor' 'wrapper_descriptor' is used for example the operators of built-in types: int.__dict__['__add__'].__class__ class 'wrapper_descriptor' And 'method-wrapper': (5).__add__.__class__ class 'method-wrapper' Daniel ___ 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] [Python-checkins] peps: Update 422 based on python-dev feedback
On Thu, Jun 7, 2012 at 2:08 PM, nick.coghlan python-check...@python.org wrote: -* If the metaclass hint refers to an instance of ``type``, then it is +* If the metaclass hint refers to a subclass of ``type``, then it is considered as a candidate metaclass along with the metaclasses of all of the parents of the class being defined. If a more appropriate metaclass is found amongst the candidates, then it will be used instead of the one I think here instance was correct (see http://hg.python.org/cpython/file/default/Lib/types.py#l76 and http://hg.python.org/cpython/file/cedc68440a67/Python/bltinmodule.c#l90). Daniel ___ 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] [Python-checkins] peps: Update 422 based on python-dev feedback
On Thu, Jun 7, 2012 at 9:47 PM, Terry Reedy tjre...@udel.edu wrote: On 6/7/2012 11:45 AM, Daniel Urban wrote: On Thu, Jun 7, 2012 at 2:08 PM, nick.coghlanpython-check...@python.org wrote: -* If the metaclass hint refers to an instance of ``type``, then it is +* If the metaclass hint refers to a subclass of ``type``, then it is considered as a candidate metaclass along with the metaclasses of all of the parents of the class being defined. If a more appropriate metaclass is found amongst the candidates, then it will be used instead of the one I think here instance was correct (see http://hg.python.org/cpython/file/default/Lib/types.py#l76 and http://hg.python.org/cpython/file/cedc68440a67/Python/bltinmodule.c#l90). If so, then the behavior of the standard case of a type subclass is not obviously (to me) covered. A subclass of type is also necessarily an instance of type, so that is also covered by this case. Daniel ___ 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] Updated PEP 362 (Function Signature Object)
BoundArguments Object = Result of a ``Signature.bind`` call. Holds the mapping of arguments to the function's parameters. The Signature.bind function has changed since the previous version of the PEP. If I understand correctly, the 'arguments' attribute is the same as the return value of bind in the previous version (more or less the same as the return value of inspect.getcallargs). My question is: why we need the other 2 attributes ('args' and 'kwargs')? The Annotation Checker example uses it to call the function. But if we are able to call bind, we already have the arguments, so we can simply call the function with them, we don't really need these attributes. I think it would be better (easier to use and understand), if bind would simply return the mapping, as in the previous version of the PEP. Has the following public attributes: * arguments : OrderedDict An ordered mutable mapping of parameters' names to arguments' values. Does not contain arguments' default values. Does this mean, that if the arguments passed to bind doesn't contain a value for an argument that has a default value, then the returned mapping won't contain that argument? If so, why not? inspect.getcallargs works fine with default values. Daniel ___ 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] Updated PEP 362 (Function Signature Object)
BoundArguments Object = Result of a ``Signature.bind`` call. Holds the mapping of arguments to the function's parameters. The Signature.bind function has changed since the previous version of the PEP. If I understand correctly, the 'arguments' attribute is the same as the return value of bind in the previous version (more or less the same as the return value of inspect.getcallargs). My question is: why we need the other 2 attributes ('args' and 'kwargs')? The Annotation Checker example uses it to call the function. But if we are able to call bind, we already have the arguments, so we can simply call the function with them, we don't really need these attributes. I think it would be better (easier to use and understand), if bind would simply return the mapping, as in the previous version of the PEP. I'll try to answer you with the following code: def foo(*args): ... print(args) bound_args = signature(foo).bind(1, 2, 3) bound_args.arguments OrderedDict([('args', (1, 2, 3))]) You can't invoke 'foo' by: foo(**bound_args.arguments) TypeError: foo() got an unexpected keyword argument 'args' Of course, but you can invoke it with 1, 2, 3, the arguments you used to create the BoundArguments instance in the first place: foo(1, 2, 3) will work fine. That's why we have two dynamic properties 'args', and 'kwargs': Ok, but what I'm saying is, that we don't really need them. bound_args.args, bound_args.kwargs ((1, 2, 3), {}) 'BoundArguments.arguments', as told in the PEP, is a mapping to work with 'Signature.parameters' (you should've seen it in the Annotation Checker example). 'args' 'kwargs' are for invocation. You can even modify 'arguments'. Has the following public attributes: * arguments : OrderedDict An ordered mutable mapping of parameters' names to arguments' values. Does not contain arguments' default values. Does this mean, that if the arguments passed to bind doesn't contain a value for an argument that has a default value, then the returned mapping won't contain that argument? If so, why not? inspect.getcallargs works fine with default values. Yes, it won't. It contains only arguments you've passed to the 'bind'. The reason is because we'd like to save as much of actual context as possible. I don't really see, where this context can be useful. Maybe an example would help. If you pass some set of arguments to the bind() method, it tries to map precisely that set. This way you can deduce from the BoundArguments what it was bound with. And default values will applied by python itself. Anyway, I think it would be nice to be able to obtain the full arguments mapping that the function would see, not just a subset. Of course, we can use inspect.getcallargs for that, but I think we should be able to do that with the new Signature API. Daniel ___ 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] Updated PEP 362 (Function Signature Object)
On Wed, Jun 6, 2012 at 8:35 PM, Yury Selivanov yselivanov...@gmail.com wrote: On 2012-06-06, at 2:22 PM, Daniel Urban wrote: I'll try to answer you with the following code: def foo(*args): ... print(args) bound_args = signature(foo).bind(1, 2, 3) bound_args.arguments OrderedDict([('args', (1, 2, 3))]) You can't invoke 'foo' by: foo(**bound_args.arguments) TypeError: foo() got an unexpected keyword argument 'args' Of course, but you can invoke it with 1, 2, 3, the arguments you used to create the BoundArguments instance in the first place: foo(1, 2, 3) will work fine. The whole point is to use BoundArguments mapping for invocation. See Nick's idea to validate callbacks, and my response to him, below in the thread. That's why we have two dynamic properties 'args', and 'kwargs': Ok, but what I'm saying is, that we don't really need them. We need them. Again, in some contexts you don't have the arguments you've passed to bind(). But how could we *need* bind to return 'args' and 'kwargs' to us, when we wouldn't be able to call bind in the first place, if we wouldn't had the arguments? bound_args.args, bound_args.kwargs ((1, 2, 3), {}) 'BoundArguments.arguments', as told in the PEP, is a mapping to work with 'Signature.parameters' (you should've seen it in the Annotation Checker example). 'args' 'kwargs' are for invocation. You can even modify 'arguments'. Has the following public attributes: * arguments : OrderedDict An ordered mutable mapping of parameters' names to arguments' values. Does not contain arguments' default values. Does this mean, that if the arguments passed to bind doesn't contain a value for an argument that has a default value, then the returned mapping won't contain that argument? If so, why not? inspect.getcallargs works fine with default values. Yes, it won't. It contains only arguments you've passed to the 'bind'. The reason is because we'd like to save as much of actual context as possible. I don't really see, where this context can be useful. Maybe an example would help. For instance, for some sort of RPC mechanism, where you don't need to store/pass arguments that have default values. I see. So, basically, it's an optimization. If you pass some set of arguments to the bind() method, it tries to map precisely that set. This way you can deduce from the BoundArguments what it was bound with. And default values will applied by python itself. Anyway, I think it would be nice to be able to obtain the full arguments mapping that the function would see, not just a subset. Of course, we can use inspect.getcallargs for that, but I think we should be able to do that with the new Signature API. Well, it will take just a few lines of code to enrich BoundArguments with default values (we can add a method to do it, if it's really that required feature). But you won't be able to ever reconstruct what arguments the bind() method was called with, if we write default values to arguments from start. As I've mentioned above, I don't think, we have to be able to reconstruct the arguments passed to bind from the return value of bind. If we will need the original arguments later/in another place, we will just save them, bind doesn't have to complicate its API with them. Also, it's better for performance. Annotation Checker example does defaults validation first, and never checks them again. If bind() would write default values to 'BoundArguments.arguments', you would check defaults on each call. And think about more complicated cases, where processing of argument's value is more complicated and time consuming. Ok, so again, it is an optimization. Daniel ___ 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] Updated PEP 362 (Function Signature Object)
On Wed, Jun 6, 2012 at 10:10 PM, Yury Selivanov yselivanov...@gmail.com wrote: On 2012-06-06, at 3:33 PM, Daniel Urban wrote: On Wed, Jun 6, 2012 at 8:35 PM, Yury Selivanov yselivanov...@gmail.com wrote: On 2012-06-06, at 2:22 PM, Daniel Urban wrote: I'll try to answer you with the following code: def foo(*args): ... print(args) bound_args = signature(foo).bind(1, 2, 3) bound_args.arguments OrderedDict([('args', (1, 2, 3))]) You can't invoke 'foo' by: foo(**bound_args.arguments) TypeError: foo() got an unexpected keyword argument 'args' Of course, but you can invoke it with 1, 2, 3, the arguments you used to create the BoundArguments instance in the first place: foo(1, 2, 3) will work fine. The whole point is to use BoundArguments mapping for invocation. See Nick's idea to validate callbacks, and my response to him, below in the thread. That's why we have two dynamic properties 'args', and 'kwargs': Ok, but what I'm saying is, that we don't really need them. We need them. Again, in some contexts you don't have the arguments you've passed to bind(). But how could we *need* bind to return 'args' and 'kwargs' to us, when we wouldn't be able to call bind in the first place, if we wouldn't had the arguments? You're missing the point. BoundArguments contains properly mapped *args and **kwargs passed to Signature.bind. You can validate them after, do type casts, modify them, overwrite etc. by manipulating 'BoundArguments.arguments'. At the end you can't, however, invoke the function by doing: func(**bound_arguments.arguments) # - this won't work as varargs will be screwed. That's why you need 'args' 'kwargs' properties on BoundArguments. Imagine, that Annotation Checker example is modified to coerce all string arguments to int (those that had 'int' in annotation) and then to multiply them by 42. We'd write the following code: for arg_name, arg_value in bound_arguments.arguments.items(): # I'm skipping is_args is_kwargs checks, and assuming # we have annotations everywhere if sig.parameters[arg_name].annotation is int \ and isinstance(arg_value, str): bound_arguments.arguments[arg_name] = int(arg_value) * 42 return func(*bound_arguments.args, **bound_arguments.kwargs) I see. Thanks, this modifying example is the first convincing use case I hear. Maybe it would be good to mention something like this in the PEP. Daniel ___ 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] Language reference updated for metaclasses
I think there is a small mistake in section 3.3.3.4. Creating the class object: After the class object is created, any class decorators included in the *function* definition are invoked ... That probaly should be class definition. Daniel ___ 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 types.build_class for 3.3
On Wed, May 9, 2012 at 3:10 AM, Nick Coghlan ncogh...@gmail.com wrote: On Wed, May 9, 2012 at 8:37 AM, Tres Seaver tsea...@palladion.com wrote: No, the mcl in the call is just the designated metaclass - the *actual* metaclass of the resulting class definition may be something different. That's why this is a separate method from mcl.__new__. Why not make it a static method, if there is no notion of a useful 'cls' argument? We need the explicitly declared metaclass as well as the bases in order to determine the correct metaclass. Note, that the current patch (at http://bugs.python.org/issue14588) obtains the explicitly declared metaclass from the keywords dict (exactly like the class statement). As a static method, the invocation would look like: type.build_class(mcl, bases, keywords, exec_body) So I think, that in theory, this static method could work exactly like the operator.build_class function in the patch: type.build_class(name, bases, kwds, exec_body) (it doesn't need the mcls in a separate argument, it is in kwds). Since mcl will always be an instance of type in 3.x (due to all classes being subtypes of object), it makes more sense to just make it a class method and invoke the method on the declared metaclass: mcl.build_class(bases, keywords, exec_body) We could do that, but mcl will always be an instance of type in 3.x is not strictly true: an arbitrary callable is still allowed as a metaclass in a class statement, so I think the build_class function should support it too. The following assertion *does not* hold reliably: cls = mcl.build_class(bases, keywords, exec_body) assert type(cls) == mcl # Not guaranteed Right. Instead, the invariant that holds is the weaker assertion: cls = mcl.build_class(bases, keywords, exec_body) assert isinstance(cls, mcl) But if mcl is an arbitrary callable, this is also not always true (of course, then the invocation above wouldn't work, but with a class statement we could still create such classes: def f(mcls, name, bases): ... return 0 ... class C(metaclass=f): ... pass ... C 0 Daniel ___ 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] Providing a mechanism for PEP 3115 compliant dynamic class creation
On Mon, Apr 16, 2012 at 04:17, Nick Coghlan ncogh...@gmail.com wrote: Sure, just create a new tracker issue and assign it to me. You already know better than most what the _prepare() step needs to do :) I've created http://bugs.python.org/issue14588, and attached the first version of a patch. I can't assign it to you, but you're on the nosy list. Thanks, Daniel ___ 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] Providing a mechanism for PEP 3115 compliant dynamic class creation
On Tue, Apr 19, 2011 at 16:10, Nick Coghlan ncogh...@gmail.com wrote: In reviewing a fix for the metaclass calculation in __build_class__ [1], I realised that PEP 3115 poses a potential problem for the common practice of using type(name, bases, ns) for dynamic class creation. Specifically, if one of the base classes has a metaclass with a significant __prepare__() method, then the current idiom will do the wrong thing (and most likely fail as a result), since ns will probably be an ordinary dictionary instead of whatever __prepare__() would have returned. Initially I was going to suggest making __build_class__ part of the language definition rather than a CPython implementation detail, but then I realised that various CPython specific elements in its signature made that a bad idea. Are you referring to the first 'func' argument? (Which is basically the body of the class statement, if I'm not mistaken). Instead, I'm thinking along the lines of an operator.prepare(metaclass, bases) function that does the metaclass calculation dance, invoking __prepare__() and returning the result if it exists, otherwise returning an ordinary dict. Under the hood we would refactor this so that operator.prepare and __build_class__ were using a shared implementation of the functionality at the C level - it may even be advisable to expose that implementation via the C API as PyType_PrepareNamespace(). __prepare__ also needs the name and optional keyword arguments. So it probably should be something like operator.prepare(name, bases, metaclass, **kw). But this way it would need almost the same arguments as __build_class__(func, name, *bases, metaclass=None, **kwds). The correct idiom for dynamic type creation in a PEP 3115 world would then be: from operator import prepare cls = type(name, bases, prepare(type, bases)) Thoughts? When creating a dynamic type, we may want to do it with a non-empty namespace. Maybe like this (with the extra arguments mentioned above): from operator import prepare ns = prepare(name, bases, type, **kwargs) ns.update(my_ns) # add the attributes we want cls = type(name, bases, ns) What about an operator.build_class(name, bases, ns, **kw) function? It would work like this: def build_class(name, bases, ns, **kw): metaclass = kw.pop('metaclass', type) pns = prepare(name, bases, metaclass, **kw) pns.update(ns) return metaclass(name, bases, pns) (Where 'prepare' is the same as above). This way we wouldn't even need to make 'prepare' public, and the new way to create a dynamic type would be: from operator import build_class cls = build_class(name, bases, ns, **my_kwargs) Daniel ___ 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] Providing a mechanism for PEP 3115 compliant dynamic class creation
On Sun, Apr 15, 2012 at 13:48, Nick Coghlan ncogh...@gmail.com wrote: /me pages thoughts from 12 months ago back into brain... Sorry about that, I planned to do this earlier... On Sun, Apr 15, 2012 at 7:36 PM, Daniel Urban urban.dani...@gmail.com wrote: On Tue, Apr 19, 2011 at 16:10, Nick Coghlan ncogh...@gmail.com wrote: Initially I was going to suggest making __build_class__ part of the language definition rather than a CPython implementation detail, but then I realised that various CPython specific elements in its signature made that a bad idea. Are you referring to the first 'func' argument? (Which is basically the body of the class statement, if I'm not mistaken). Yup, I believe that was my main objection to exposing __build_class__ directly. There's no obligation for implementations to build a throwaway function to evaluate a class body. __prepare__ also needs the name and optional keyword arguments. So it probably should be something like operator.prepare(name, bases, metaclass, **kw). But this way it would need almost the same arguments as __build_class__(func, name, *bases, metaclass=None, **kwds). True. The correct idiom for dynamic type creation in a PEP 3115 world would then be: from operator import prepare cls = type(name, bases, prepare(type, bases)) Thoughts? When creating a dynamic type, we may want to do it with a non-empty namespace. Maybe like this (with the extra arguments mentioned above): from operator import prepare ns = prepare(name, bases, type, **kwargs) ns.update(my_ns) # add the attributes we want cls = type(name, bases, ns) What about an operator.build_class(name, bases, ns, **kw) function? It would work like this: def build_class(name, bases, ns, **kw): metaclass = kw.pop('metaclass', type) pns = prepare(name, bases, metaclass, **kw) pns.update(ns) return metaclass(name, bases, pns) (Where 'prepare' is the same as above). This way we wouldn't even need to make 'prepare' public, and the new way to create a dynamic type would be: from operator import build_class cls = build_class(name, bases, ns, **my_kwargs) No, I think we would want to expose the created namespace directly - that way people can use update(), direct assigment, exec(), eval(), or whatever other mechanism they choose to handle the task of populating the namespace. However, a potentially cleaner way to do that might be offer use an optional callback API rather than exposing a separate public prepare() function. Something like: def build_class(name, bases=(), kwds=None, eval_body=None): metaclass, ns = _prepare(name, bases, kwds) if eval_body is not None: eval_body(ns) return metaclass(name, bases, ns) That seems more flexible indeed. I will try to make a patch next week, if that's OK. Daniel ___ 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] python and super
On Thu, Apr 14, 2011 at 16:18, Ronald Oussoren ronaldousso...@mac.com wrote: It would be odd to not call super in __init__, but for other methods not calling the superclass implementation is fairly common. Yes it is odd, that for example list.__init__ doesn't call super :-) (http://bugs.python.org/issue8733) Daniel ___ 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] abstractmethod doesn't work in classes
I've found that abstractmethod and similar decorators don't work in classes, inherited from built-in types other than object. http://bugs.python.org/issue5996 ___ 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] Possible patch for functools partial - Interested?
On Mon, May 17, 2010 at 09:47, Hrvoje Niksic hrvoje.nik...@avl.com wrote: On 05/14/2010 06:39 AM, Daniel Urban wrote: I've made a new patch, in which the keywords attribute is a read-only proxy of the dictionary. What about backward compatibility? This looks like an incompatible change. You're probably right. I'd be happy to make patch which doesn't replace the dict with the proxy. But that would mean, that the hash value isn't really immutable. Daniel Urban ___ 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] Possible patch for functools partial - Interested?
On Thu, May 13, 2010 at 13:30, Steven D'Aprano st...@pearwood.info wrote: I'd support an immutable dict. partial objects already impose a significant (~ 30%) performance penalty: from timeit import Timer min(Timer('f(5)', 'f = lambda x: x').repeat()) 0.93580079078674316 min(Timer('p(5)', 'from functools import partial; p = partial(lambda x: x)').repeat()) 1.2715129852294922 No need to make that worse if that can be avoided. I've made a new patch, in which the keywords attribute is a read-only proxy of the dictionary. I've used your benchmark, and I haven't found any significant difference in execution times. The patch is in the tracker (http://bugs.python.org/issue8699) and Rietveld (http://codereview.appspot.com/1179044). Daniel Urban ___ 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] Possible patch for functools partial - Interested?
While a partial object should reasonably never change, you could change it: from functools import partial p = partial(lambda *a, **kw: kw, 1, 2, spam='eggs') p() {'spam': 'eggs'} p.keywords['spam'] = 'bacon' p() {'spam': 'bacon'} I realize touching p.keywords voids your warranty, but if we can stop people from doing it, maybe we should (or at least put a warning in the documentation, no?). So I'm thinking either we make an immutable/hashable dict while we're at it, or store the keyword arguments as a tuple (which guarantees immutability), and only convert them back to a dict when you want to call the partial object (simpler, slower). You're right. I think it is possible to stop people from modifying p.keywords. If p.keywords wouldn't be a dict, but a read-only proxy for that dict, that may solve this problem. I think that is possible, with PyDictProxy_New [1]. But I'm not certain if that is a good idea, it may have side effects I'm not aware of. Any thoughts about this? Your thoughts? Should we continue this discussion at issue8699? I don't know, I'm new here... [1] http://docs.python.org/py3k/c-api/dict.html#PyDictProxy_New Thanks, Daniel Urban ___ 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] Possible patch for functools partial - Interested?
I wrote an e-mail yesterday, but it seems, it didn't reach python-dev. Here it is again: On Thu, May 13, 2010 at 13:30, Steven D'Aprano st...@pearwood.info wrote: I'd support an immutable dict. partial objects already impose a significant (~ 30%) performance penalty: from timeit import Timer min(Timer('f(5)', 'f = lambda x: x').repeat()) 0.93580079078674316 min(Timer('p(5)', 'from functools import partial; p = partial(lambda x: x)').repeat()) 1.2715129852294922 No need to make that worse if that can be avoided. I've made a new patch, in which the keywords attribute is a read-only proxy of the dictionary. I've used your benchmark, and I haven't found any significant difference in execution times. The patch is in the tracker (http://bugs.python.org/issue8699) and Rietveld (http://codereview.appspot.com/1179044). Daniel Urban ___ 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] Possible patch for functools partial - Interested?
On Fri, May 7, 2010 at 17:02, Antoine Pitrou solip...@pitrou.net wrote: It would be more useful to provide equality, hashing and repr to partial itself, rather than a subclass. Feel free to propose a patch :) Hi! I've done that. I've opened a feature request: http://bugs.python.org/issue8699 The patch is also at Rietveld: http://codereview.appspot.com/1179044 I'm a beginner, so my patch is probably far from perfect, but I'd appreciate any help, and will try to correct my mistakes. Thanks, Daniel Urban ___ 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