OK, I have a solution: if I patch the function 

  render_view(context, request, name='', secure=True)

in my .../pyramid-1.3.2-py3.2.egg/pyramid/view.py file
by replacing

  return ''.join(iterable)

at the end with the following if-then-else code

  if isinstance(iterable[0], str):
      return ''.join(iterable)
  else:
      return b''.join(iterable)

then everything works as expected, but I'd certainly not
want to do this forever / would very much appreciate, if
someone could have a closer look at the problem.

-Andreas


Andreas Reuleaux <[email protected]> writes:

> OK, not having gotten any feedback, I guess my problem description was
> to vague.
>
> I have therefore prepared a little sample program, that should be easy
> to extract and run from this e-mail: when running it with python2 I have
> no problems, when running it with python3 I get the aforementioned byte
> vs. string problems (also shown below once more).
>
> While I roughly know, what has changed between python2 and python3
> concerning strings/bytes, I am kind of stuck in this situation: I don't
> know what to do in this case and I would hope that someone will try out
> this sample program and point me in the right direction.
>
> To make the installation experience easier, I have avoided to use to
> many different python/configuration files: the whole program lives in
> one file sample.py, which make use of a couple of templates.
>
> To try out the program, you should therefore extract from this e-mail
>
> * the file sample.py
>
> * as well as the templates page.pt, home.pt, other.pt, and notfound.pt
>   (note that only page.pt is a complete html page, the others are
>   just html snippets)
>
> steps to install/run the program on python2
>
> create the environment
> $ virtualenv foo
> $ cd foo
> $ ./bin/easy_install pyramid
> $ ./bin/easy_install pyramid_viewgroup
>
> copy the python script and the page templates to your foo env
> $ cp .../simple.py .
> $ cp .../page.pt .
> $ cp .../home.pt .
> $ cp .../other.pt .
> $ cp .../notfound.pt .
>
> adjust the path to the templates in simple.py, like
> path=os.path.dirname('/path/to/my/foo/')
>
> start the server
> $ ./bin/python simple.py -port 8080
>
> and have a look at some pages
> http://myserver:8080/home
> http://myserver:8080/other
> http://myserver:8080/whatever - not found!
> http://myserver:8080/         - default view
>
> (see the explanations below, what's going on under the hood.)
>
> --
> now do the same with python3
>
> create the environment
> $ virtualenv-3.2 bar3
> $ cd bar3
> $ ./bin/easy_install-3.2 pyramid
> $ ./bin/easy_install-3.2 pyramid_viewgroup
>
> copy the simple.py script and the page templates as above,
> and adjust the path to the templates
>
> start the server with
> $ ./bin/python3 simple.py -port 8080
>
> and have a look at some pages as above.
>
> While http://myserver:8080/, the default view renders fine,
> as soon as I look at some of the other pages: home, other, whatever (not 
> found)
> I get 
>
> File 
> "/home/reuleaux/tmp/bar3/lib/python3.2/site-packages/pyramid-1.3.2-py3.2.egg/pyramid/view.py",
>  line 139, in render_view
>     return ''.join(iterable)
> TypeError: sequence item 0: expected str instance, bytes found
>
>  - Expression: "provider('content')"
>  - Filename:   None
>  - Location:   (24:33)
>  - Source:     ... l:replace="structure provider('content')">page 
> content</div>
>                                         ^^^^^^^^^^^^^^^^^^^
>  - Arguments:  repeat: {...} (0)
>                renderer_name: /home/reuleaux/tmp/bar3/page.pt
>                req: <NoneType - at 0x84bf40>
>                request: <NoneType - at 0x84bf40>
>                provider: <Provider - at 0x28059d0>
>                renderer_info: <RendererHelper - at 0x2805a10>
>                context: <Home - at 0x2805a50>
>                escape: False
>                view: <NoneType - at 0x84bf40>
> 192.168.1.7 - - [21/Jul/2012 01:58:49] "GET /home HTTP/1.1" 500 59  
>
> As mentioned before: I am lost in this case, any help is appreciated.
>
> Some explanations of what's going on in the python2 case / 
> how it is supposed to work:
>
> While viewlets/content providers are not everyone's preferred style,
> I have used them here to assemble some pages from building blocks
> e. g. my home page looks just like this:
>
>   @implementer(IPage)
>   class Home(object):
>       content=HomeContent()
>       title='Home'
>
> I. e. it is a page (implements IPage), and its contents is just
> the home content.
>
> Another page, Other, is very similar, but has of course some other
> content:
>
>   @implementer(IPage)
>   class Other(object):
>       content=OtherContent()
>       title='Other'
>
> I have used traversal to find those objects, e. g.
>   
>   http://myserver:port/home
>
> will render Home, .../other will render Other and so on
>
> The views operate just on the interfaces IPage, IContent,
> i. e. view_page can render any page, and will make use of
> view_content to fill in / show the content provided for
> this particular page.
>
>
> Anyway, thanks for reading, and thanks in advance for trying out.
>
>
> -Andreas
>
>
> simple.py
> --------------------------------------------------
> from wsgiref.simple_server import make_server
> from pyramid.config import Configurator
> from pyramid.response import Response
>
> from pyramid_viewgroup import Provider
>
> from pyramid.renderers import render_to_response
>
> import sys
> import os
>
> import argparse
>
>
> opts=None
>
>
> # path = os.path.dirname('/home/reuleaux/tmp/foo/')
> path = os.path.dirname('/home/reuleaux/work/website/py3/')
>
>
>
> from zope.interface import Interface, implementer
>
>
> class IContent(Interface):
>     pass
>
>
> class IPage(Interface):
>     pass
>
>
> @implementer(IContent)
> class HomeContent(object):
>     msg="hi from home"
>     tmplt=os.path.join(path, 'home.pt')
>
>
> @implementer(IPage)
> class Home(object):
>     content=HomeContent()
>     title='Home'
>
>
> @implementer(IContent)
> class OtherContent(object):
>     msg="hi from other"
>     tmplt=os.path.join(path, 'other.pt')
>     
>
> @implementer(IPage)
> class Other(object):
>     content=OtherContent()
>     title='Other'
>
>
> @implementer(IContent)
> class NotFoundContent(object):
>     tmplt=os.path.join(path, 'notfound.pt')
>     msg="not found!"
>     
>
> @implementer(IPage)
> class NotFound(object):
>     content=NotFoundContent()
>     title='not found'
>
>
>
> app={
>     'home': Home,
>     'other': Other,
>     }
>
>
> @implementer(IPage)
> class App(object):
>     def __getitem__(self, name):
>         return app.get(name, NotFound)()
>     
>
> class Root(object):
>     def __init__(self, request):
>         self.request = request
>     
>     def __getitem__(self, name=None):
>         if name in ['static', 
>                     ]:
>             raise KeyError
>         else:
>             return App()[name]
>         
>
>
>
> def default_view(request):
>     return Response('Hello world!')
>
>
>
>
>
> def content_view(request):
>     content=getattr(request.context, 'content', None)
>
>     if hasattr(content, 'tmplt'):
>         return render_to_response(content.tmplt,
>                                   { },
>                               )
>     else:
>         return Response('<span class="mark">content</span>')
>
>
> def page_view(request):
>     context=request.context
>     provider=Provider(context, request)
>     return render_to_response(
>         os.path.join(path, 'page.pt'),
>         {
>             'provider': provider,
>             'context': context,
>         },
>     )
>    
>
>
>
> def parser():
>
>     parser=argparse.ArgumentParser()
>     
>     parser.add_argument("-port", 
>                         '--port', 
>                         dest="port",
>                         action="store",
>                         default=6543,
>                         help="port")
>
>     return parser
>
>
> def run(args):
>     
>     p=parser()
>     global opts
>     opts = p.parse_args(args)
>     # print(opts)
>
>     config = Configurator(root_factory=Root)
>
>
>     config.add_view('.default_view',)
>     
>     config.add_view('.page_view',
>                     context='.IPage',)
>
>         
>     config.add_view('.content_view',
>                     name='content',
>                     context='.IPage',)
>
>
>     app = config.make_wsgi_app()
>     server = make_server('0.0.0.0', int(opts.port), app)
>     server.serve_forever()
>
>
> if __name__ == '__main__':
>    run(sys.argv[1:])
> --------------------------------------------------
>
>
>
>
>
> page.pt
> --------------------------------------------------
> <?xml version="1.0" encoding="utf-8"?>
>
> <html xmlns="http://www.w3.org/1999/xhtml";
>       xmlns:tal="http://xml.zope.org/namespaces/tal";
>       >
>   <head>
>     <title>${context.title}</title>
>     
>     <style type="text/css"
>            media="screen">
>       .mark  { 
>       font-weight: bold;
>       font-style: italic;
>       } 
>     </style>
>     
>
>   </head>
>   <body>
>      <p>any page will have this structure</p>
>
>      <p>and here comes the content:</p>
>
>      <div tal:replace="structure provider('content')">page content</div>
>
>      <p>rest of the page...</p>
>
>   </body>
> </html>
> --------------------------------------------------
>
>
>
>
> home.pt
> --------------------------------------------------
> <div
>     xmlns:tal="http://xml.zope.org/namespaces/tal";
>     tal:omit-tag=""
>     >
>
>   
>   <p>
>     this is my <span class="mark">home page</span>...
>   </p>  
>
>
> </div>
> --------------------------------------------------
>
>
>
>
>
> other.pt
> --------------------------------------------------
> <div
>     xmlns:tal="http://xml.zope.org/namespaces/tal";
>     tal:omit-tag=""
>     >
>
>
>   <p>  
>     this is my <span class="mark">other page</span>
>   </p>
>   
>
> </div>
> --------------------------------------------------
>
>
>
>
> notfound.pt
> --------------------------------------------------
> <div
>     xmlns:tal="http://xml.zope.org/namespaces/tal";
>     tal:omit-tag=""
>     >
>
>   Sorry, page not found
>
> </div>
> --------------------------------------------------

-- 
You received this message because you are subscribed to the Google Groups 
"pylons-discuss" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/pylons-discuss?hl=en.

Reply via email to