Skip to content

VersionField and SpecField shouldn't accept strings, only Version / Spec objects. #97

Open

Description

@ejosan

problem

running get_or_create twice will result in the first run to fail and the second to pass

the model

from django.db.models import Model
from semantic_version.django_fields import VersionField
class SemVersion(Model):
    version = VersionField(max_length=200)

test script

# -*- coding: utf-8 -*-
# from __future__ import absolute_import, unicode_literals, print_function
import unittest
import django
django.setup()
from apps.version.models import SemVersion

class SemverTest(unittest.TestCase):

    def test_one(self):
        obj1,_ = SemVersion.objects.get_or_create(version='0.1.1+build')
        print(obj1)
        print(obj1.version.major)
        print(obj1.version.minor)
        print(obj1.version.patch)
        print(obj1.version.prerelease)
        print(obj1.version.build)

if __name__ == '__main__':
    suite = unittest.TestSuite()
    suite.addTest(SemverTest('test_one'))

    result = unittest.TextTestRunner(verbosity=2, resultclass=unittest.TextTestResult).run(suite)

output first run:

test_one (__main__.SemverTest) ... SemVersion object
ERROR

======================================================================
ERROR: test_one (__main__.SemverTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/ONT/user/apps/version/tests/test.py", line 20, in test_one
    print(obj1.version.major)
AttributeError: 'str' object has no attribute 'major'

----------------------------------------------------------------------
Ran 1 test in 0.022s

FAILED (errors=1)

output second run:

test_one (__main__.SemverTest) ... SemVersion object
0
1
1
()
('build',)
ok

----------------------------------------------------------------------
Ran 1 test in 0.015s

OK

looks like the the create part of get_or_create returns not an object but a string, the second time get_or_create is run the get part kicks in and returns a correct version object. This is inconsistent and should work. Tested it with python 3.6 and 2.7 both same results. Django 1.11.15

Activity

  1. added
    Status:CodeWelcomeThis feature design has been approved; next step: write the code!
    Topic:DjangoIssues related to Django integration
    on Jul 7, 2020
  2. rbarrois commented on Jul 7, 2020

    @rbarrois
    Owner

    Thanks for the report! That's indeed a bug, likely because Django's get_or_create returns the value as is.

  3. added a commit that references this issue on Jul 7, 2020
  4. rbarrois commented on Jul 7, 2020

    @rbarrois
    Owner

    After taking a deeper look, it seems to be a standard behaviour from Django: if the developer provides a badly-typed-but-coercable value, it might be used properly by the database, but the value on the model won't be changed.

    This is, unfortunately, not properly documented in Django.

    Here are a couple of links on that topic:

    Basically, a VersionField shouldn't accept a string, only a Version object; that's the bug ;)

  5. changed the title [-]SemVersion.objects.get_or_create invalid behaviour[/-] [+]VersionField and SpecField shouldn't accept strings, only `Version` / `Spec` objects.[/+] on Jul 7, 2020
  6. ejosan commented on Jul 8, 2020

    @ejosan
    Author

    After taking a deeper look, it seems to be a standard behaviour from Django: if the developer provides a badly-typed-but-coercable value, it might be used properly by the database, but the value on the model won't be changed.

    This is, unfortunately, not properly documented in Django.

    Here are a couple of links on that topic:

    Basically, a VersionField shouldn't accept a string, only a Version object; that's the bug ;)

    ;-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Status:CodeWelcomeThis feature design has been approved; next step: write the code!Topic:DjangoIssues related to Django integrationType:Bug

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions