Re: Adding abort and redirect to Pyramid

2011-05-26 Thread Mike Orr
On Sun, May 15, 2011 at 11:27 PM, Chris McDonough chr...@plope.com wrote:
 I've created a branch named httpexception-utils on GitHub which
 contains an implementation of redirect and abort for Pyramid that
 act like their Pylons brethren.

 In short, the abort feature is used like this:

    from pryamid.httpexceptions import abort

    def aview(request):
        abort(401)

 This will perform the same job as what used to be necessary as:

    def aview(request):
        return HTTPUnauthorized()

 The redirect feature is used like this:

    from pryamid.httpexceptions import redirect

    def aview(request):
        redirect('http://example.com')

 This will perform the same job as what used to be necessary as:

    def aview(request):
        return HTTPFound(location='http://example.com')

 In addition, any HTTP exception (an exception imported from
 pyramid.httpexceptions) can now be raised rather than returned.  The
 object raised will be used as a response.

 Here's the branch:

 https://github.com/Pylons/pyramid/tree/httpexception-utils

 Here's the commit which added the feature:

 https://github.com/Pylons/pyramid/commit/1ffb8e3cc21603b29ccd78152f82cca7f61a09b1

 It'd be nice to get some feedback from existing Pylons users to see if
 the implementations of these features are good enough; it'd also be
 nice to hear dissenting opinions with reasons for dissent if folks
 believe this feature should not be added to Pyramid.

Raising HTTP exceptions should definitely be added to Pyramid. It's
silly for an application to have to add an exception view that just
returns the exception: it feels kludgy, it's not what views are for,
and it adds to the overhead. Why can't the code that invokes the view
just have an 'except HTTPException:'?  If the user really wants to
register an exception view in order to display a fancy-dancy page,
that's another thing.  It seems like Pyramid should be able to
accommodate both.

HTTP errors *are* exceptions. If you call a support method and it
discovers that a required query parameter is missing, what's it
supposed to do? The request can't continue, so it might as well kill
it right there. That's directly akin to a ZeroDivisionError. 'raise'
has two advantages. One, it shortcuts the call stack so you don't have
to return some dummy value, or define another exception just to catch
it later. Two, 'raise' is a Python keyword so it's syntax-highlighted
and users should be expecting it.

abort() and redirect() are not necessarily the most intuitive but I
can't think of any better API for them. I did use them a lot in Pylons
and I miss them a bit in Pyramid.  They do have the disadvantage that
they look like normal returning function calls instead of having that
'raise' keyword. 'redirect' is particularly useful because it's not
intuitive that 'HTTPFound' means I'm doing a redirect. If you see it
often you get used to it, but otherwise it's like, Oh, nice, it found
something. That doesn't tell me what it's going to do with it. I
think that's a shortcoming of the HTTP status: it should have been
called 'Redirect' rather than 'Found'.

BTW, I mentioned a few days ago that my application is displaying a
blank page when I return HTTPNotFound or HTTPBadRequest, so something
is missing somewhere. The HTTP status is right but the body is empty,
no Not Found or anything.

-- 
Mike Orr sluggos...@gmail.com

-- 
You received this message because you are subscribed to the Google Groups 
pylons-devel group.
To post to this group, send email to pylons-devel@googlegroups.com.
To unsubscribe from this group, send email to 
pylons-devel+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/pylons-devel?hl=en.



Re: route_url _query None value behavior

2011-05-26 Thread Chris McDonough
On Tue, 2011-05-24 at 18:22 -0700, Jerry wrote:
 Thanks Mike.
 
 Chris, so how about this to offload some work from the template/helper
 --
 
 if v is not None:
 v = quote_plus(str(v))
 result += '%s%s=%s' % (prefix, k, v)

That's probably fine.  It will need tests and docs.  The right place to
submit it is via a github pull request.

- C


 
 Jerry
 
 On May 25, 12:02 am, Mike Orr sluggos...@gmail.com wrote:
  webhelpers.util.update_params deletes any parameter with a value of
  None. Mako templates converts None values to ''. Having None convert
  to None is almost never useful in query parameters, while having
  integers and other types converted to strings is useful. So that all
  argues for trapping None and either converting it to '' or deleting
  the parameter.
 
 
 
 
 
 
 
 
 
  On Sat, May 21, 2011 at 7:39 PM, Chris McDonough chr...@plope.com wrote:
   Don't think this is really right if you consider the desire to be able
   to pass integers (like 0), which others have requested before.
 
   What precedent is there to passing the value None being converted to
   empty string?
 
   - C
 
   On Sat, 2011-05-21 at 18:35 -0700, Jerry wrote:
   Google group messes with the formatting, which should have been --
 
   else:
   if v.__class__ is unicode:
   v = v.encode('utf-8')
   if v:
   v = quote_plus(str(v))
   result += '%s%s=%s' % (prefix, k, v)
   else:
   result += '%s%s=' % (prefix, k)
 
   Jerry
 
   On May 22, 9:32 am, Jerry jerryji1...@gmail.com wrote:
