Skip to content

Commit b0aeb3e

Browse files
committed
Deprecate weekday_name, create localizing function in ccalendar.pyx
1 parent 58152f8 commit b0aeb3e

File tree

4 files changed

+79
-65
lines changed

4 files changed

+79
-65
lines changed

pandas/_libs/tslibs/ccalendar.pyx

+33
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ cimport numpy as np
1313
from numpy cimport int64_t, int32_t
1414
np.import_array()
1515

16+
import locale
17+
from pandas.util.testing import set_locale
18+
from strptime import LocaleTime
1619

1720
# ----------------------------------------------------------------------
1821
# Constants
@@ -36,11 +39,18 @@ cdef int32_t* _month_offset = [
3639
# Canonical location for other modules to find name constants
3740
MONTHS = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL',
3841
'AUG', 'SEP', 'OCT', 'NOV', 'DEC']
42+
# The first blank line is consistent with calendar.month_name in the calendar
43+
# standard library
44+
MONTHS_FULL = ['', 'January', 'February', 'March', 'April', 'May', 'June',
45+
'July', 'August, 'September', 'October', 'November',
46+
'December']
3947
MONTH_NUMBERS = {name: num for num, name in enumerate(MONTHS)}
4048
MONTH_ALIASES = {(num + 1): name for num, name in enumerate(MONTHS)}
4149
MONTH_TO_CAL_NUM = {name: num + 1 for num, name in enumerate(MONTHS)}
4250

4351
DAYS = ['MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT', 'SUN']
52+
DAYS_FULL = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday',
53+
'Saturday', 'Sunday']
4454
int_to_weekday = {num: name for num, name in enumerate(DAYS)}
4555
weekday_to_int = {int_to_weekday[key]: key for key in int_to_weekday}
4656

@@ -172,3 +182,26 @@ cpdef int32_t get_week_of_year(int year, int month, int day) nogil:
172182
woy = 1
173183

174184
return woy
185+
186+
187+
cpdef get_locale_names(object name_type, object time_locale=None) nogil:
188+
"""Returns an array of localized day or month names
189+
190+
Parameters
191+
----------
192+
name_type : string, attribute of LocaleTime() in which to return localized
193+
names
194+
locale : string
195+
196+
Returns
197+
-------
198+
names : list
199+
200+
"""
201+
cdef:
202+
object locale_time = LocaleTime()
203+
list locale_names
204+
205+
with set_locale(time_locale, locale.LC_TIME):
206+
locale_names = getattr(LocaleTime(), name_type)
207+
return locale_names

pandas/_libs/tslibs/fields.pyx

+9-17
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ np.import_array()
1515

1616

