~cjwatson/storm/py3-strings

« back to all changes in this revision

Viewing changes to tests/variables.py

  • Committer: Colin Watson
  • Date: 2019-08-11 16:57:24 UTC
  • Revision ID: cjwatson@canonical.com-20190811165724-y99252clnw75z4ut
Update string handling for Python 3.

This is inspired by work done by Thiago Bellini.  I've taken a different
approach in a few areas which are useful to discuss briefly here (and some
of this should end up in release notes):

 * I generally wrote "bytes" rather than "six.binary_type", since it's
   shorter and works in all supported versions of Python.

 * In the SQLite backend, there's no need to use memoryview, because the
   sqlite3 module in Python 3 automatically converts between the SQLite BLOB
   type and bytes.

 * Some exception messages have changed slightly for clarity.

 * On Python 3, raw=True and token=True in storm.expr.Compile.__call__ only
   treats str specially, not bytes and str, because ultimately the compiler
   is assembling a text string to send to the database.

 * On Python 3, storm.tracer.BaseStatementTracer.connection_raw_execute
   renders text parameters using ascii() rather than by encoding to bytes
   and then calling repr().  While this does result in slightly different
   output from Python 2, it's normally more useful since the encoding is in
   terms of Unicode codepoints rather than UTF-8.

 * storm.sqlobject.AutoUnicodeVariable (and hence StringCol) explicitly
   documents that it only accepts text on Python 3, since native strings are
   already Unicode there so there's much less need for the porting
   affordance.

Show diffs side-by-side

added added

removed removed

Lines of Context:
445
445
        variable = RawStrVariable()
446
446
        variable.set(b"str")
447
447
        self.assertEquals(variable.get(), b"str")
448
 
        variable.set(buffer(b"buffer"))
 
448
        buffer_type = memoryview if six.PY3 else buffer
 
449
        variable.set(buffer_type(b"buffer"))
449
450
        self.assertEquals(variable.get(), b"buffer")
450
451
        self.assertRaises(TypeError, variable.set, u"unicode")
451
452
 
479
480
 
480
481
    def test_get_set_from_database(self):
481
482
        datetime_str = "1977-05-04 12:34:56.78"
482
 
        datetime_uni = unicode(datetime_str)
 
483
        datetime_uni = six.text_type(datetime_str)
483
484
        datetime_obj = datetime(1977, 5, 4, 12, 34, 56, 780000)
484
485
 
485
486
        variable = DateTimeVariable()
492
493
        self.assertEquals(variable.get(), datetime_obj)
493
494
 
494
495
        datetime_str = "1977-05-04 12:34:56"
495
 
        datetime_uni = unicode(datetime_str)
 
496
        datetime_uni = six.text_type(datetime_str)
496
497
        datetime_obj = datetime(1977, 5, 4, 12, 34, 56)
497
498
 
498
499
        variable.set(datetime_str, from_db=True)
557
558
 
558
559
    def test_get_set_from_database(self):
559
560
        date_str = "1977-05-04"
560
 
        date_uni = unicode(date_str)
 
561
        date_uni = six.text_type(date_str)
561
562
        date_obj = date(1977, 5, 4)
562
563
        datetime_obj = datetime(1977, 5, 4, 0, 0, 0)
563
564
 
601
602
 
602
603
    def test_get_set_from_database(self):
603
604
        time_str = "12:34:56.78"
604
 
        time_uni = unicode(time_str)
 
605
        time_uni = six.text_type(time_str)
605
606
        time_obj = time(12, 34, 56, 780000)
606
607
 
607
608
        variable = TimeVariable()
614
615
        self.assertEquals(variable.get(), time_obj)
615
616
 
616
617
        time_str = "12:34:56"
617
 
        time_uni = unicode(time_str)
 
618
        time_uni = six.text_type(time_str)
618
619
        time_obj = time(12, 34, 56)
619
620
 
620
621
        variable.set(time_str, from_db=True)
671
672
 
672
673
    def test_get_set_from_database(self):
673
674
        delta_str = "42 days 12:34:56.78"
674
 
        delta_uni = unicode(delta_str)
 
675
        delta_uni = six.text_type(delta_str)
675
676
        delta_obj = timedelta(days=42, hours=12, minutes=34,
676
677
                              seconds=56, microseconds=780000)
677
678
 
685
686
        self.assertEquals(variable.get(), delta_obj)
686
687
 
687
688
        delta_str = "1 day, 12:34:56"
688
 
        delta_uni = unicode(delta_str)
 
689
        delta_uni = six.text_type(delta_str)
689
690
        delta_obj = timedelta(days=1, hours=12, minutes=34, seconds=56)
690
691
 
691
692
        variable.set(delta_str, from_db=True)
900
901
 
901
902
class JSONVariableTest(EncodedValueVariableTestMixin, TestHelper):
902
903
 
903
 
    encode = staticmethod(lambda data: json.dumps(data).decode("utf-8"))
 
904
    if six.PY3:
 
905
        encode = staticmethod(lambda data: json.dumps(data))
 
906
    else:
 
907
        encode = staticmethod(lambda data: json.dumps(data).decode("utf-8"))
904
908
    variable_type = JSONVariable
905
909
 
906
910
    def is_supported(self):
913
917
        self.assertRaises(TypeError, variable.set, b'"abc"', from_db=True)
914
918
 
915
919
    def test_unicode_to_db(self):
916
 
        # JSONVariable._dumps() works around unicode/str handling issues in
 
920
        # JSONVariable._dumps() works around text/bytes handling issues in
917
921
        # json.
918
922
        variable = self.variable_type()
919
923
        variable.set({u"a": 1})
920
 
        self.assertTrue(isinstance(variable.get(to_db=True), unicode))
 
924
        self.assertTrue(isinstance(variable.get(to_db=True), six.text_type))
921
925
 
922
926
 
923
927
class ListVariableTest(TestHelper):