Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is format() throwing ValueError: Unknown format code 'f' for object of type 'str' when I'm not inputting a string?

I am using Python 2.7. (Switching to Python 3 for this particular code is not an option, please don't suggest it.) I am writing unit tests for some code.

Here is the relevant piece of code:

class SingleLineGrooveTable:
  VEFMT = '.3f'

  @classmethod
  def formatve(cls, value, error=None):
    er = 0
    if error is not None:
      er = error
      v = value
    elif len(value) > 1:
      v, er = value
    else:
      v = value
    return format(v, cls.VEFMT), format(er, cls.VEFMT)

and my test is:

import unittest

class TestSingleLineGrooveTable(unittest.TestCase):
  
  def test_formatve_no_error(self):
    e_v = '3.142'
    e_er = '0.000'
    r_v, r_er = SingleLineGrooveTable.formatve([3.1423])
    self.assertEqual(e_v, r_v)
    self.assertEqual(e_er, r_er)

(Yes, I know it's funny I'm getting an error on the test with "no_error" in the name...)

When I run the test, it throws ValueError: Unknown format code 'f' for object of type 'str' on the return statement for the function. But I can't figure out where it's getting a str from. Possibly relevant, this code and the code I have that uses it were copied pretty much wholesale from someone else's code (who I can no longer contact), so maybe I'm calling it in the wrong way, but still, that's a list, not a string!

What is going on here? How do I fix this?

like image 288
Réka Avatar asked Jan 22 '26 12:01

Réka


2 Answers

On Python 2, object.__format__ effectively delegates to format(str(self), format_spec). You can see the implementation here.

Since list inherits object.__format__, your first format call is effectively calling format(str([3.1423]), '.3f'). That's why you get the error message you do.

This would still produce an error on Python 3. It'd just be a different error.

like image 79
user2357112 supports Monica Avatar answered Jan 25 '26 01:01

user2357112 supports Monica


Try this code

class SingleLineGrooveTable:
    VEFMT = '.3f'

    @classmethod
    def formatve(cls, value, error=None):
        er = 0
        if error is not None:
            er = error
            v = value
        elif len(value) > 1:
            v, er = value
        else:
            v = value[0]  # Extract the float from the list
        return format(v, cls.VEFMT), format(er, cls.VEFMT)

import unittest

class TestSingleLineGrooveTable(unittest.TestCase):
  
    def test_formatve_no_error(self):
        e_v = '3.142'
        e_er = '0.000'
        r_v, r_er = SingleLineGrooveTable.formatve([3.1423])
        self.assertEqual(e_v, r_v)
        self.assertEqual(e_er, r_er)

if __name__ == '__main__':
    unittest.main()
like image 32
pgksunilkumar Avatar answered Jan 25 '26 03:01

pgksunilkumar



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!