1717
from ccalendar cimport (get_days_in_month, is_leapyear, dayofweek,
18-
get_week_of_year)
18+
get_week_of_year, get_locale_names, MONTHS_FULL,
19+
DAYS_FULL)
1920
from np_datetime cimport (pandas_datetimestruct, pandas_timedeltastruct,
2021
dt64_to_dtstruct, td64_to_tdstruct)
2122
from nattype cimport NPY_NAT
@@ -100,15 +101,12 @@ def get_date_name_field(ndarray[int64_t] dtindex, object field,
100101
ndarray[object] out
101102
pandas_datetimestruct dts
102103
int dow
103-
object locale_time = LocaleTime()
104104

105105
count = len(dtindex)
106106
out = np.empty(count, dtype=object)
107107

108108
if field == 'weekday_name':
109-
_dayname = np.array(['Monday', 'Tuesday', 'Wednesday', 'Thursday',
110-
'Friday', 'Saturday', 'Sunday'],
111-
dtype=np.object_)
109+
_dayname = np.array(DAYS_FULL, dtype=np.object_)
112110
for i in range(count):
113111
if dtindex[i] == NPY_NAT:
114112
out[i] = np.nan
@@ -119,13 +117,10 @@ def get_date_name_field(ndarray[int64_t] dtindex, object field,
119117
out[i] = _dayname[dow]
120118
if field == 'day_name':
121119
if time_locale is None:
122-
_dayname = np.array(['monday', 'tuesday', 'wednesday', 'thursday',
123-
'friday', 'saturday', 'sunday'],
124-
dtype=np.object_)
120+
_dayname = np.array(DAYS_FULL, dtype=np.object_)
125121
else:
126-
with set_locale(time_locale, locale.LC_TIME):
127-
locale_time = LocaleTime()
128-
_dayname = np.array(locale_time.f_weekday, dtype=np.object_)
122+
_dayname = np.array(get_locale_names('f_weekday', time_locale),
123+
dtype=np.object_)
129124
for i in range(count):
130125
if dtindex[i] == NPY_NAT:
131126
out[i] = np.nan
@@ -137,13 +132,10 @@ def get_date_name_field(ndarray[int64_t] dtindex, object field,
137132
return out
138133
elif field == 'month_name':
139134
if time_locale is None:
140-
_monthname = np.array(['', 'monday', 'tuesday', 'wednesday',
141-
'thursday', 'friday', 'saturday', 'sunday'],
142-
dtype=np.object_)
135+
_monthname = np.array(MONTHS_FULL, dtype=np.object_)
143136
else:
144-
with set_locale(time_locale, locale.LC_TIME):
145-
locale_time = LocaleTime()
146-
_monthname = np.array(locale_time.f_month, dtype=np.object_)
137+
_monthname = np.array(get_locale_names('f_month', time_locale),
138+
dtype=np.object_)
147139
for i in range(count):
148140
if dtindex[i] == NPY_NAT:
149141
out[i] = np.nan

pandas/_libs/tslibs/nattype.pyx

+28-34
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
# -*- coding: utf-8 -*-
22
# cython: profile=False
3-
import warnings
43

54
from cpython cimport (
65
PyFloat_Check, PyComplex_Check,
@@ -38,30 +37,24 @@ _nat_scalar_rules[Py_GE] = False
3837

3938
# ----------------------------------------------------------------------
4039

40+
def _make_missing_value_func(func_name, missing_value, doc):
41+
"""Generate function that returns a missing value
4142
42-
def _make_nan_func(func_name, cls):
43-
def f(*args, **kwargs):
44-
return np.nan
43+
Parameters
44+
----------
45+
func_name : string
46+
missing_value : nan value
47+
doc: string
4548
46-
f.__name__ = func_name
47-
if isinstance(cls, str):
48-
# passed the literal docstring directly
49-
f.__doc__ = cls
50-
else:
51-
f.__doc__ = getattr(cls, func_name).__doc__
52-
return f
53-
54-
55-
def _make_nat_func(func_name, cls):
49+
Returns
50+
-------
51+
f : function
52+
"""
5653
def f(*args, **kwargs):
57-
return NaT
54+
return missing_value
5855

5956
f.__name__ = func_name
60-
if isinstance(cls, str):
61-
# passed the literal docstring directly
62-
f.__doc__ = cls
63-
else:
64-
f.__doc__ = getattr(cls, func_name).__doc__
57+
f.__doc__ = doc
6558
return f
6659

6760

@@ -323,9 +316,10 @@ class NaTType(_NaT):
323316
# These are the ones that can get their docstrings from datetime.
324317

325318
# nan methods
326-
weekday = _make_nan_func('weekday', datetime)
327-
isoweekday = _make_nan_func('isoweekday', datetime)
328-
month_name = _make_nan_func('month_name', # noqa:E128
319+
weekday = _make_missing_value_func('weekday', np.nan, datetime.__doc__)
320+
isoweekday = _make_missing_value_func('isoweekday', np.nan,
321+
datetime.__doc__)
322+
month_name = _make_missing_value_func('month_name', np.nan, # noqa:E128
329323
"""
330324
Return the month name of the Timestamp with specified locale.
331325
@@ -338,7 +332,7 @@ class NaTType(_NaT):
338332
-------
339333
month_name : string
340334
""")
341-
day_name = _make_nan_func('day_name', # noqa:E128
335+
day_name = _make_missing_value_func('day_name', np.nan, # noqa:E128
342336
"""
343337
Return the day name of the Timestamp with specified locale.
344338
@@ -352,7 +346,7 @@ class NaTType(_NaT):
352346
day_name : string
353347
""")
354348
# _nat_methods
355-
date = _make_nat_func('date', datetime)
349+
date = _make_missing_value_func('date', NaT, datetime.__doc__)
356350

357351
utctimetuple = _make_error_func('utctimetuple', datetime)
358352
timetz = _make_error_func('timetz', datetime)
@@ -442,14 +436,14 @@ class NaTType(_NaT):
442436
""")
443437

444438
# _nat_methods
445-
to_pydatetime = _make_nat_func('to_pydatetime', # noqa:E128
439+
to_pydatetime = _make_missing_value_func('to_pydatetime', NaT, # noqa:E128
446440
"""
447441
Convert a Timestamp object to a native Python datetime object.
448442
449443
If warn=True, issue a warning if nanoseconds is nonzero.
450444
""")
451445

452-
now = _make_nat_func('now', # noqa:E128
446+
now = _make_missing_value_func('now', NaT, # noqa:E128
453447
"""
454448
Timestamp.now(tz=None)
455449
@@ -461,7 +455,7 @@ class NaTType(_NaT):
461455
tz : str or timezone object, default None
462456
Timezone to localize to
463457
""")
464-
today = _make_nat_func('today', # noqa:E128
458+
today = _make_missing_value_func('today', NaT, # noqa:E128
465459
"""
466460
Timestamp.today(cls, tz=None)
467461
@@ -474,7 +468,7 @@ class NaTType(_NaT):
474468
tz : str or timezone object, default None
475469
Timezone to localize to
476470
""")
477-
round = _make_nat_func('round', # noqa:E128
471+
round = _make_missing_value_func('round', NaT, # noqa:E128
478472
"""
479473
Round the Timestamp to the specified resolution
480474
@@ -490,15 +484,15 @@ class NaTType(_NaT):
490484
------
491485
ValueError if the freq cannot be converted
492486
""")
493-
floor = _make_nat_func('floor', # noqa:E128
487+
floor = _make_missing_value_func('floor', NaT, # noqa:E128
494488
"""
495489
return a new Timestamp floored to this resolution
496490
497491
Parameters
498492
----------
499493
freq : a freq string indicating the flooring resolution
500494
""")
501-
ceil = _make_nat_func('ceil', # noqa:E128
495+
ceil = _make_missing_value_func('ceil', NaT, # noqa:E128
502496
"""
503497
return a new Timestamp ceiled to this resolution
504498
@@ -507,7 +501,7 @@ class NaTType(_NaT):
507501
freq : a freq string indicating the ceiling resolution
508502
""")
509503

510-
tz_convert = _make_nat_func('tz_convert', # noqa:E128
504+
tz_convert = _make_missing_value_func('tz_convert', NaT, # noqa:E128
511505
"""
512506
Convert tz-aware Timestamp to another time zone.
513507
@@ -526,7 +520,7 @@ class NaTType(_NaT):
526520
TypeError
527521
If Timestamp is tz-naive.
528522
""")
529-
tz_localize = _make_nat_func('tz_localize', # noqa:E128
523+
tz_localize = _make_missing_value_func('tz_localize', NaT, # noqa:E128
530524
"""
531525
Convert naive Timestamp to local time zone, or remove
532526
timezone from tz-aware Timestamp.
@@ -561,7 +555,7 @@ class NaTType(_NaT):
561555
TypeError
562556
If the Timestamp is tz-aware and tz is not None.
563557
""")
564-
replace = _make_nat_func('replace', # noqa:E128
558+
replace = _make_missing_value_func('replace', NaT, # noqa:E128
565559
"""
566560
implements datetime.replace, handles nanoseconds
567561

pandas/_libs/tslibs/timestamps.pyx

+9-14
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ from np_datetime cimport (reverse_ops, cmp_scalar, check_dts_bounds,
3737
from timedeltas import Timedelta
3838
from timedeltas cimport delta_to_nanoseconds
3939
from timezones cimport get_timezone, is_utc, maybe_get_tz, treat_tz_as_pytz
40-
from strptime import LocaleTime
4140

4241
# ----------------------------------------------------------------------
4342
# Constants
@@ -703,13 +702,10 @@ class Timestamp(_Timestamp):
703702
day_name : string
704703
"""
705704
if time_locale is None:
706-
days = {0: 'monday', 1: 'tuesday', 2: 'wednesday',
707-
3: 'thursday', 4: 'friday', 5: 'saturday',
708-
6: 'sunday'}
705+
days = dict(enumerate(ccalendar.DAYS_FULL))
709706
else:
710-
with set_locale(time_locale, locale.LC_TIME):
711-
locale_time = LocaleTime()
712-
days = dict(enumerate(locale_time.f_weekday))
707+
names = ccalendar.get_locale_names('f_weekday', time_locale)
708+
days = dict(enumerate(names))
713709
return days[self.weekday()].capitalize()
714710

715711
def month_name(self, time_locale=None):
@@ -726,14 +722,10 @@ class Timestamp(_Timestamp):
726722
month_name : string
727723
"""
728724
if time_locale is None:
729-
months = {1: 'january', 2: 'february', 3: 'march',
730-
4: 'april', 5: 'may', 6: 'june', 7: 'july',
731-
8: 'august', 9: 'september', 10: 'october',
732-
11: 'november', 12: 'december'}
725+
months = dict(enumerate(ccalendar.MONTHS_FULL))
733726
else:
734-
with set_locale(time_locale, locale.LC_TIME):
735-
locale_time = LocaleTime()
736-
months = dict(enumerate(locale_time.f_month))
727+
names = ccalendar.get_locale_names('f_month', time_locale)
728+
months = dict(enumerate(names))
737729
return months[self.month].capitalize()
738730

739731
@property
@@ -742,6 +734,9 @@ class Timestamp(_Timestamp):
742734
.. depreciated:: 0.23.0
743735
Use ``Timestamp.day_name()`` instead
744736
"""
737+
warnings.warn("`weekday_name` is deprecated and will be removed in a "
738+
"future version. Use `day_name` instead",
739+
FutureWarning, stacklevel=2)
745740
cdef dict wdays = {0: 'Monday', 1: 'Tuesday', 2: 'Wednesday',
746741
3: 'Thursday', 4: 'Friday', 5: 'Saturday',
747742
6: 'Sunday'}

0 commit comments

Comments
 (0)