Skip to content

Commit

Permalink
Merge master
Browse files Browse the repository at this point in the history
  • Loading branch information
jadchaar committed Aug 1, 2019
2 parents 6c8fbba + b9d1171 commit 3fb6a33
Show file tree
Hide file tree
Showing 9 changed files with 157 additions and 18 deletions.
13 changes: 13 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
## History

### 0.14.4

- [FIX] Fixed a regression in 0.14.3 that prevented a tzinfo argument of type string to be passed to the `get()` function. Functionality such as `arrow.get("2019072807", "YYYYMMDDHH", tzinfo="UTC")` should work as normal again.
- [CHANGE] Moved `backports.functools_lru_cache` dependency from `extra_requires` to `install_requires` for `Python 2.7` installs to fix [#495](https://github.com/crsmithdev/arrow/issues/495).

### 0.14.3

- [NEW] Added full support for Python 3.8.
- [CHANGE] Added warnings for upcoming factory.get() parsing changes in 0.15.0. Please see https://github.com/crsmithdev/arrow/issues/612 for full details.
- [FIX] Extensive refactor and update of documentation.
- [FIX] factory.get() can now construct from kwargs.
- [FIX] Added meridians to Spanish Locale.

### 0.14.2

- [CHANGE] Travis CI builds now use tox to lint and run tests.
Expand Down
11 changes: 9 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,12 @@ docs:

clean:
rm -rf venv .tox ./**/__pycache__
rm -rf dist build .egg arrow.egg-info
rm -f ./**/*.pyc ./**/.coverage
rm -rf dist build .egg .eggs arrow.egg-info
rm -f ./**/*.pyc .coverage

publish:
rm -rf dist build .egg .eggs arrow.egg-info
pip3 install -U setuptools twine wheel
python3 setup.py sdist bdist_wheel
twine upload dist/*
rm -rf dist build .egg .eggs arrow.egg-info
2 changes: 1 addition & 1 deletion arrow/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.14.2"
__version__ = "0.14.4"
34 changes: 34 additions & 0 deletions arrow/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from __future__ import absolute_import

import calendar
import warnings
from datetime import date, datetime, tzinfo
from time import struct_time

Expand All @@ -19,6 +20,21 @@
from arrow.util import is_timestamp, isstr


class ArrowParseWarning(DeprecationWarning):
"""Raised when arrow.get() is passed a string with no formats and matches incorrectly
on one of the default formats.
e.g.
arrow.get('blabla2016') -> <Arrow [2016-01-01T00:00:00+00:00]>
arrow.get('13/4/2045') -> <Arrow [2045-01-01T00:00:00+00:00]>
In version 0.15.0 this warning will become a ParserError.
"""


warnings.simplefilter("always", ArrowParseWarning)


class ArrowFactory(object):
""" A factory for generating :class:`Arrow <arrow.arrow.Arrow>` objects.
Expand Down Expand Up @@ -136,6 +152,14 @@ def get(self, *args, **kwargs):
locale = kwargs.get("locale", "en_us")
tz = kwargs.get("tzinfo", None)

# if kwargs given, send to constructor unless only tzinfo provided
if len(kwargs) > 1:
arg_count = 3

# tzinfo kwarg is not provided
if len(kwargs) == 1 and tz is None:
arg_count = 3

# () -> now, @ utc.
if arg_count == 0:
if isinstance(tz, tzinfo):
Expand Down Expand Up @@ -171,6 +195,11 @@ def get(self, *args, **kwargs):

# (str) -> parse.
elif isstr(arg):
warnings.warn(
"The .get() parsing method without a format string will parse more strictly in version 0.15.0."
"See https://github.com/crsmithdev/arrow/issues/612 for more details.",
ArrowParseWarning,
)
dt = parser.DateTimeParser(locale).parse_iso(arg)
return self.type.fromdatetime(dt, tz)

Expand Down Expand Up @@ -213,6 +242,11 @@ def get(self, *args, **kwargs):

# (str, format) -> parse.
elif isstr(arg_1) and (isstr(arg_2) or isinstance(arg_2, list)):
warnings.warn(
"The .get() parsing method with a format string will parse more strictly in version 0.15.0."
"See https://github.com/crsmithdev/arrow/issues/612 for more details.",
ArrowParseWarning,
)
dt = parser.DateTimeParser(locale).parse(args[0], args[1])
return self.type.fromdatetime(dt, tzinfo=tz)

Expand Down
1 change: 1 addition & 0 deletions arrow/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class DateTimeParser(object):
_TIMESTAMP_RE = re.compile(r"^\d+\.?\d+$")
# TODO: test timestamp thoroughly

# TODO: test new regular expressions
_BASE_INPUT_RE_MAP = {
"YYYY": _FOUR_DIGIT_RE,
"YY": _TWO_DIGIT_RE,
Expand Down
54 changes: 45 additions & 9 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -301,8 +301,8 @@ Then get and use a factory for it:
>>> custom.days_till_xmas()
>>> 211
Tokens
~~~~~~
Supported Tokens
~~~~~~~~~~~~~~~~

Use the following tokens in parsing and formatting. Note that they're not the same as the tokens for `strptime(3) <https://www.gnu.org/software/libc/manual/html_node/Low_002dLevel-Time-String-Parsing.html#index-strptime>`_:

Expand Down Expand Up @@ -368,20 +368,56 @@ Use the following tokens in parsing and formatting. Note that they're not the s
|**Timestamp** |X |1381685817 |
+--------------------------------+--------------+-------------------------------------------+

Any token can be escaped when parsing by enclosing it within square brackets:

.. code-block:: python
>>> arrow.get("2018-03-09 8 h 40", "YYYY-MM-DD h [h] m")
<Arrow [2018-03-09T08:40:00+00:00]>
.. rubric:: Footnotes

.. [#t1] localization support for parsing and formatting
.. [#t2] localization support only for formatting
.. [#t3] the result is truncated to microseconds, with `half-to-even rounding <https://en.wikipedia.org/wiki/IEEE_floating_point#Roundings_to_nearest>`_.
.. [#t4] timezone names from `tz database <https://www.iana.org/time-zones>`_ provided via dateutil package
Escaping Formats
~~~~~~~~~~~~~~~~

Tokens, phrases, and regular expressions in a format string can be escaped when parsing by enclosing them within square brackets.

Tokens & Phrases
++++++++++++++++

Any `token <Supported Tokens_>`_ or phrase can be escaped as follows:

.. code-block:: python
>>> fmt = "YYYY-MM-DD h [h] m"
>>> arrow.get("2018-03-09 8 h 40", fmt)
<Arrow [2018-03-09T08:40:00+00:00]>
>>> fmt = "YYYY-MM-DD h [hello] m"
>>> arrow.get("2018-03-09 8 hello 40", fmt)
<Arrow [2018-03-09T08:40:00+00:00]>
>>> fmt = "YYYY-MM-DD h [hello world] m"
>>> arrow.get("2018-03-09 8 hello world 40", fmt)
<Arrow [2018-03-09T08:40:00+00:00]>
This can be useful for parsing dates in different locales such as French, in which it is common to format time strings as "8 h 40" rather than "8:40".

Regular Expressions
+++++++++++++++++++

You can also escape regular expressions by enclosing them within square brackets. In the following example, we are using the regular expression :code:`\s+` to match any number of whitespace characters that separate the tokens. This is useful if you do not know the number of spaces between tokens ahead of time (e.g. in log files).

.. code-block:: python
>>> fmt = r"ddd[\s+]MMM[\s+]DD[\s+]HH:mm:ss[\s+]YYYY"
>>> arrow.get("Mon Sep 08 16:41:45 2014", fmt)
<Arrow [2014-09-08T16:41:45+00:00]>
>>> arrow.get("Mon \tSep 08 16:41:45 2014", fmt)
<Arrow [2014-09-08T16:41:45+00:00]>
>>> arrow.get("Mon Sep 08 16:41:45 2014", fmt)
<Arrow [2014-09-08T16:41:45+00:00]>
API Guide
---------

Expand Down
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ backports.functools_lru_cache==1.5.0
chai==1.1.2
nose==1.3.7
nose-cov==1.6
pre-commit==1.16.1
pre-commit==1.17.0
python-dateutil==2.8.0
pytz==2019.1
simplejson==3.16.0
sphinx==1.8.5; python_version == '2.7'
sphinx==2.0.1; python_version >= '3.5'
sphinx==2.1.2; python_version >= '3.5'
10 changes: 6 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
setup(
name="arrow",
version=about["__version__"],
description="Better dates and times for Python",
description="Better dates & times for Python",
long_description=readme,
long_description_content_type="text/x-rst",
url="https://arrow.readthedocs.io/en/latest/",
Expand All @@ -23,8 +23,10 @@
packages=["arrow"],
zip_safe=False,
python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*",
install_requires=["python-dateutil"],
extras_require={":python_version=='2.7'": ["backports.functools_lru_cache>=1.2.1"]},
install_requires=[
"python-dateutil",
"backports.functools_lru_cache>=1.2.1;python_version=='2.7'",
],
test_suite="tests",
tests_require=["chai"],
classifiers=[
Expand All @@ -40,7 +42,7 @@
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
],
keywords="arrow date time datetime",
keywords="arrow date time datetime timestamp timezone",
project_urls={
"Repository": "https://github.com/crsmithdev/arrow",
"Bug Reports": "https://github.com/crsmithdev/arrow/issues",
Expand Down
46 changes: 46 additions & 0 deletions tests/factory_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,52 @@ def test_three_args(self):
self.factory.get(2013, 1, 1), datetime(2013, 1, 1, tzinfo=tz.tzutc())
)

def test_full_kwargs(self):

self.assertEqual(
self.factory.get(
year=2016,
month=7,
day=14,
hour=7,
minute=16,
second=45,
microsecond=631092,
),
datetime(2016, 7, 14, 7, 16, 45, 631092, tzinfo=tz.tzutc()),
)

def test_three_kwargs(self):

self.assertEqual(
self.factory.get(year=2016, month=7, day=14),
datetime(2016, 7, 14, 0, 0, tzinfo=tz.tzutc()),
)

def test_tzinfo_string_kwargs(self):
result = self.factory.get("2019072807", "YYYYMMDDHH", tzinfo="UTC")
self.assertEqual(
result._datetime, datetime(2019, 7, 28, 7, 0, 0, 0, tzinfo=tz.tzutc())
)

def test_insufficient_kwargs(self):

with self.assertRaises(TypeError):
self.factory.get(year=2016)

with self.assertRaises(TypeError):
self.factory.get(year=2016, month=7)

def test_locale_kwarg_only(self):

with self.assertRaises(TypeError):
self.factory.get(locale="ja")

def test_locale_with_tzinfo(self):

with self.assertRaises(TypeError):
self.factory.get(locale="ja", tzinfo=tz.gettz("Asia/Tokyo"))


class UtcNowTests(Chai):
def setUp(self):
Expand Down

0 comments on commit 3fb6a33

Please sign in to comment.