Hi,
 
Pyramid's route_url/route_path behavior with None _query terms doesn't
seem very canonical to me --
 
(Pdb) request.route_path('home', _query=[('q', None)])
'/home?q=None'
 
Omitting value is more like it --
 
(Pdb) request.route_path('home', _query=[('q', '')])
'/home?q='
 
so is omitting both --
 
(Pdb) request.route_path('home', _query=[('q', [])])
'/home?'
 
Chris and other Pyramid maintainers: would you consider adding this
simple check to urlencode() in pyramid/encode.py ? --
 
 89 for (k, v) in query:
 90 if k.__class__ is unicode:
 91 k = k.encode('utf-8')
 92 k = quote_plus(str(k))
 93 if hasattr(v, '__iter__'):
 94 for x in v:
 95 if x.__class__ is unicode:
 96 x = x.encode('utf-8')
 97 x = quote_plus(str(x))
 98 result += '%s%s=%s' % (prefix, k, x)
 99 prefix = ''
100 else:
101 if v.__class__ is unicode:
102 v = v.encode('utf-8')
   if v:
103 v = quote_plus(str(v))
104 result += '%s%s=%s' % (prefix, k, v)
   else:
   result += '%s%s=' % (prefix, k)
105 prefix = ''
 
Thanks.
 
Jerry
 
   --
   You received this message because you are subscribed to the Google Groups 
   pylons-devel group.
   To post to this group, send email to pylons-devel@googlegroups.com.
   To unsubscribe from this group, send email to 
   pylons-devel+unsubscr...@googlegroups.com.
   For more options, visit this group 
   athttp://groups.google.com/group/pylons-devel?hl=en.
 
  --
  Mike Orr sluggos...@gmail.com
 


-- 
You received this message because you are subscribed to the Google Groups 
pylons-devel group.
To post to this group, send email to pylons-devel@googlegroups.com.
To unsubscribe from this group, send email to 
pylons-devel+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/pylons-devel?hl=en.



Re: Pyramid 2 Brainstorm Marrow

2011-05-26 Thread Alice Bevan–McGregor

Howdy!

On 2011-05-25 14:50:58 -0700, Mike Orr said:

Alice, thank you for correcting any misconceptions about Marrow, and 
for documenting it on the Brainstorm page for future reference. I 
apologize if I've made any mischaracterizations, either from reading 
something that was false or interpreting it wrongly.


No worries!  Besides, if something isn't documented properly or gives 
the wrong impression, that's more my fault than anything else.


The Marrow suite looks like a well-thought-out, pythonic collection of 
services. As such, it definitely serves as an example of one way 
Pyramid could handle things in the future. It'll be several months 
before we make any definite decision though.


Of course.  Following the Zen, *right now* is rarely a good idea.  ;)

As you know, a few people are advocating various approaches for 
replacing Paste*, PasteHTTPServer and the INI file. In the next few 
months they'll be releasing them and writing HOWTOs for them. If you 
feel like it, a HOWTO for adding Marrow enhancements to a typical 
Pyramid or Akhet application would be welcome.


Somewhat difficult to write HOWTO's for a framework I don't currently 
use.  :P  I'll see what can be done, however, as upcoming employment 
does make use of Pyramid, which should give me a better 'working grasp' 
of how to integrate my Marrow packages.


I took a quick look at the Marrow parser both for Pyramid and for my 
standalone utilities. My command-line options tend to have complex 
specifications and interactions, and they don't always correspond 
directly to function arguments.


I would love to see some examples of complex interactions.  If one of 
your requirements are options that are only made available if another 
option is enabled/defined, that's on the roadmap.  :)  Also, 
sub-commands (hg/git style) are already supported in head using classes 
instead of bare functions.


Perhaps if I thought more about it, they could. But the magic in the 
decorators is not something I need, even if others find it desirable.


The decorators I used are adding a py3k feature to 2.x.  Python 3 
already includes a method for adding 'hinting' information to 
arguments.  These decorators are actually the examples given in the 
decorator PEP!  :D


Argparse does what it does reasonably well; I have not yet gotten sick 
enough of it to jettison it.


For sure there is no point taking an existing working solution and 
throwing it to the wind to re-engineer it under a different parser.  
Marrow.script is primarily targeted at people who either have an 
existing callable (class/method) they want to expose as a command-line 
script, or for those who want to write really, really fast one-off 
scripts.


OTOH it could greatly simplify the paster scripts I have thus far come 
across in the wild.


For Pyramid, the developers seem to prefer conservative innovation. 
Make incremental improvements, but not too radical. Obviously, Pyramid 
is a radical departure from Pylons 1, but that's an occasional paradigm 
shift akin to Python 3; it's not typical for all Pyramid/Pylons 
development.


