Warning: Can't synchronize with repository "(default)" (Unsupported version control system "svn": No module named svn). Look in the Trac log for more information.

Ticket #824 (closed defect: fixed)

Opened 13 years ago

Last modified 12 years ago

Number validator not working

Reported by: anonymous Owned by: godoy
Priority: normal Milestone: 1.0b2
Component: TurboGears Version: 0.9a5
Severity: normal Keywords:
Cc:

Description

After upgrading from 0.9a4 to 0.9a5 I encountered the following problem with my project:

Background: In a controller file I have a validator set up as: validators = { "last_sync_date": validators.Number() } and the number supplied was: 1146671186.081156.

When running I got the following error:

Traceback (most recent call last):

File "/Library/Frameworks/Python?.framework/Versions/2.4/lib/python2.4/site-packages/CherryPy-2.2.1-py2.4.egg/cherrypy/_cphttptools.py", line 105, in _run

self.main()

File "/Library/Frameworks/Python?.framework/Versions/2.4/lib/python2.4/site-packages/CherryPy-2.2.1-py2.4.egg/cherrypy/_cphttptools.py", line 254, in main

body = page_handler(*virtual_path, self.params)

File "<string>", line 3, in newFunction File "/Library/Frameworks/Python?.framework/Versions/2.4/lib/python2.4/site-packages/TurboGears-0.9a5-py2.4.egg/turbogears/controllers.py", line 210, in expose

output = database.run_with_transaction(func._expose,func, accept, allow_json, allow_json_from_config,*args, kw)

File "/Library/Frameworks/Python?.framework/Versions/2.4/lib/python2.4/site-packages/TurboGears-0.9a5-py2.4.egg/turbogears/database.py", line 216, in run_with_transaction

retval = func(*args, kw)

File "<string>", line 5, in _expose File "/Library/Frameworks/Python?.framework/Versions/2.4/lib/python2.4/site-packages/TurboGears-0.9a5-py2.4.egg/turbogears/controllers.py", line 230, in <lambda>

