response.meta.keywords of type "map"

55 views
Skip to first unread message

lucas

unread,
Sep 1, 2020, 10:03:28 PM9/1/20
to web2py-users
hello one and all,

its been a while since i've been on here.  that is a good sign for my sites have been working great.  love python and web2py.  ok, so, i'm slowing porting to python 3.8 from 2.7.  still constant on web2py 2.20.4.  do i had some code under a controller that looks like:

response.meta.keywords += (', '+c.keywords if c.keywords else "")

and it errors saying that "TypeError(unsupported operand type(s) for +=: 'map' and 'str')".  after a bit of investigation i found that response.meta.keywords is of type "map" instead of it used to being a string.  i'm obviously concatenating strings above.

what the heck is type "map" and how's that work with keywords?

lucas

lucas

unread,
Sep 2, 2020, 7:52:27 AM9/2/20
to web2py-users
in fact, when i inspect the head of the final html in the browser, w2p doesn't return a string at all, in fact it returns a reference to an object:

<meta name="keywords" content="<map object at 0x7f693a6a98e0>">

villas

unread,
Sep 2, 2020, 10:39:37 AM9/2/20
to web2py-users
I'm not sure what you are doing exactly but you seem to have created a map iterator.  Maybe you could convert that to a list?  You might be able to work with it more easily.  Something like this:  
list( response.meta.keywords )

lucas

unread,
Sep 2, 2020, 11:16:09 AM9/2/20
to web2py-users
very simply, i'm trying to add keywords of type string to the response.meta.keywords, which used to be of type string and now its of type map, which exceptions out as above.

i've also tried appending to the list like "response.meta.keywords.append("some string here")" and I've tried treating like a dictionary like, "response.meta.keywords['variable name'] = "keyword string"" and both blew up with an exception also.  very strange change of response.meta.keywords.

villas

unread,
Sep 2, 2020, 7:07:13 PM9/2/20
to web2py-users
I may have an older version,  but I imagine that response.meta.keywords is still just a string.
It may be  c.keywords  is type map?
I think type map would be an iterator which you can convert to a list.
Once you've used it,  it's gone.

So, did you try something like on e of these?:  
response.meta.keywords =  ', '.join( c.keyword) )  # if it's a list
or
response.meta.keywords =  ', '.join( list( c.keywords)  )  # convert map to a list
or
response.meta.keywords =  ', '.join(  [ i[0] for i in list(c.keyword)] )  # it may be a list of lists

Sorry, but as you can see,  my motto is simply 'try everything until it works'!
You may wish to read up about the map function and iterators if this is a new concept.

lucas

unread,
Sep 2, 2020, 10:58:00 PM9/2/20
to web2py-users

no, i tried all those tests.  when i simply do return BODY(type(response.meta.keywords)) it returns 'map'.

lucas

unread,
Sep 3, 2020, 6:52:07 AM9/3/20
to web2py-users
maybe i didn't explain what happened here.  i've been running web2py on a centos 7.6 server with python 2.7.5.  i created a brand new server with centos 8.2 with python 3.8.0.  both servers are running web2py 2.20.4.  when i copy the application code from the centos 7.6 to the new centos 8.2 and run the code the application excepts out on the response.meta.keywords = "some string" because its of <type 'map'> whereas on the centos 7.6 is of <type 'list'> where the += "some string" appends to the list.

it doesn't make sense because web2py is the same version on both servers and for the object to change type so much is confusing.  and map isn't a real thing in python because when i read about it, it always points to type dict.

lucas

unread,
Sep 3, 2020, 7:14:45 AM9/3/20
to web2py-users
ok, i've tried what you suggested but on response.meta.keywords:

        list(response.meta.keywords).append(', '+c.keywords if c.keywords else "")

which does not except out, but when i view the final html code in the browser, web2py still returns:

<meta name="keywords" content="<map object at 0x7f42e140f9d0>">

on the new centos 8.2 server.  BUT on the old centos 7.6 it returns the proper string of keywords.

villas

unread,
Sep 3, 2020, 8:45:51 AM9/3/20
to web2py-users
If necessary,  update pydal
Explanation:  It sounds like an instance of iteritems is not being converted to python 3 - I think that happens in pydal._compat.py.

If that is not the problem, continue...

Check value of:  type(c.keywords)
Check value of:  print(list(c.keywords))

If  type(c.keywords)  is map, then surely this should work:
response.meta.keywords =  ', '.join( list( c.keywords)  ) 

My idea would be to convert c.keywords to a simple string,  then concatenate it to response.meta.keywords afterwards.

General info:   response.meta is a Storage object which is really just a special web2py dict. 
In other words,  this:  response.meta.keywords = 'my key word string'
would be equivalent to this:  response.meta['keywords'] = 'my key word string'

lucas

unread,
Sep 3, 2020, 12:19:31 PM9/3/20
to web2py-users
so, i did a lot of digging and experimenting.  it came down to adding this line:

    response.meta.keywords = ""

so, i'm guessing instantiating keywords as a string forced it to be of type string.  and i confirmed with the final html in the browser and verified it was outputting the string of keywords and it is.

so, in conclusion, i think there is a bug in 2.20.4 of web2py and that a line of code should be added to instantiate the response.meta.keywords = "" to force it to type string.

Reply all
Reply to author
Forward
0 new messages