Despite optional ZCML and the use of ZCA, Pyramid isn't, in my mind, 
such a drastic departure from existing frameworks.  Traversal (pre- 
view lookup) is limited object dispatch using __getitem__ instead of 
__getattr__.  Woot.  ;P  The Paste components are identical, Beaker and 
SA are popular, etc.  For people migrating from TurboGears/Pylons or 
any other framework derived from Paste, things should be /relatively/ 
comfortable.


When Python makes a language change, the criteria is, Is it obviously 
the best way? Do the advantages significantly outweigh the bother of 
changing?  Both for the users and for the developers? It takes time 
for everybody to try out new libraries, and for a consensus to form 
that one of them is obviously the best way and is a significant 
advantage.


I see it as less of a technological best solution war than a 
marketing one.  WebCore has been API stable for a year and a half and 
critical bug-free for a year.  Over 50 commercial projects have been 
created and launched using it, spread between three primary users in as 
many countries.  Why hasn't it caught on with other users?  For the 
most part, no-one knows it exists despite my view that it trounces 
other frameworks in simplicity, usability, and performance.  (And uses 
the exact same underlying Paste, WebOb, Beaker, SA, etc. stack w/ only 
~300 lines of glue.)


What one might consider best is purely subjective, which is 
unfortunate from a let's make a standard perspective.  Advantage and 
disadvantage comparison is also rather subjective.  Hell, Django 
decided to forego any external reusable dependencies…


Yes, those are a few of the problems with Paste*. But we (Pyramid) need 
to stop and think awhile about what we want to replace it with.


I'd love to see a wiki page for each of these things with discussion, 
requirements exploration, and pros/cons of different 

Re: Pyramid 2 Brainstorm Marrow

2011-05-26 Thread Alice Bevan–McGregor

Howdy!

On 2011-05-26 16:11:45 -0700, Mike Orr said:

On the other hand, those who are already using Argparse may find Marrow 
unnecessary...


There are always alternate parsers and the option to do it by hand.  
Also, please ensure you mention a specific Marrow package rather than 
the entire suite.  (Like refering to Repoze when you actually mean 
repoze.who.)



...too magic...


Python's introspection features, while 'advanced', are well known.


...and something else to learn.


Actually, the point of m.script is that there isn't anything else to 
learn.  If you can write a function, you can write a command-line 
script.  The two lines of boilerplate to tie your function to m.script 
are unchanging and documented.


But Pyramid is a different situation than either of these. The main 
function in a pyramid application is: [snip]


That main function relies on upstream configuration loading support.  
As such, that function isn't the one you'd wrap in m.script.  You'd 
wrap the command that loads the configuration.



main(global_conf=None, **local_conf):


The above becomes:

main(config, log=None, verbose=False, quiet=False, ...)

Where config would be the first required positional argument of the 
script, generally the name of an INI file.  If you wanted to do 
something advanced like Paster, where the configuration can be passed 
as STDIN by executing the INI as a shell script, you'd need to add a 
few lines of code before the m.script boilerplate to determine if STDIN 
is readable.


Replacing the functionality of PasteDeploy (the paster script 
configuration parsing) was not the goal of m.script; m.script is just 
command-line parsing.  An additional component, marrow.config, will 
include a m.script-powered command-line script to process YAML 
configurations in a similar way to PasteDeploy, but I'm still 
meditating on the exact feature set and implementation.



What Paste mainly does is to convert an INI file like this: [snip]


Yup; m.config is the domain for that, not m.script.

I can see your point. It's just that it's not a case of Pyramid 
choosing between alternatives it knows it needs. It's a case of you 
promoting an alternative that Pyramid isn't sure it needs, so it wants 
to make sure it does need it before putting a lot of time into it.


Indeed.  I'll be using the Marrow suite regardless.  ;)

Have a great night,

— Alice.

P.s. apologies if the last bit of my previous response sounded too 
snippy; it was not intentional.



--
You received this message because you are subscribed to the Google Groups 
pylons-devel group.
To post to this group, send email to pylons-devel@googlegroups.com.
To unsubscribe from this group, send email to 
pylons-devel+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/pylons-devel?hl=en.



Re: Pyramid 2 Brainstorm Marrow

2011-05-26 Thread Mike Orr
On Thu, May 26, 2011 at 3:39 PM, Alice Bevan–McGregor
al...@gothcandy.com wrote:
 Unfortunately, the majority of the Marrow projects that could
 benefit Pyramid would require core changes, thus a fork and a number of
 branches to explore the options, not just add-on packages or adaptive
 HOWTOs.

In that case, what might be better than a HOWTO is an outline of how
the packages could be integrated. I.e., which specific parts of
Pyramid would interface with which parts of the Marrow suite. If you
need help analyzing the Pyramid side, i may be able to help with that
; i.e., looking under the surface in Pyramid and what design
requirements it has at that particular point.

-- 
Mike Orr sluggos...@gmail.com

-- 
You received this message because you are subscribed to the Google Groups 
pylons-devel group.
To post to this group, send email to pylons-devel@googlegroups.com.
To unsubscribe from this group, send email to 
pylons-devel+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/pylons-devel?hl=en.