Refactored code and tests that relied on django.utils.tzinfo.
Refs #17262.
This commit is contained in:
parent
ec2778b445
commit
d9413d33b2
|
@ -14,10 +14,9 @@ from django.template import Template, Context, defaultfilters
|
|||
from django.test import TestCase
|
||||
from django.test.utils import override_settings
|
||||
from django.utils.html import escape
|
||||
from django.utils.timezone import utc
|
||||
from django.utils.timezone import utc, get_fixed_timezone
|
||||
from django.utils import translation
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.utils import tzinfo
|
||||
|
||||
from i18n import TransRealMixin
|
||||
|
||||
|
@ -153,8 +152,8 @@ class HumanizeTests(TransRealMixin, TestCase):
|
|||
|
||||
def test_naturalday_tz(self):
|
||||
today = datetime.date.today()
|
||||
tz_one = tzinfo.FixedOffset(datetime.timedelta(hours=-12))
|
||||
tz_two = tzinfo.FixedOffset(datetime.timedelta(hours=12))
|
||||
tz_one = get_fixed_timezone(-720)
|
||||
tz_two = get_fixed_timezone(720)
|
||||
|
||||
# Can be today or yesterday
|
||||
date_one = datetime.datetime(today.year, today.month, today.day, tzinfo=tz_one)
|
||||
|
|
|
@ -7,12 +7,12 @@ from django.contrib.sites.models import get_current_site
|
|||
from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist
|
||||
from django.http import HttpResponse, Http404
|
||||
from django.template import loader, TemplateDoesNotExist, RequestContext
|
||||
from django.utils import feedgenerator, tzinfo
|
||||
from django.utils import feedgenerator
|
||||
from django.utils.encoding import force_text, iri_to_uri, smart_text
|
||||
from django.utils.html import escape
|
||||
from django.utils.http import http_date
|
||||
from django.utils import six
|
||||
from django.utils.timezone import is_naive
|
||||
from django.utils.timezone import get_default_timezone, is_naive, make_aware
|
||||
|
||||
|
||||
def add_domain(domain, url, secure=False):
|
||||
|
@ -186,15 +186,15 @@ class Feed(object):
|
|||
else:
|
||||
author_email = author_link = None
|
||||
|
||||
tz = get_default_timezone()
|
||||
|
||||
pubdate = self.__get_dynamic_attr('item_pubdate', item)
|
||||
if pubdate and is_naive(pubdate):
|
||||
ltz = tzinfo.LocalTimezone(pubdate)
|
||||
pubdate = pubdate.replace(tzinfo=ltz)
|
||||
pubdate = make_aware(pubdate, tz)
|
||||
|
||||
updateddate = self.__get_dynamic_attr('item_updateddate', item)
|
||||
if updateddate and is_naive(updateddate):
|
||||
ltz = tzinfo.LocalTimezone(updateddate)
|
||||
updateddate = updateddate.replace(tzinfo=ltz)
|
||||
updateddate = make_aware(updateddate, tz)
|
||||
|
||||
feed.add_item(
|
||||
title = title,
|
||||
|
|
|
@ -18,11 +18,10 @@ import calendar
|
|||
import datetime
|
||||
|
||||
from django.utils.dates import MONTHS, MONTHS_3, MONTHS_ALT, MONTHS_AP, WEEKDAYS, WEEKDAYS_ABBR
|
||||
from django.utils.tzinfo import LocalTimezone
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.utils.encoding import force_text
|
||||
from django.utils import six
|
||||
from django.utils.timezone import is_aware, is_naive
|
||||
from django.utils.timezone import get_default_timezone, is_aware, is_naive
|
||||
|
||||
re_formatchars = re.compile(r'(?<!\\)([aAbBcdDeEfFgGhHiIjlLmMnNoOPrsStTUuwWyYzZ])')
|
||||
re_escaped = re.compile(r'\\(.)')
|
||||
|
@ -48,7 +47,7 @@ class TimeFormat(Formatter):
|
|||
# or time objects (against established django policy).
|
||||
if isinstance(obj, datetime.datetime):
|
||||
if is_naive(obj):
|
||||
self.timezone = LocalTimezone(obj)
|
||||
self.timezone = get_default_timezone()
|
||||
else:
|
||||
self.timezone = obj.tzinfo
|
||||
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
import datetime
|
||||
import re
|
||||
from django.utils import six
|
||||
from django.utils.timezone import utc
|
||||
from django.utils.tzinfo import FixedOffset
|
||||
from django.utils.timezone import utc, get_fixed_timezone
|
||||
|
||||
|
||||
date_re = re.compile(
|
||||
r'(?P<year>\d{4})-(?P<month>\d{1,2})-(?P<day>\d{1,2})$'
|
||||
|
@ -27,6 +27,7 @@ datetime_re = re.compile(
|
|||
r'(?P<tzinfo>Z|[+-]\d{2}:?\d{2})?$'
|
||||
)
|
||||
|
||||
|
||||
def parse_date(value):
|
||||
"""Parses a string and return a datetime.date.
|
||||
|
||||
|
@ -59,7 +60,7 @@ def parse_datetime(value):
|
|||
"""Parses a string and return a datetime.datetime.
|
||||
|
||||
This function supports time zone offsets. When the input contains one,
|
||||
the output uses an instance of FixedOffset as tzinfo.
|
||||
the output uses a timezone with a fixed offset from UTC.
|
||||
|
||||
Raises ValueError if the input is well formatted but not a valid datetime.
|
||||
Returns None if the input isn't well formatted.
|
||||
|
@ -76,7 +77,7 @@ def parse_datetime(value):
|
|||
offset = 60 * int(tzinfo[1:3]) + int(tzinfo[-2:])
|
||||
if tzinfo[0] == '-':
|
||||
offset = -offset
|
||||
tzinfo = FixedOffset(offset)
|
||||
tzinfo = get_fixed_timezone(offset)
|
||||
kw = dict((k, int(v)) for k, v in six.iteritems(kw) if v is not None)
|
||||
kw['tzinfo'] = tzinfo
|
||||
return datetime.datetime(**kw)
|
||||
|
|
|
@ -8,7 +8,7 @@ import unittest
|
|||
from django.core.exceptions import ValidationError
|
||||
from django.test import TestCase, skipUnlessDBFeature
|
||||
from django.utils import six
|
||||
from django.utils import tzinfo
|
||||
from django.utils.timezone import get_fixed_timezone
|
||||
from django.db import connection, router
|
||||
from django.db.models.sql import InsertQuery
|
||||
|
||||
|
@ -189,8 +189,8 @@ class ModelTests(TestCase):
|
|||
# Regression test for #10443.
|
||||
# The idea is that all these creations and saving should work without
|
||||
# crashing. It's not rocket science.
|
||||
dt1 = datetime.datetime(2008, 8, 31, 16, 20, tzinfo=tzinfo.FixedOffset(600))
|
||||
dt2 = datetime.datetime(2008, 8, 31, 17, 20, tzinfo=tzinfo.FixedOffset(600))
|
||||
dt1 = datetime.datetime(2008, 8, 31, 16, 20, tzinfo=get_fixed_timezone(600))
|
||||
dt2 = datetime.datetime(2008, 8, 31, 17, 20, tzinfo=get_fixed_timezone(600))
|
||||
obj = Article.objects.create(
|
||||
headline="A headline", pub_date=dt1, article_text="foo"
|
||||
)
|
||||
|
|
|
@ -2,7 +2,8 @@ from __future__ import unicode_literals
|
|||
|
||||
from django.contrib.syndication import views
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.utils import feedgenerator, tzinfo
|
||||
from django.utils import feedgenerator
|
||||
from django.utils.timezone import get_fixed_timezone
|
||||
|
||||
from .models import Article, Entry
|
||||
|
||||
|
@ -140,7 +141,7 @@ class TZAwareDatesFeed(TestAtomFeed):
|
|||
# Provide a weird offset so that the test can know it's getting this
|
||||
# specific offset and not accidentally getting on from
|
||||
# settings.TIME_ZONE.
|
||||
return item.published.replace(tzinfo=tzinfo.FixedOffset(42))
|
||||
return item.published.replace(tzinfo=get_fixed_timezone(42))
|
||||
|
||||
|
||||
class TestFeedUrlFeed(TestAtomFeed):
|
||||
|
|
|
@ -1,19 +1,36 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import datetime
|
||||
from xml.dom import minidom
|
||||
|
||||
try:
|
||||
import pytz
|
||||
except ImportError:
|
||||
pytz = None
|
||||
|
||||
from django.contrib.syndication import views
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.test import TestCase
|
||||
from django.utils import tzinfo
|
||||
from django.utils.feedgenerator import rfc2822_date, rfc3339_date
|
||||
from django.utils import timezone
|
||||
|
||||
from .models import Entry
|
||||
|
||||
|
||||
TZ = timezone.get_default_timezone()
|
||||
|
||||
|
||||
class FeedTestCase(TestCase):
|
||||
fixtures = ['feeddata.json']
|
||||
|
||||
def setUp(self):
|
||||
# Django cannot deal with very old dates when pytz isn't installed.
|
||||
if pytz is None:
|
||||
old_entry = Entry.objects.get(pk=1)
|
||||
old_entry.updated = datetime.datetime(1980, 1, 1, 12, 30)
|
||||
old_entry.published = datetime.datetime(1986, 9, 25, 20, 15, 00)
|
||||
old_entry.save()
|
||||
|
||||
def assertChildNodes(self, elem, expected):
|
||||
actual = set(n.nodeName for n in elem.childNodes)
|
||||
expected = set(expected)
|
||||
|
@ -59,8 +76,7 @@ class SyndicationFeedTest(FeedTestCase):
|
|||
|
||||
# Find the last build date
|
||||
d = Entry.objects.latest('published').published
|
||||
ltz = tzinfo.LocalTimezone(d)
|
||||
last_build_date = rfc2822_date(d.replace(tzinfo=ltz))
|
||||
last_build_date = rfc2822_date(timezone.make_aware(d, TZ))
|
||||
|
||||
self.assertChildNodes(chan, ['title', 'link', 'description', 'language', 'lastBuildDate', 'item', 'atom:link', 'ttl', 'copyright', 'category'])
|
||||
self.assertChildNodeContent(chan, {
|
||||
|
@ -89,8 +105,7 @@ class SyndicationFeedTest(FeedTestCase):
|
|||
|
||||
# Find the pubdate of the first feed item
|
||||
d = Entry.objects.get(pk=1).published
|
||||
ltz = tzinfo.LocalTimezone(d)
|
||||
pub_date = rfc2822_date(d.replace(tzinfo=ltz))
|
||||
pub_date = rfc2822_date(timezone.make_aware(d, TZ))
|
||||
|
||||
items = chan.getElementsByTagName('item')
|
||||
self.assertEqual(len(items), Entry.objects.count())
|
||||
|
@ -242,8 +257,7 @@ class SyndicationFeedTest(FeedTestCase):
|
|||
updated = feed.getElementsByTagName('updated')[0].firstChild.wholeText
|
||||
|
||||
d = Entry.objects.latest('published').published
|
||||
ltz = tzinfo.LocalTimezone(d)
|
||||
latest_published = rfc3339_date(d.replace(tzinfo=ltz))
|
||||
latest_published = rfc3339_date(timezone.make_aware(d, TZ))
|
||||
|
||||
self.assertEqual(updated, latest_published)
|
||||
|
||||
|
@ -253,8 +267,7 @@ class SyndicationFeedTest(FeedTestCase):
|
|||
updated = feed.getElementsByTagName('updated')[0].firstChild.wholeText
|
||||
|
||||
d = Entry.objects.exclude(pk=5).latest('updated').updated
|
||||
ltz = tzinfo.LocalTimezone(d)
|
||||
latest_updated = rfc3339_date(d.replace(tzinfo=ltz))
|
||||
latest_updated = rfc3339_date(timezone.make_aware(d, TZ))
|
||||
|
||||
self.assertEqual(updated, latest_updated)
|
||||
|
||||
|
@ -308,8 +321,7 @@ class SyndicationFeedTest(FeedTestCase):
|
|||
updated = doc.getElementsByTagName('updated')[0].firstChild.wholeText
|
||||
|
||||
d = Entry.objects.latest('published').published
|
||||
ltz = tzinfo.LocalTimezone(d)
|
||||
latest = rfc3339_date(d.replace(tzinfo=ltz))
|
||||
latest = rfc3339_date(timezone.make_aware(d, TZ))
|
||||
|
||||
self.assertEqual(updated, latest)
|
||||
|
||||
|
|
|
@ -11,9 +11,9 @@ from __future__ import unicode_literals
|
|||
from datetime import date, datetime, time, timedelta
|
||||
|
||||
from django.test.utils import str_prefix
|
||||
from django.utils.tzinfo import LocalTimezone, FixedOffset
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.encoding import python_2_unicode_compatible
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils import timezone
|
||||
|
||||
# These two classes are used to test auto-escaping of __unicode__ output.
|
||||
@python_2_unicode_compatible
|
||||
|
@ -31,8 +31,8 @@ class SafeClass:
|
|||
# 'expected string output' or Exception class)
|
||||
def get_filter_tests():
|
||||
now = datetime.now()
|
||||
now_tz = datetime.now(LocalTimezone(now))
|
||||
now_tz_i = datetime.now(FixedOffset((3 * 60) + 15)) # imaginary time zone
|
||||
now_tz = timezone.make_aware(now, timezone.get_default_timezone())
|
||||
now_tz_i = timezone.localtime(now_tz, timezone.get_fixed_timezone(195))
|
||||
today = date.today()
|
||||
|
||||
# NOTE: \xa0 avoids wrapping between value and unit
|
||||
|
@ -355,7 +355,7 @@ def get_filter_tests():
|
|||
'date04': (r'{{ d|date:"o" }}', {'d': datetime(2008, 12, 29)}, '2009'),
|
||||
'date05': (r'{{ d|date:"o" }}', {'d': datetime(2010, 1, 3)}, '2009'),
|
||||
# Timezone name
|
||||
'date06': (r'{{ d|date:"e" }}', {'d': datetime(2009, 3, 12, tzinfo=FixedOffset(30))}, '+0030'),
|
||||
'date06': (r'{{ d|date:"e" }}', {'d': datetime(2009, 3, 12, tzinfo=timezone.get_fixed_timezone(30))}, '+0030'),
|
||||
'date07': (r'{{ d|date:"e" }}', {'d': datetime(2009, 3, 12)}, ''),
|
||||
# Ticket 19370: Make sure |date doesn't blow up on a midnight time object
|
||||
'date08': (r'{{ t|date:"H:i" }}', {'t': time(0, 1)}, '00:01'),
|
||||
|
@ -363,7 +363,7 @@ def get_filter_tests():
|
|||
# Ticket 20693: Add timezone support to built-in time template filter
|
||||
'time01': (r'{{ dt|time:"e:O:T:Z" }}', {'dt': now_tz_i}, '+0315:+0315:+0315:11700'),
|
||||
'time02': (r'{{ dt|time:"e:T" }}', {'dt': now}, ':' + now_tz.tzinfo.tzname(now_tz)),
|
||||
'time03': (r'{{ t|time:"P:e:O:T:Z" }}', {'t': time(4, 0, tzinfo=FixedOffset(30))}, '4 a.m.::::'),
|
||||
'time03': (r'{{ t|time:"P:e:O:T:Z" }}', {'t': time(4, 0, tzinfo=timezone.get_fixed_timezone(30))}, '4 a.m.::::'),
|
||||
'time04': (r'{{ t|time:"P:e:O:T:Z" }}', {'t': time(4, 0)}, '4 a.m.::::'),
|
||||
'time05': (r'{{ d|time:"P:e:O:T:Z" }}', {'d': today}, ''),
|
||||
'time06': (r'{{ obj|time:"P:e:O:T:Z" }}', {'obj': 'non-datetime-value'}, ''),
|
||||
|
|
|
@ -1,42 +1,28 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from datetime import datetime, date
|
||||
import os
|
||||
import time
|
||||
import unittest
|
||||
|
||||
from django.test import TestCase
|
||||
from django.test.utils import override_settings
|
||||
from django.utils.dateformat import format
|
||||
from django.utils import dateformat
|
||||
from django.utils.timezone import utc, get_fixed_timezone, get_default_timezone
|
||||
from django.utils import translation
|
||||
from django.utils.timezone import utc
|
||||
from django.utils.tzinfo import FixedOffset, LocalTimezone
|
||||
|
||||
|
||||
class DateFormatTests(unittest.TestCase):
|
||||
@override_settings(TIME_ZONE='Europe/Copenhagen')
|
||||
class DateFormatTests(TestCase):
|
||||
|
||||
# Run tests that require a time zone only when the OS supports it.
|
||||
tz_tests = hasattr(time, 'tzset')
|
||||
|
||||
def setUp(self):
|
||||
self.old_TZ = os.environ.get('TZ')
|
||||
os.environ['TZ'] = 'Europe/Copenhagen'
|
||||
self._orig_lang = translation.get_language()
|
||||
translation.activate('en-us')
|
||||
|
||||
try:
|
||||
# Check if a timezone has been set
|
||||
time.tzset()
|
||||
self.tz_tests = True
|
||||
except AttributeError:
|
||||
# No timezone available. Don't run the tests that require a TZ
|
||||
self.tz_tests = False
|
||||
|
||||
def tearDown(self):
|
||||
translation.activate(self._orig_lang)
|
||||
if self.old_TZ is None:
|
||||
del os.environ['TZ']
|
||||
else:
|
||||
os.environ['TZ'] = self.old_TZ
|
||||
|
||||
# Cleanup - force re-evaluation of TZ environment variable.
|
||||
if self.tz_tests:
|
||||
time.tzset()
|
||||
|
||||
def test_date(self):
|
||||
d = date(2009, 5, 16)
|
||||
|
@ -47,14 +33,14 @@ class DateFormatTests(unittest.TestCase):
|
|||
self.assertEqual(datetime.fromtimestamp(int(format(dt, 'U'))), dt)
|
||||
|
||||
def test_datetime_with_local_tzinfo(self):
|
||||
ltz = LocalTimezone(datetime.now())
|
||||
ltz = get_default_timezone()
|
||||
dt = datetime(2009, 5, 16, 5, 30, 30, tzinfo=ltz)
|
||||
self.assertEqual(datetime.fromtimestamp(int(format(dt, 'U')), ltz), dt)
|
||||
self.assertEqual(datetime.fromtimestamp(int(format(dt, 'U'))), dt.replace(tzinfo=None))
|
||||
|
||||
def test_datetime_with_tzinfo(self):
|
||||
tz = FixedOffset(-510)
|
||||
ltz = LocalTimezone(datetime.now())
|
||||
tz = get_fixed_timezone(-510)
|
||||
ltz = get_default_timezone()
|
||||
dt = datetime(2009, 5, 16, 5, 30, 30, tzinfo=tz)
|
||||
self.assertEqual(datetime.fromtimestamp(int(format(dt, 'U')), tz), dt)
|
||||
self.assertEqual(datetime.fromtimestamp(int(format(dt, 'U')), ltz), dt)
|
||||
|
@ -128,7 +114,7 @@ class DateFormatTests(unittest.TestCase):
|
|||
timestamp = datetime(2008, 5, 19, 11, 45, 23, 123456)
|
||||
|
||||
# 3h30m to the west of UTC
|
||||
tz = FixedOffset(-3*60 - 30)
|
||||
tz = get_fixed_timezone(-210)
|
||||
aware_dt = datetime(2009, 5, 16, 5, 30, 30, tzinfo=tz)
|
||||
|
||||
if self.tz_tests:
|
||||
|
|
|
@ -4,7 +4,7 @@ from datetime import date, time, datetime
|
|||
import unittest
|
||||
|
||||
from django.utils.dateparse import parse_date, parse_time, parse_datetime
|
||||
from django.utils.tzinfo import FixedOffset
|
||||
from django.utils.timezone import get_fixed_timezone
|
||||
|
||||
|
||||
class DateParseTests(unittest.TestCase):
|
||||
|
@ -34,11 +34,11 @@ class DateParseTests(unittest.TestCase):
|
|||
self.assertEqual(parse_datetime('2012-4-9 4:8:16'),
|
||||
datetime(2012, 4, 9, 4, 8, 16))
|
||||
self.assertEqual(parse_datetime('2012-04-23T09:15:00Z'),
|
||||
datetime(2012, 4, 23, 9, 15, 0, 0, FixedOffset(0)))
|
||||
datetime(2012, 4, 23, 9, 15, 0, 0, get_fixed_timezone(0)))
|
||||
self.assertEqual(parse_datetime('2012-4-9 4:8:16-0320'),
|
||||
datetime(2012, 4, 9, 4, 8, 16, 0, FixedOffset(-200)))
|
||||
datetime(2012, 4, 9, 4, 8, 16, 0, get_fixed_timezone(-200)))
|
||||
self.assertEqual(parse_datetime('2012-04-23T10:20:30.400+02:30'),
|
||||
datetime(2012, 4, 23, 10, 20, 30, 400000, FixedOffset(150)))
|
||||
datetime(2012, 4, 23, 10, 20, 30, 400000, get_fixed_timezone(150)))
|
||||
# Invalid inputs
|
||||
self.assertEqual(parse_datetime('20120423091500'), None)
|
||||
self.assertRaises(ValueError, parse_datetime, '2012-04-56T09:15:90')
|
||||
|
|
|
@ -4,7 +4,7 @@ import datetime
|
|||
import unittest
|
||||
|
||||
from django.utils import feedgenerator
|
||||
from django.utils import tzinfo
|
||||
from django.utils.timezone import get_fixed_timezone
|
||||
|
||||
|
||||
class FeedgeneratorTest(unittest.TestCase):
|
||||
|
@ -43,7 +43,7 @@ class FeedgeneratorTest(unittest.TestCase):
|
|||
Test rfc2822_date() correctly formats datetime objects with tzinfo.
|
||||
"""
|
||||
self.assertEqual(
|
||||
feedgenerator.rfc2822_date(datetime.datetime(2008, 11, 14, 13, 37, 0, tzinfo=tzinfo.FixedOffset(datetime.timedelta(minutes=60)))),
|
||||
feedgenerator.rfc2822_date(datetime.datetime(2008, 11, 14, 13, 37, 0, tzinfo=get_fixed_timezone(60))),
|
||||
"Fri, 14 Nov 2008 13:37:00 +0100"
|
||||
)
|
||||
|
||||
|
@ -70,7 +70,7 @@ class FeedgeneratorTest(unittest.TestCase):
|
|||
Test rfc3339_date() correctly formats datetime objects with tzinfo.
|
||||
"""
|
||||
self.assertEqual(
|
||||
feedgenerator.rfc3339_date(datetime.datetime(2008, 11, 14, 13, 37, 0, tzinfo=tzinfo.FixedOffset(datetime.timedelta(minutes=120)))),
|
||||
feedgenerator.rfc3339_date(datetime.datetime(2008, 11, 14, 13, 37, 0, tzinfo=get_fixed_timezone(120))),
|
||||
"2008-11-14T13:37:00+02:00"
|
||||
)
|
||||
|
||||
|
|
|
@ -4,7 +4,8 @@ import datetime
|
|||
import unittest
|
||||
|
||||
from django.utils.timesince import timesince, timeuntil
|
||||
from django.utils.tzinfo import LocalTimezone, FixedOffset
|
||||
from django.utils import timezone
|
||||
|
||||
|
||||
class TimesinceTests(unittest.TestCase):
|
||||
|
||||
|
@ -95,8 +96,8 @@ class TimesinceTests(unittest.TestCase):
|
|||
def test_different_timezones(self):
|
||||
""" When using two different timezones. """
|
||||
now = datetime.datetime.now()
|
||||
now_tz = datetime.datetime.now(LocalTimezone(now))
|
||||
now_tz_i = datetime.datetime.now(FixedOffset((3 * 60) + 15))
|
||||
now_tz = timezone.make_aware(now, timezone.get_default_timezone())
|
||||
now_tz_i = timezone.localtime(now_tz, timezone.get_fixed_timezone(195))
|
||||
|
||||
self.assertEqual(timesince(now), '0\xa0minutes')
|
||||
self.assertEqual(timesince(now_tz), '0\xa0minutes')
|
||||
|
|
Loading…
Reference in New Issue