On 7/16/13 8:46 PM, Ryan Ollos wrote:
On Tue, Jul 16, 2013 at 11:38 AM, Matevž Bradač <[email protected]> wrote:

On 16. Jul, 2013, at 18:58, Ryan Ollos wrote:

On Mon, Jul 15, 2013 at 3:18 PM, Apache Bloodhound <
[email protected]> wrote:

#579: ProductizedHref fails for dicts as first argument
---------------------------+-----------------------
  Reporter:  olemis        |      Owner:  gjm
      Type:  defect        |     Status:  review
  Priority:  major         |  Milestone:  Release 7
Component:  multiproduct  |    Version:
Resolution:                |   Keywords:  web href
---------------------------+-----------------------
Changes (by olemis):

* owner:  olemis => gjm


Old description:

Productized Href breaks Href contract when dict objects are passed as
first argument. See sample code below

{{{#!py

from trac.web.href import Href
h = Href('/x/y')
p = dict(a=1,b=2,c=3)
h(p)
'/x/y?a=1&c=3&b=2'
from multiproduct.hooks import ProductizedHref
help(ProductizedHref)
help(ProductizedHref)
phref = ProductizedHref(h, 'z')
phref(p)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "multiproduct/hooks.py", line 106, in __call__
    filter(lambda x: args[0].startswith(x), self.STATIC_PREFIXES):
  File "multiproduct/hooks.py", line 106, in <lambda>
    filter(lambda x: args[0].startswith(x), self.STATIC_PREFIXES):
AttributeError: 'dict' object has no attribute 'startswith'
}}}
New description:

Productized Href breaks Href contract when dict objects are passed as
first argument. See sample code below

{{{#!py

from trac.web.href import Href
h = Href('/x/y')
p = dict(a=1,b=2,c=3)
h(p)
'/x/y?a=1&c=3&b=2'
from multiproduct.hooks import ProductizedHref
phref = ProductizedHref(h, 'z')
phref(p)
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
   File "multiproduct/hooks.py", line 106, in __call__
     filter(lambda x: args[0].startswith(x), self.STATIC_PREFIXES):
   File "multiproduct/hooks.py", line 106, in <lambda>
     filter(lambda x: args[0].startswith(x), self.STATIC_PREFIXES):
AttributeError: 'dict' object has no attribute 'startswith'
}}}

--

Comment:

This is what I get now

{{{#!py

from trac.web.href import Href
h = Href('/x/y')
p = dict(a=1,b=2,c=3)
h(p)
'/x/y?a=1&c=3&b=2'
from multiproduct.hooks import ProductizedHref
phref = ProductizedHref(h, 'z')
phref(p)
'z?a=1&c=3&b=2'
}}}

Looks much better, but now that I take a look I'm not sure either of
whether that's the expected behavior. I just tried to fix the error and
stay a bit out of the way wrt semantics. I really only use
`ProductizedHref` in my local testing environment; never in production
(that I recall), so I guess **now** I'm not the right person to comment
on
this subject, beyond my comments above. I'm forwarding this review
request
to gjm . He might have a few ideas.

 From SVN annotate, I see that Jure committed the code we have questions
about in r1453351. Jure, could you help us understand the intended
behavior
of ProductizedHref?
IIRC the ProductizedHref is a wrapper for Href to help with creation of
product-scoped URLs from any environment, be it a global, or another
product.
It's mainly used in the global dashboard's product widgets, so that hrefs
to
product specific milestones, versions etc. are readily available.
(The other use in ProductRequestWithFactory seems obsolete, except in
tests)

Looking at recent fixes from Olemis (#552), it seems that ProductizedHref
may
not be needed anymore and could be removed (from tests as well)?

Ah, thanks. I hadn't looked to see that ProductRequestWithSession isn't
used anywhere either. I will look at removing both ProductizedHref and
ProductRequestWithSession after #552 is applied.

The ProductizedHref is, as Matevz already mentioned, a wrapper that encapsulates global Href and renders either product scoped or global (for PATHS_NO_TRANSFORM, STATIC_PREFIXES) URLs. Creation of ProductizedHref is controlled by ProductRequestWithSession.

Example would be:
> from trac.web.href import Href
> from multiproduct.hooks import ProductizedHref
> global_href = Href('/')
> product_href = ProductizedHref(global_href, '/myproduct')
> product_href.admin(a=2, b=3)
'/admin?a=2&b=3'
> product_href.milestone(a=2, b=3)
'/myproduct/milestone?a=2&b=3'

The use of ProductizedHref should be completely transparent as it's hidden from the code through the ProductRequestFactory ...

Cheers,
Jure

Reply via email to