Skip to content

Commit

Permalink
Remove Python 2 support
Browse files Browse the repository at this point in the history
Restores testing against Django master branch.
  • Loading branch information
jdufresne committed Feb 23, 2019
1 parent fa36187 commit 828e548
Show file tree
Hide file tree
Showing 21 changed files with 58 additions and 125 deletions.
8 changes: 2 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,12 @@ matrix:
env: TOXENV=flake8
- python: 3.7
env: TOXENV=isort
- python: 2.7
env: TOXENV=py27-django111
- python: 3.4
env: TOXENV=py34-django111
- python: 3.5
env: TOXENV=py35-django111
- python: 3.6
env: TOXENV=py36-django111
- python: 3.4
env: TOXENV=py34-django20
- python: 3.7
env: TOXENV=py37-django111
- python: 3.5
env: TOXENV=py35-django20
- python: 3.6
Expand Down
5 changes: 3 additions & 2 deletions CHANGELOG.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
Changelog
=========

UNRELEASED
----------
UNRELEASED 1.0.0
~~~~~~~~~~~~~~~~
* **Backwards incompatible:** Remove support for Python 2.
* Added ``has_changed()`` method to ``taggit.forms.TagField``.

0.24.0 (2019-02-19)
Expand Down
10 changes: 4 additions & 6 deletions docs/conf.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
#
# django-taggit documentation build configuration file, created by
# sphinx-quickstart on Mon May 3 22:22:47 2010.
#
Expand Down Expand Up @@ -38,8 +36,8 @@
master_doc = "index"

# General information about the project.
project = u"django-taggit"
copyright = u"2010-2014, Alex Gaynor and others."
project = "django-taggit"
copyright = "2010-2014, Alex Gaynor and others."

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
Expand Down Expand Up @@ -176,8 +174,8 @@
(
"index",
"django-taggit.tex",
u"django-taggit Documentation",
u"Alex Gaynor",
"django-taggit Documentation",
"Alex Gaynor",
"manual",
)
]
Expand Down
1 change: 0 additions & 1 deletion requirements/test.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
Django>=1.11
coverage
mock
3 changes: 0 additions & 3 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
[metadata]
license-file = LICENSE

[bdist_wheel]
universal = 1

[flake8]
# E501: line too long
ignore = E501
Expand Down
6 changes: 2 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
packages=find_packages(exclude=("tests*",)),
package_data={"taggit": ["locale/*/LC_MESSAGES/*"]},
license="BSD",
python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*",
python_requires=">=3.5",
install_requires=["Django>=1.11"],
classifiers=[
"Development Status :: 5 - Production/Stable",
Expand All @@ -30,13 +30,11 @@
"License :: OSI Approved :: BSD License",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3 :: Only",
],
include_package_data=True,
zip_safe=False,
Expand Down
2 changes: 0 additions & 2 deletions taggit/admin.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from __future__ import unicode_literals

from django.contrib import admin

from taggit.models import Tag, TaggedItem
Expand Down
2 changes: 1 addition & 1 deletion taggit/apps.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from django.apps import AppConfig as BaseConfig
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _


class TaggitAppConfig(BaseConfig):
Expand Down
12 changes: 4 additions & 8 deletions taggit/forms.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,21 @@
from __future__ import unicode_literals

from django import forms
from django.utils import six
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _

from taggit.utils import edit_string_for_tags, parse_tags


class TagWidget(forms.TextInput):
def format_value(self, value):
if value is not None and not isinstance(value, six.string_types):
if value is not None and not isinstance(value, str):
value = edit_string_for_tags(value)

return super(TagWidget, self).format_value(value)
return super().format_value(value)


class TagField(forms.CharField):
widget = TagWidget

def clean(self, value):
value = super(TagField, self).clean(value)
value = super().clean(value)
try:
return parse_tags(value)
except ValueError:
Expand Down
49 changes: 22 additions & 27 deletions taggit/managers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from __future__ import unicode_literals

from operator import attrgetter

