@decorators

Discussion in 'Python' started by daishi, Aug 6, 2004.

  1. daishi

    daishi Guest

    For what it's worth:

    As far as I know, the proposed @decorator syntax will be the first
    time that two logical lines of python with the same indentation will
    not be independent of one another. Previously, when looking at:

    some_python(code)
    and_some_more = stuff

    there was no need to look at the the first line in order to know what
    the second line meant/did (and vice versa). It would seem that the
    cases when there are effects across multiple logical lines is captured
    in compound statements:

    """
    Compound statements contain (groups of) other statements; they affect
    or control the execution of those other statements in some way.
    """ -Python Reference Manual

    My understanding of decorators is that they fit this definition.
    One thing that I am not entirely clear about is whether decorators
    are intended to be a compound statement themselves, or whether they
    are meant to simply be extensions of current compound statements
    such as function definition (and class definitions?)

    In either case, however, it seems that the following should apply:

    """
    Each clause header begins with a uniquely identifying keyword and ends
    with a colon. A suite ... can be one or more indented statements on
    subsequent lines.
    """ -Python Reference Manual

    In the first case where decorators form their own compound statement,
    this would seem to imply the basic layout of:

    @decorator:
    def foo():
    pass

    (Whether that uniquely identifying keyword for decorators happens to
    be spelled '@' is not important to me.)

    In the second case where decorators are simply extensions of current
    compound statements, the current wording of the Python Reference
    Manual would seem to imply that for function definition the clause
    header must begin with 'def'. I.e., the decorator should not come
    before the def, and certainly not on a separate line. Beyond this,
    however, for me it is not particularly important whether the
    decorator comes before/after the function name/argument list, and
    how it is delimited.

    I guess the basic point that I am trying to make is that what I find
    important is consistency with the basic visual layout of code promised
    (IMHO) by python. I believe that this promise is violated by the
    currently proposed decorator scheme.

    d

    PS: Although I believe the current view of the implementors is to view
    decorators as an extension to function definition, I believe that the
    separate compound statement view is fairly rich. As others have noted,
    it can make identical decorations simpler:

    @static,synchronized:
    def foo():
    pass
    def bar():
    pass
    daishi, Aug 6, 2004
    #1
    1. Advertising

  2. daishi

    Roy Smith Guest

    A few random comments:

    I really dislike the proposed syntax, for two main reasons. First, I
    don't like the idea of inventing new uses for punctuation (down that
    road lies perl). Second, I don't like the idea that you're creating a
    contextual block which violates (or at least ignores) the normal
    indenting rules.

    I just went to read pep-318 in its entirety, and discovered that the
    last modified date is only a few hours ago. People might want to go
    read the latest version.

    I'm also wondering about doc strings. Doc strings are really metadata,
    and if the idea of decorators is to build a uniform way to handle
    metadata, it would be nice to see it somehow include docstrings. There
    are clearly backward compatability issues to worry about, however.

    I'm also thinking about programming by contract. It seems like the pre-
    and post-condition assertions could also be thought of as meta-data.
    Some of the examples in the PEP hint at doing this, but don't address
    things contract inheritance. Has there been any discussion of this?

    Lastly, and perhaps most importantly, I'm rather distressed at the tone
    of some of the postings I've seen here over the past couple of days.
    Some of the sentiments I've seen expressed are downright rude,
    combative, and accusatory. These sorts of things are way out of line.

    Come on folks. It should be possible to express an opinion, even a
    strongly held one, without resorting to accusations of sinister plots or
    evil intent. I may not like the proposal, but at the same time I'm
    hugely appreciative of the hard work put in by the folks who proposed
    it, paid their own way to go to meetings where it was discussed, wrote
    the code, did the builds, etc, etc. They deserve accolades, not
    hostility.
    Roy Smith, Aug 6, 2004
    #2
    1. Advertising

  3. Thinking about the editing of programs containing decorators (which
    probably are not anyway) ,if they are placed before the def (and class?)
    probably
    it's right to have a special symbol marking all lines which are to be
    folded with the owner of them,so they can be easily recognized.
    Surely this breaks identation layout because these lines look like pieces
    of the outer scope.

    Some of the __x__ methods are in some way orthogonal to the code .I wonder
    if this new orthogonality shouldn't share this syntax ....

    In ruby '@' is in place of methods 'firstarg.' which is very efficient.I
    would like to use the @ symbol like first argument to methods ,in place of
    a name(self for most).But this is another story.

    I hope there is a way to 'decorate' inside the def which is possibly
    wrong:this thing I would like to understand more.

    Ciao Paolino
    --
    .....lotta dura per la verdura
    paolo veronelli, Aug 6, 2004
    #3
  4. daishi

    John Roth Guest

    "Roy Smith" <> wrote in message
    news:...
    > A few random comments:
    >
    >
    > I'm also thinking about programming by contract. It seems like the pre-
    > and post-condition assertions could also be thought of as meta-data.
    > Some of the examples in the PEP hint at doing this, but don't address
    > things contract inheritance. Has there been any discussion of this?


    There are several DBC packages out there. I can't give you any
    pointers because I don't do things that way, but I've seen some
    rather enthusiastic comments.

    All of the existing packages (at least to my knowledge) use
    descriptors to wrap the necessary functions. They could be
    very easily reimplemented in terms of the decorator syntax.
    However, the decorator syntax brings no new functionality
    to the table; it's simply syntactic sugar for already existing
    functionality.

    It may, of course, improve readability, which is always
    desirable.

    > Lastly, and perhaps most importantly, I'm rather distressed at the tone
    > of some of the postings I've seen here over the past couple of days.
    > Some of the sentiments I've seen expressed are downright rude,
    > combative, and accusatory. These sorts of things are way out of line.


    Likewise.

    John Roth
    John Roth, Aug 6, 2004
    #4
  5. On Fri, 06 Aug 2004 08:19:43 -0400, Roy Smith <> wrote:
    > I just went to read pep-318 in its entirety, and discovered that the
    > last modified date is only a few hours ago. People might want to go
    > read the latest version.


    Don't get too excited - there's going to be a lot more updates happening
    to it still.
    Anthony Baxter, Aug 6, 2004
    #5
  6. daishi

    Mark Bottjer Guest

    John Roth wrote:
    > All of the existing packages (at least to my knowledge) use
    > descriptors to wrap the necessary functions. They could be
    > very easily reimplemented in terms of the decorator syntax.
    > However, the decorator syntax brings no new functionality
    > to the table; it's simply syntactic sugar for already existing
    > functionality.


    Exactly. What's more, I don't think that decorators are really the ideal
    way to express DBC, either. For one thing, pre and post conditions often
    want access to at least the argument list, and often to the internal
    variables of the definition. I don't think that this will be possible
    with the decorators as proposed, since they are outside the scope of the
    function.

    > It may, of course, improve readability, which is always
    > desirable.


    I think readability would be improved more by adding support in the form
    of special control blocks (more like if and while than def or class):

    class C:
    def f( self, a, b):
    pre:
    assert type(a) == types.int
    assert type(b) == types.int
    assert a < b
    post:
    assert (rc is None) or (type( rc) == types.list)
    if (a % b) > (a / b):
    return None
    return (a % b) * (a / b)

    Bringing this back on topic, the decorator syntax could theoretically be
    extended to support this:

    class C:
    def f( self, a, b):
    @pre:
    ...
    @post:
    ...
    if ...

    That is, decorators optionally could accept a block of code along with
    their explicit arguments. What they do with that block is up to them. Of
    course, I'm not familiar enough with the internals to know how feasible
    this would be...

    > "Roy Smith" <> wrote...
    >>Lastly, and perhaps most importantly, I'm rather distressed at the tone
    >>of some of the postings I've seen here over the past couple of days.
    >>Some of the sentiments I've seen expressed are downright rude,
    >>combative, and accusatory. These sorts of things are way out of line.


    Agreed. I think we're all a bit on edge at seeing something we think
    might still be flawed about to be canonized, but bickering won't help
    anything.

    Don't forget: if we make this too painful for the BDFL, he might just
    drop the whole idea and tell us to live with what we've got. :)

    -- Mark
    Mark Bottjer, Aug 6, 2004
    #6
  7. daishi

    Mark Bottjer Guest

    Roy Smith wrote:
    > I really dislike the proposed syntax, for two main reasons. First, I
    > don't like the idea of inventing new uses for punctuation (down that
    > road lies perl).


    Eh. After print >>, it doesn't seem so bad :). And I *like* the fact
    that it doesn't look like a normal statement, because it *isn't* a
    normal statement. This could also be accomplished with a keyword, but
    I've yet to hear one that makes sense in all usages.

    > Second, I don't like the idea that you're creating a
    > contextual block which violates (or at least ignores) the normal
    > indenting rules.


    Bingo! That is my biggest problem with this syntax. If it were just
    moved inside the function definition, like the docstring, I'd be *so*
    much happier...

    > I'm also wondering about doc strings. Doc strings are really metadata,
    > and if the idea of decorators is to build a uniform way to handle
    > metadata, it would be nice to see it somehow include docstrings.


    I'm not sure docstrings need to change. The do what they do pretty well
    (though I'd like to be able to parse them a bit more easily). @dec isn't
    just about metadata, though: its about *any* sort of modification to the
    default function object def creates. Metadata is one of the more common
    uses, to be sure, but by no means the only one. In short, I see no need
    to bring the docstring into this.

    -- Mark
    Mark Bottjer, Aug 6, 2004
    #7
  8. daishi

    John Roth Guest

    "Mark Bottjer" <> wrote in message
    news:...
    > John Roth wrote:
    > > All of the existing packages (at least to my knowledge) use
    > > descriptors to wrap the necessary functions. They could be
    > > very easily reimplemented in terms of the decorator syntax.
    > > However, the decorator syntax brings no new functionality
    > > to the table; it's simply syntactic sugar for already existing
    > > functionality.

    >
    > Exactly. What's more, I don't think that decorators are really the ideal
    > way to express DBC, either. For one thing, pre and post conditions often
    > want access to at least the argument list, and often to the internal
    > variables of the definition. I don't think that this will be possible
    > with the decorators as proposed, since they are outside the scope of the
    > function.


    Since I wrote that, I managed to read the new, improved
    and rewritten PEP, and discovered that the new syntax
    doesn't allow parameters. So it can't be used as a replacement
    for the property() built-in function, and it therefore also can't
    be used for the DBC functionality. As delivered, it's strictly
    a replacement for the classmethod and staticmethod
    builtin functions (and any other module or builtins that
    take one parameter, of course.)

    Guido's stated reasoning was that he had "a bad feeling"
    about allowing more general expressions. So do I.
    From what people are saying that's substantive (rather
    than syntactic) I think that there are a number of very
    different desires on the table, and it's not at all clear
    either what they are or how they combine.

    > Don't forget: if we make this too painful for the BDFL, he might just
    > drop the whole idea and tell us to live with what we've got. :)


    He's been through it before. Remember PEP 308?

    John Roth
    >
    > -- Mark
    John Roth, Aug 6, 2004
    #8
  9. daishi

    Mark Bottjer Guest

    John Roth wrote:
    > Since I wrote that, I managed to read the new, improved
    > and rewritten PEP, and discovered that the new syntax
    > doesn't allow parameters.


    Sigh. My knowledge is SO last night...

    > So it can't be used as a replacement
    > for the property() built-in function, and it therefore also can't
    > be used for the DBC functionality. As delivered, it's strictly
    > a replacement for the classmethod and staticmethod
    > builtin functions (and any other module or builtins that
    > take one parameter, of course.)


    Right. But people are still chasing after parameterized decorators,
    which is why I included the example.

    Personally, I think that we will never have a "one size fits all"
    solution here, other than the one we *already* have. When doing
    something truly unusual, I see nothing wrong with using the existing
    (foo = bar(foo, baz)) syntax to do it. Syntactic sugar is about making
    common cases easier, not about providing everything for everyone.

    > Guido's stated reasoning was that he had "a bad feeling"
    > about allowing more general expressions. So do I.
    > From what people are saying that's substantive (rather
    > than syntactic) I think that there are a number of very
    > different desires on the table, and it's not at all clear
    > either what they are or how they combine.


    Agreed. Along the same lines, I read a post elsewhere which reminded us
    that we can always *relax* the restrictions later, once we understand
    what we actually want. Sage advise.

    > He's been through it before. Remember PEP 308?


    I try not to... :)

    -- Mark
    Mark Bottjer, Aug 6, 2004
    #9
  10. daishi

    Tim Peters Guest

    [John Roth]
    > ...
    > Since I wrote that, I managed to read the new, improved
    > and rewritten PEP, and discovered that the new syntax
    > doesn't allow parameters.


    It does. What it says is "arbitrary expressions will not work", and I
    would agree that's vague if you insisted it was <wink>. What it means
    is that parameters are fine, but things like

    @list_of_decorators[index]
    @eatme and deco1 or deco2
    @random.choice([deco1, deco2, deco3])

    are right out. Note that the PEP still contains examples of
    decorators with arguments, and the people who want decorators most
    need them to accept arguments.
    Tim Peters, Aug 6, 2004
    #10
  11. daishi

    John Roth Guest

    "Tim Peters" <> wrote in message
    news:...
    > [John Roth]
    > > ...
    > > Since I wrote that, I managed to read the new, improved
    > > and rewritten PEP, and discovered that the new syntax
    > > doesn't allow parameters.

    >
    > It does. What it says is "arbitrary expressions will not work", and I
    > would agree that's vague if you insisted it was <wink>. What it means
    > is that parameters are fine, but things like
    >
    > @list_of_decorators[index]
    > @eatme and deco1 or deco2
    > @random.choice([deco1, deco2, deco3])
    >
    > are right out. Note that the PEP still contains examples of
    > decorators with arguments, and the people who want decorators most
    > need them to accept arguments.


    OK. I sit corrected.

    John Roth
    John Roth, Aug 6, 2004
    #11
  12. Tim Peters <> writes:

    > It does. What it says is "arbitrary expressions will not work", and I
    > would agree that's vague if you insisted it was <wink>. What it means
    > is that parameters are fine, but things like
    >
    > @list_of_decorators[index]


    This could be written legally as
    @list_of_decorators.__getitem__(1)

    Or one could use operator.getitem

    > @eatme and deco1 or deco2


    @eval("eatme and deco1 or deco2")

    > @random.choice([deco1, deco2, deco3])


    That one is already legal!

    Seems the restriction is somewhat pointless as it's easy to work around
    if one really wants to.

    Bernhard

    --
    Intevation GmbH http://intevation.de/
    Skencil http://sketch.sourceforge.net/
    Thuban http://thuban.intevation.org/
    Bernhard Herzog, Aug 7, 2004
    #12
  13. Mark Bottjer <>
    wrote on Fri, 06 Aug 2004 16:10:37 -0400:
    > John Roth wrote:
    >> All of the existing packages (at least to my knowledge) use
    >> descriptors to wrap the necessary functions. They could be
    >> very easily reimplemented in terms of the decorator syntax.
    >> However, the decorator syntax brings no new functionality
    >> to the table; it's simply syntactic sugar for already existing
    >> functionality.

    > Exactly. What's more, I don't think that decorators are really the ideal
    > way to express DBC, either. For one thing, pre and post conditions often
    > want access to at least the argument list, and often to the internal
    > variables of the definition. I don't think that this will be possible
    > with the decorators as proposed, since they are outside the scope of the
    > function.


    You can already do pre- and post-conditions without new syntax:

    import types
    def intdiv(a, b):
    # preconditions
    assert type(a) == types.IntType
    assert type(b) == types.IntType
    assert b != 0
    rc = None
    try:
    # body
    rc = a // b; return rc
    finally:
    # postconditions
    assert type(rc) == types.IntType

    If assignment was an expression, that return would be a little nicer,
    but it's acceptable.

    --
    <a href="http://kuoi.asui.uidaho.edu/~kamikaze/"> Mark Hughes </a>
    "Virtues foster one another; so too, vices.
    Bad English kills trees, consumes energy, and befouls the Earth.
    Good English renews it." -The Underground Grammarian, v1n2
    Mark 'Kamikaze' Hughes, Aug 9, 2004
    #13
  14. daishi

    Mark Bottjer Guest

    Mark 'Kamikaze' Hughes wrote:
    > You can already do pre- and post-conditions without new syntax:
    >
    > import types
    > def intdiv(a, b):
    > # preconditions
    > assert type(a) == types.IntType
    > assert type(b) == types.IntType
    > assert b != 0
    > rc = None
    > try:
    > # body
    > rc = a // b; return rc
    > finally:
    > # postconditions
    > assert type(rc) == types.IntType
    >
    > If assignment was an expression, that return would be a little nicer,
    > but it's acceptable.


    Sorry, but to me this is ugly. The preconditions aren't so bad (in fact,
    much of my code has just such lines in it), but that postcondition block
    is awful. It looks arbitrary, hides the real "meat" of the function, and
    requires the construction of an exception frame when one shouldn't
    really be needed. It works, certainly, but I think we'll have to "agree
    to disagree" about how acceptable this syntax is. :)

    > Mark Bottjer <>
    > wrote on Fri, 06 Aug 2004 16:10:37 -0400:
    >
    >> Exactly. What's more, I don't think that decorators are really the
    >> ideal way to express DBC, either. For one thing, pre and post
    >> conditions often want access to at least the argument list, and often
    >> to the internal variables of the definition. I don't think that this
    >> will be possible with the decorators as proposed, since they are
    >> outside the scope of the function.


    After more thought, I think that it might be possible using decorators
    and subfunctions. Shouldn't the following be workable?

    import types
    @pre_and_post
    def intdiv(a, b):
    def __pre():
    assert type(a) == types.IntType
    assert type(b) == types.IntType
    assert b != 0
    def __post():
    assert type(rc) == types.IntType
    return a // b

    Where pre_and_post effectively wraps intdiv with the statement sequence:

    intdiv.__pre()
    try:
    return intdiv( *args)
    finally:
    intdiv.__post()

    This is functionally equivalent to your example (it even still requires
    the try/finally). But I suggest that this version is more understandable
    because it breaks the code up by what it does: __pre collects all the
    preconditions, __post collects all the postconditions, and the body is
    left alone. Theoretically, we could even globally enable or disable DBC
    by having pre_and_post switch on some global variable, which would not
    be possible with the conditions coded inline.

    I'm not savvy enough with Python internals to code this up myself, but
    I'm sure someone out there either can, or can tell me why it won't work.

    -- Mark
    Mark Bottjer, Aug 11, 2004
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Michael Strorm
    Replies:
    12
    Views:
    1,769
    Michael Strorm
    Apr 20, 2005
  2. Michael Sparks

    Using metaclasses to play with decorators.

    Michael Sparks, Jun 15, 2004, in forum: Python
    Replies:
    4
    Views:
    335
    Michele Simionato
    Jun 18, 2004
  3. Michael Sparks
    Replies:
    6
    Views:
    351
    David MacQuigg
    Jun 18, 2004
  4. Robert Brewer
    Replies:
    9
    Views:
    313
    David MacQuigg
    Jun 26, 2004
  5. Arien Malec

    PEP 318 decorators are not Decorators

    Arien Malec, Aug 13, 2004, in forum: Python
    Replies:
    11
    Views:
    567
    Arien Malec
    Aug 16, 2004
Loading...

Share This Page