func._expose.when(rule)(lambda _func, accept, allow_json, allow_json_from_config,*args,kw: _execute_func(

File "/Library/Frameworks/Python?.framework/Versions/2.4/lib/python2.4/site-packages/TurboGears-0.9a5-py2.4.egg/turbogears/controllers.py", line 251, in _execute_func

output = errorhandling.try_call(func, *args, kw)

File "/Library/Frameworks/Python?.framework/Versions/2.4/lib/python2.4/site-packages/TurboGears-0.9a5-py2.4.egg/turbogears/errorhandling.py", line 71, in try_call

return func(self, *args, kw)

File "/Volumes/Litter? Box/Users?/stodd/Documents/Contracts/Cont@ct/Projects/contact/contact/controllers/group.py", line 22, in newFunction

theItems = [(theKey, validators[theKey].to_python(theDictionary[theKey])) for theKey in theValidationKeys]

File "/Library/Frameworks/Python?.framework/Versions/2.4/lib/python2.4/site-packages/FormEncode-0.5.1-py2.4.egg/formencode/api.py", line 316, in to_python

value = tp(value, state)

File "/Library/Frameworks/Python?.framework/Versions/2.4/lib/python2.4/site-packages/TurboGears-0.9a5-py2.4.egg/turbogears/validators.py", line 57, in _to_python

value = format.parse_decimal(value)

File "/Library/Frameworks/Python?.framework/Versions/2.4/lib/python2.4/site-packages/TurboGears-0.9a5-py2.4.egg/turbogears/i18n/format.py", line 165, in parse_decimal

value = value.replace(get_group_format(locale), "")

AttributeError?: 'float' object has no attribute 'replace'

Is this a bug that was introduced in 0.9a5?

If I comment out this validator, everything works as expected.

Change History

comment:1 Changed 13 years ago by godoy

The Number validator was officially changed in 0.9a5, indeed. Before you got exactly the same version as in formencode.validators.Number.

I haven't seen this bug in my tests -- I changed the validator to allow I18Nization of numbers, since we're worried with a global community...

The error, though, seems to come from parse_decimal, code that already existed before in TG.

From the logic viewpoint -- I haven't gone into the code yet -- what should get to this point is a string / unicode object.

Is the above the only validator you have in place?

comment:2 Changed 13 years ago by godoy

This works here. Can you try the same sequence at an interactive interpreter, please?

>>> from turbogears import validators
>>> string = "1146671186.081156"
>>> validator = validators.Number()
>>> validator.to_python(string)
1146671186.081156
>>> validator.from_python(validator.to_python(string))
u'1,146,671,186.08'
>>>

As you can see, it is formatted to use en_US locale by default.

comment:3 Changed 13 years ago by anonymous

In answer to your first question: No, I have other validators as well. I didn't include them to keep things simple. In my controller file I have a class:

class GroupAPIController(GroupController):

    validators = {
        "group_id": validators.Int(),
        "member_id": validators.Int(),
        "group_name": validators.String(),
        "owner_name": validators.String(),
        "joining": validators.Int(),
        "abcard_id": validators.Int(),
        "change": validators.String(),
        "last_sync_date": validators.Number(),
        "date": validators.Number()
        }

    <snip>

    @turbogears.expose(format='json', allow_json=True)
    @JSON_INPUT(validators = validators)
    def changedContactIDs(self, last_sync_date):
        """
        returns list of changed contact ids for all the groups to which the owner belongs
        """
        theChangedContactIDs = []
        theUser = self.CurrentUser()
        theGroups = theUser.groups
        for theGroup in theGroups:
            theContacts = theGroup.abCards
            for theContact in theContacts:
                print "group ", theGroup.name, " has abcard with id: ", theContact.id
                theModDate = theContact.changeDate
                print "mod date: ", theModDate, " last sync date: ", last_sync_date
                if theModDate > last_sync_date:
                    print "sending abcard id: ", theContact.id
                    theChangedContactIDs.append(theContact.id)
        return dict(contact_ids=theChangedContactIDs)

    <other stuff>

Basically, I am using a Cocoa client app to interact with the server using JSON. The other validators seem to work as they did before with no problems.

As to your second question: I entered the same sequence into an interactive interpreter and got the same results as shown in your response.

comment:4 Changed 13 years ago by godoy

  • Owner changed from anonymous to godoy

So, there's no problem with the validator itself. It is somewhere else either in your code or in new code in Turbogears. We have to find where ;-)

Could it be something wrong with your JSON_INPUT() decorator? What happens if you use @turbogears.validate() to validate input, does it work?

comment:5 Changed 13 years ago by anonymous

I changed the method decorators to:

@turbogears.expose(format='json', allow_json=True)
@JSON_INPUT(validators = validators)
@turbogears.validate(validators = validators)
def changedContactIDs(self, last_sync_date):

This change produced the following output:

2006-05-09 09:38:02,007 cherrypy.msg INFO HTTP: Page handler: <bound method GroupAPIController.newFunction of <contact.controllers.group.GroupAPIController object at 0x142bed0>> Traceback (most recent call last):

File "/Library/Frameworks/Python?.framework/Versions/2.4/lib/python2.4/site-packages/CherryPy-2.2.1-py2.4.egg/cherrypy/_cphttptools.py", line 105, in _run

self.main()

File "/Library/Frameworks/Python?.framework/Versions/2.4/lib/python2.4/site-packages/CherryPy-2.2.1-py2.4.egg/cherrypy/_cphttptools.py", line 254, in main

body = page_handler(*virtual_path, self.params)

File "<string>", line 3, in newFunction File "/Library/Frameworks/Python?.framework/Versions/2.4/lib/python2.4/site-packages/TurboGears-0.9a5-py2.4.egg/turbogears/controllers.py", line 210, in expose

output = database.run_with_transaction(func._expose,func, accept, allow_json, allow_json_from_config,*args, kw)

File "/Library/Frameworks/Python?.framework/Versions/2.4/lib/python2.4/site-packages/TurboGears-0.9a5-py2.4.egg/turbogears/database.py", line 216, in run_with_transaction

retval = func(*args, kw)

File "<string>", line 5, in _expose File "/Library/Frameworks/Python?.framework/Versions/2.4/lib/python2.4/site-packages/TurboGears-0.9a5-py2.4.egg/turbogears/controllers.py", line 230, in <lambda>

func._expose.when(rule)(lambda _func, accept, allow_json, allow_json_from_config,*args,kw: _execute_func(

File "/Library/Frameworks/Python?.framework/Versions/2.4/lib/python2.4/site-packages/TurboGears-0.9a5-py2.4.egg/turbogears/controllers.py", line 251, in _execute_func

output = errorhandling.try_call(func, *args, kw)

File "/Library/Frameworks/Python?.framework/Versions/2.4/lib/python2.4/site-packages/TurboGears-0.9a5-py2.4.egg/turbogears/errorhandling.py", line 71, in try_call

return func(self, *args, kw)

File "/Volumes/Litter? Box/Users?/stodd/Documents/Contracts/Cont@ct/Projects/contact/contact/controllers/group.py", line 23, in newFunction

theItems = [(theKey, validators[theKey].to_python(theDictionary[theKey])) for theKey in theValidationKeys]

File "/Library/Frameworks/Python?.framework/Versions/2.4/lib/python2.4/site-packages/FormEncode-0.5.1-py2.4.egg/formencode/api.py", line 316, in to_python

value = tp(value, state)

File "/Library/Frameworks/Python?.framework/Versions/2.4/lib/python2.4/site-packages/TurboGears-0.9a5-py2.4.egg/turbogears/validators.py", line 57, in _to_python

value = format.parse_decimal(value)

File "/Library/Frameworks/Python?.framework/Versions/2.4/lib/python2.4/site-packages/TurboGears-0.9a5-py2.4.egg/turbogears/i18n/format.py", line 165, in parse_decimal

value = value.replace(get_group_format(locale), "")

AttributeError?: 'float' object has no attribute 'replace'

So, it appears that there was a change in to_python/_to_python/parse_decimal sequence.

FYI, I inherited the code for JSON_INPUT which is as follows:

def JSON_INPUT(validators = {}):
	def decorator(fn):
		def newFunction(self, *args, **vargs):
			if cherrypy.request.headerMap['Content-Type'] == 'text/javascript':
				theBody = cherrypy.request.body.read()
				theDictionary = simplejson.loads(theBody)
	
				theValidationKeys = set(theDictionary.keys()).intersection(set(validators.keys()))
				theItems = [(theKey, validators[theKey].to_python(theDictionary[theKey])) for theKey in theValidationKeys]
				theDictionary.update(dict(theItems))

				theDictionary = dict([(str(theItem[0]), theItem[1]) for theItem in theDictionary.items()])
	
				vargs.update(theDictionary)

			result = fn(self, *args, **vargs)

			return result
	
		return newFunction
	
	return decorator

comment:6 Changed 13 years ago by jorge.vargas

  • Milestone set to 1.0b2

godoy any update on this issue? where u able to reproduce it?

comment:7 Changed 12 years ago by alberto

  • Status changed from new to closed
  • Resolution set to fixed

This should be fixed in [2254].

Please reopen if it isn't.

Alberto

Note: See TracTickets for help on using tickets.