from django import VERSION
Expand All @@ -15,16 +13,15 @@
lazy_related_operation,
)
from django.db.models.query_utils import PathInfo
from django.utils import six
from django.utils.text import capfirst
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _

from taggit.forms import TagField
from taggit.models import CommonGenericTaggedItemBase, TaggedItem
from taggit.utils import require_instance_manager


class ExtraJoinRestriction(object):
class ExtraJoinRestriction:
"""
An extra restriction used for contenttype restriction in joins.
"""
Expand All @@ -39,12 +36,10 @@ def __init__(self, alias, col, content_types):
def as_sql(self, compiler, connection):
qn = compiler.quote_name_unless_alias
if len(self.content_types) == 1:
extra_where = "%s.%s = %%s" % (qn(self.alias), qn(self.col))
extra_where = "{}.{} = %s".format(qn(self.alias), qn(self.col))
else:
extra_where = "%s.%s IN (%s)" % (
qn(self.alias),
qn(self.col),
",".join(["%s"] * len(self.content_types)),
extra_where = "{}.{} IN ({})".format(
qn(self.alias), qn(self.col), ",".join(["%s"] * len(self.content_types))
)
return extra_where, self.content_types

Expand All @@ -57,7 +52,7 @@ def clone(self):

class _TaggableManager(models.Manager):
def __init__(self, through, model, instance, prefetch_cache_name):
super(_TaggableManager, self).__init__()
super().__init__()
self.through = through
self.model = model
self.instance = instance
Expand Down Expand Up @@ -101,7 +96,9 @@ def get_prefetch_queryset(self, instances, queryset=None):
.using(db)
.extra(
select={
"_prefetch_related_val": "%s.%s" % (qn(join_table), qn(source_col))
"_prefetch_related_val": "{}.{}".format(
qn(join_table), qn(source_col)
)
}
)
)
Expand Down Expand Up @@ -181,11 +178,11 @@ def _to_tag_model_instances(self, tags):
for t in tags:
if isinstance(t, self.through.tag_model()):
tag_objs.add(t)
elif isinstance(t, six.string_types):
elif isinstance(t, str):
str_tags.add(t)
else:
raise ValueError(
"Cannot add {0} ({1}). Expected {2} or str.".format(
"Cannot add {} ({}). Expected {} or str.".format(
t, type(t), type(self.through.tag_model())
)
)
Expand Down Expand Up @@ -344,7 +341,7 @@ def most_common(self, min_count=None, extra_filters=None):
def similar_objects(self):
lookup_kwargs = self._lookup_kwargs()
lookup_keys = sorted(lookup_kwargs)
qs = self.through.objects.values(*six.iterkeys(lookup_kwargs))
qs = self.through.objects.values(*lookup_kwargs.keys())
qs = qs.annotate(n=models.Count("pk"))
qs = qs.exclude(**lookup_kwargs)
qs = qs.filter(tag__in=self.all())
Expand Down Expand Up @@ -408,7 +405,7 @@ def __init__(

rel = ManyToManyRel(self, to, related_name=related_name, through=self.through)

super(TaggableManager, self).__init__(
super().__init__(
verbose_name=verbose_name,
help_text=help_text,
blank=blank,
Expand Down Expand Up @@ -438,28 +435,26 @@ def deconstruct(self):
"""
Deconstruct the object, used with migrations.
"""
name, path, args, kwargs = super(TaggableManager, self).deconstruct()
name, path, args, kwargs = super().deconstruct()
# Remove forced kwargs.
for kwarg in ("serialize", "null"):
del kwargs[kwarg]
# Add arguments related to relations.
# Ref: https://github.com/jazzband/django-taggit/issues/206#issuecomment-37578676
rel = self.remote_field
if isinstance(rel.through, six.string_types):
if isinstance(rel.through, str):
kwargs["through"] = rel.through
elif not rel.through._meta.auto_created:
kwargs["through"] = "%s.%s" % (
rel.through._meta.app_label,
rel.through._meta.object_name,
kwargs["through"] = "{}.{}".format(
rel.through._meta.app_label, rel.through._meta.object_name
)

related_model = rel.model
if isinstance(related_model, six.string_types):
if isinstance(related_model, str):
kwargs["to"] = related_model
else:
kwargs["to"] = "%s.%s" % (
related_model._meta.app_label,
related_model._meta.object_name,
kwargs["to"] = "{}.{}".format(
related_model._meta.app_label, related_model._meta.object_name
)

return name, path, args, kwargs
Expand All @@ -472,15 +467,15 @@ def contribute_to_class(self, cls, name):
cls._meta.add_field(self)
setattr(cls, name, self)
if not cls._meta.abstract:
if isinstance(self.remote_field.model, six.string_types):
if isinstance(self.remote_field.model, str):

def resolve_related_class(cls, model, field):
field.remote_field.model = model

lazy_related_operation(
resolve_related_class, cls, self.remote_field.model, field=self
)
if isinstance(self.through, six.string_types):
if isinstance(self.through, str):

def resolve_related_class(cls, model, field):
self.through = model
Expand Down
3 changes: 0 additions & 3 deletions taggit/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models


Expand Down
5 changes: 1 addition & 4 deletions taggit/migrations/0002_auto_20150616_2121.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations


Expand All @@ -10,6 +7,6 @@ class Migration(migrations.Migration):

operations = [
migrations.AlterIndexTogether(
name="taggeditem", index_together=set([("content_type", "object_id")])
name="taggeditem", index_together={("content_type", "object_id")}
)
]
15 changes: 5 additions & 10 deletions taggit/models.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
from __future__ import unicode_literals

from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.db import IntegrityError, models, router, transaction
from django.utils.encoding import python_2_unicode_compatible
from django.utils.text import slugify
from django.utils.translation import ugettext, ugettext_lazy as _
from django.utils.translation import gettext, gettext_lazy as _

try:
from unidecode import unidecode
Expand All @@ -15,7 +12,6 @@ def unidecode(tag):
return tag


@python_2_unicode_compatible
class TagBase(models.Model):
name = models.CharField(verbose_name=_("Name"), unique=True, max_length=100)
slug = models.SlugField(verbose_name=_("Slug"), unique=True, max_length=100)
Expand Down Expand Up @@ -46,7 +42,7 @@ def save(self, *args, **kwargs):
# most cases ;)
try:
with transaction.atomic(using=using):
res = super(TagBase, self).save(*args, **kwargs)
res = super().save(*args, **kwargs)
return res
except IntegrityError:
pass
Expand All @@ -63,10 +59,10 @@ def save(self, *args, **kwargs):
self.slug = slug
# We purposely ignore concurrecny issues here for now.
# (That is, till we found a nice solution...)
return super(TagBase, self).save(*args, **kwargs)
return super().save(*args, **kwargs)
i += 1
else:
return super(TagBase, self).save(*args, **kwargs)
return super().save(*args, **kwargs)

def slugify(self, tag, i=None):
slug = slugify(unidecode(tag))
Expand All @@ -82,10 +78,9 @@ class Meta:
app_label = "taggit"


@python_2_unicode_compatible
class ItemBase(models.Model):
def __str__(self):
return ugettext("%(object)s tagged with %(tag)s") % {
return gettext("%(object)s tagged with %(tag)s") % {
"object": self.content_object,
"tag": self.tag,
}
Expand Down
5 changes: 0 additions & 5 deletions taggit/utils.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
from __future__ import unicode_literals

from django.conf import settings
from django.utils.encoding import force_text
from django.utils.functional import wraps
from django.utils.module_loading import import_string

Expand All @@ -20,8 +17,6 @@ def _parse_tags(tagstring):
if not tagstring:
return []

tagstring = force_text(tagstring)

# Special case - if there are no commas or double quotes in the
# input, we don't *do* a recall... I mean, we know we only need to
# split on spaces.
Expand Down
Loading

0 comments on commit 828e548

Please sign in to comment.