Skip to content

Commit b306e9e

Browse files
authored
Version 2.1.1 (#44)
Improves date parsing, making it work even when pt-br locale is not installed on the user's machine
1 parent 8d535b4 commit b306e9e

File tree

8 files changed

+49
-45
lines changed

8 files changed

+49
-45
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
__pycache__/
22
.cache/
3+
.ipynb_checkpoints/
4+
.pytest_cache/
35
.mypy_cache/
46
.vscode/
57
dist/

setup.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from setuptools import setup
22

33

4-
__version__ = '2.1.0'
4+
__version__ = "2.1.1"
55

66

77
with open('README.rst', 'r', encoding='utf-8') as f:
@@ -19,9 +19,11 @@
1919
dev_requirements = [
2020
"bandit==1.6.0",
2121
"codecov==2.0.15",
22+
"mypy==0.910",
2223
"pytest==4.6.2",
2324
"pytest-cov==2.7.1",
24-
"pytest-mypy>=0.3.2"
25+
"pytest-mypy>=0.8.1",
26+
"types-requests>=2.25.6"
2527
]
2628

2729
setup(

sgs/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "2.0.3"
1+
__version__ = "2.1.1"

sgs/common.py

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,45 @@
11
"""
22
Shared functions.
33
"""
4-
from datetime import datetime
4+
import functools
55
import locale
6+
import os
67
import re
8+
from datetime import datetime
79
from typing import Union
8-
import os
910

1011

1112
LRU_CACHE_SIZE = 32
1213
MAX_ATTEMPT_NUMBER = 5
1314

1415

16+
@functools.lru_cache(maxsize=365)
1517
def to_datetime(date_string: str, language: str) -> Union[datetime, str]:
1618
""" Converts a date string to a datetime object """
17-
locales = {"pt": "pt_BR.utf-8", "en": "en_US.utf-8"}
18-
19-
""" correct problem with locale in Windows platform """
20-
if os.name == 'nt':
21-
locales = {"pt": "Portuguese_Brazil.1252", "en": "Portuguese_Brazil.1252"}
22-
23-
locale.setlocale(locale.LC_TIME, locales[language])
24-
25-
dd_mm_aaaa = "%d/%m/%Y"
26-
mmm_aaaa = "%b/%Y"
2719

28-
formats = [dd_mm_aaaa, mmm_aaaa]
29-
30-
for fmt in formats:
31-
try:
32-
date = datetime.strptime(date_string, fmt)
33-
break
34-
except ValueError:
35-
continue
20+
yyyy = "[0-9]{4}"
21+
mmm_yyyy = r"[a-z]{3}/[0-9]{4}"
22+
23+
if re.match(yyyy, date_string):
24+
date = datetime(int(date_string), 12, 31)
25+
elif re.match(mmm_yyyy, date_string):
26+
month_text, year_text = date_string.split("/")
27+
months = [
28+
("jan", "jan"), ("fev", "feb"), ("mar", "mar"),
29+
("abr", "apr"), ("mai", "may"), ("jun", "jun"),
30+
("jul", "jul"), ("ago", "aug"), ("set", "sep"),
31+
("out", "oct"), ("nov", "nov"), ("dez", "dec")
32+
]
33+
for n, month_names in enumerate(months, 1):
34+
if month_text in month_names:
35+
month_number = n
36+
break
37+
date = datetime(int(year_text), month_number, 1)
3638
else:
37-
yyyy = "[0-9]{4}"
38-
if re.match(yyyy, date_string):
39-
year = int(date_string)
40-
month = 12
41-
day = 31
39+
try:
40+
day, month, year = [int(date_part) for date_part in date_string.split("/")]
4241
date = datetime(year, month, day)
43-
else:
44-
return date_string # returns original value if cant parse
45-
42+
except ValueError:
43+
# return the original value if we cant parse it
44+
return date_string
4645
return date

sgs/search.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,16 +90,16 @@ def parse_search_response(response, language: str) -> Optional[list]:
9090
cols["source"]: "source",
9191
}
9292
df.rename(columns=col_names, inplace=True)
93-
cols = [
93+
cols_names = [
9494
"code",
9595
"name",
9696
"unit",
9797
"frequency",
9898
"first_value",
9999
"last_value",
100100
"source",
101-
]
102-
df = df[cols]
101+
] # type: ignore
102+
df = df[cols_names]
103103
except (IndexError, KeyError):
104104
return None
105105
else:
@@ -170,7 +170,7 @@ def search_ts(query: Union[int, str], language: str) -> Optional[list]:
170170
params["texto"] = query
171171
params["hdTipoPesquisa"] = 6
172172

173-
response = session.post(url, params=params, timeout=10)
173+
response = session.post(url, params=params, timeout=10) # type: ignore
174174
response.raise_for_status()
175175

176176
results = parse_search_response(response, language)

sgs/ts.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@ def time_serie(ts_code: int, start: str, end: str, strict: bool = False) -> pd.S
3434
2018-01-05 0.026444
3535
2018-01-08 0.026444
3636
"""
37-
37+
3838
if strict:
3939
ts_data = api.get_data_with_strict_range(ts_code, start, end)
4040
else:
4141
ts_data = api.get_data(ts_code, start, end)
42-
42+
4343
values = []
4444
index = []
4545
for i in ts_data:
@@ -48,4 +48,4 @@ def time_serie(ts_code: int, start: str, end: str, strict: bool = False) -> pd.S
4848

4949
# Transform empty strings in null values
5050
values = [np.nan if value == "" else value for value in values]
51-
return pd.Series(values, index, name=ts_code, dtype=np.float)
51+
return pd.Series(values, index, name=ts_code, dtype=np.float64) # type: ignore

tests/test_api.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ def test_get_data():
1010
data = api.get_data(4, "02/01/2018", "31/01/2018")
1111
assert isinstance(data, list)
1212
assert len(data) == NUMBER_OF_LINES
13-
13+
14+
1415
@pytest.mark.api
1516
def test_get_data_with_strict_range():
1617
NUMBER_OF_LINES = 0

tests/test_ts.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,23 @@
88
def test_time_serie():
99
ts = time_serie(4, "02/01/2018", "31/01/2018")
1010
assert len(ts) == 20
11-
assert ts.dtype == np.float
11+
assert ts.dtype == np.float64
1212

1313
@pytest.mark.ts
1414
def test_ts_with_null_values():
1515
# Issue #28
1616
ts = time_serie(21554, start="31/12/1992", end="01/06/2019")
17-
data = ts.loc['1994-04-01']
17+
data = ts.loc['1994-04-01']
1818
assert np.isnan(data) == True
19-
19+
2020
@pytest.mark.ts
2121
def test_ts_with_strict_as_false():
2222
ts = time_serie(20577, "17/08/2019", "18/08/2019")
2323
assert len(ts) == 1
24-
assert ts.dtype == np.float
25-
24+
assert ts.dtype == np.float64
25+
2626
@pytest.mark.ts
2727
def test_ts_with_strict_as_true():
2828
ts = time_serie(20577, "17/08/2019", "18/08/2019", True)
2929
assert len(ts) == 0
30-
assert ts.dtype == np.float
30+
assert ts.dtype == np.float64

0 commit comments

Comments
 (0)