ecos-reader 0.3.0__tar.gz → 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/.github/workflows/ci.yml +4 -4
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/.github/workflows/codeql.yml +3 -3
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/.github/workflows/docs.yml +3 -3
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/.github/workflows/nightly-e2e.yml +2 -2
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/.github/workflows/publish.yml +6 -6
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/.github/workflows/security.yml +2 -2
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/CHANGELOG.md +17 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/PKG-INFO +1 -1
- ecos_reader-0.4.0/docs/user-guide/migration-frequency.md +31 -0
- ecos_reader-0.4.0/docs/user-guide/migration-v0.4.0.md +62 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/pyproject.toml +1 -1
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/src/ecos/__init__.py +1 -6
- ecos_reader-0.4.0/src/ecos/indicators/_frequency.py +54 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/src/ecos/indicators/growth.py +6 -24
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/src/ecos/indicators/interest_rate.py +2 -6
- ecos_reader-0.4.0/tests/indicators/test_frequency.py +92 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/tests/indicators/test_interest_rate.py +1 -1
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/tests/test_e2e_indicators.py +1 -1
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/uv.lock +1 -1
- ecos_reader-0.3.0/docs/user-guide/migration-frequency.md +0 -84
- ecos_reader-0.3.0/src/ecos/indicators/_frequency.py +0 -105
- ecos_reader-0.3.0/tests/indicators/test_frequency.py +0 -152
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/.github/CODEOWNERS +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/.github/dependabot.yml +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/.gitignore +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/.pre-commit-config.yaml +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/API_SPEC.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/CONTRIBUTING.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/IMPLEMENTATION_STATUS.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/LICENSE +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/README.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/docs/api-reference/client.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/docs/api-reference/exceptions.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/docs/api-reference/indicators.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/docs/api-reference/overview.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/docs/api-reference/statistic-item-list.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/docs/api-reference/statistic-meta.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/docs/api-reference/statistic-search.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/docs/api-reference/statistic-table-list.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/docs/api-reference/statistic-top-100.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/docs/api-reference/statistic-word.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/docs/development/contributing.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/docs/development/indicator-registry.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/docs/development/partial-coverage-redesign.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/docs/development/release.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/docs/examples/basic.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/docs/examples/dashboard.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/docs/getting-started/installation.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/docs/getting-started/quickstart.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/docs/index.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/docs/reference/ecos_code_catalog.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/docs/user-guide/advanced.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/docs/user-guide/basic-usage.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/docs/user-guide/financial-markets.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/docs/user-guide/fiscal.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/docs/user-guide/growth.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/docs/user-guide/interest-rates.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/docs/user-guide/migration-v0.3.0.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/docs/user-guide/money.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/docs/user-guide/prices.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/ecos_all_statistics.csv +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/ecos_implementation_status.csv +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/examples/basic_usage.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/examples/macro_dashboard.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/mkdocs.yml +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/public-api-docs/statistic-item-list.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/public-api-docs/statistic-meta.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/public-api-docs/statistic-search.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/public-api-docs/statistic-table-list.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/public-api-docs/statistic-top-100.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/public-api-docs/statistic-word.md +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/scripts/audit_codes.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/scripts/gen_indicator_registry_doc.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/src/ecos/cache.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/src/ecos/client.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/src/ecos/config.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/src/ecos/constants.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/src/ecos/exceptions.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/src/ecos/indicators/__init__.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/src/ecos/indicators/_dates.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/src/ecos/indicators/_registry.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/src/ecos/indicators/_subcategory.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/src/ecos/indicators/bond.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/src/ecos/indicators/fiscal.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/src/ecos/indicators/money.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/src/ecos/indicators/prices.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/src/ecos/indicators/stock.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/src/ecos/logging.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/src/ecos/metrics.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/src/ecos/parser.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/src/ecos/py.typed +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/src/ecos/types.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/tests/__init__.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/tests/conftest.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/tests/indicators/__init__.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/tests/indicators/test_bond.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/tests/indicators/test_dates.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/tests/indicators/test_fiscal.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/tests/indicators/test_growth.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/tests/indicators/test_money.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/tests/indicators/test_prices.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/tests/indicators/test_registry.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/tests/indicators/test_stock.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/tests/indicators/test_subcategory.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/tests/test_cache.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/tests/test_client.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/tests/test_codes_live.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/tests/test_config.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/tests/test_e2e.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/tests/test_exceptions.py +0 -0
- {ecos_reader-0.3.0 → ecos_reader-0.4.0}/tests/test_parser.py +0 -0
|
@@ -27,10 +27,10 @@ jobs:
|
|
|
27
27
|
name: Lint & type-check
|
|
28
28
|
runs-on: ubuntu-latest
|
|
29
29
|
steps:
|
|
30
|
-
- uses: actions/checkout@
|
|
30
|
+
- uses: actions/checkout@v6
|
|
31
31
|
|
|
32
32
|
- name: Install uv
|
|
33
|
-
uses: astral-sh/setup-uv@
|
|
33
|
+
uses: astral-sh/setup-uv@v8.1.0
|
|
34
34
|
with:
|
|
35
35
|
enable-cache: true
|
|
36
36
|
|
|
@@ -58,10 +58,10 @@ jobs:
|
|
|
58
58
|
matrix:
|
|
59
59
|
python-version: ["3.10", "3.11", "3.12"]
|
|
60
60
|
steps:
|
|
61
|
-
- uses: actions/checkout@
|
|
61
|
+
- uses: actions/checkout@v6
|
|
62
62
|
|
|
63
63
|
- name: Install uv
|
|
64
|
-
uses: astral-sh/setup-uv@
|
|
64
|
+
uses: astral-sh/setup-uv@v8.1.0
|
|
65
65
|
with:
|
|
66
66
|
enable-cache: true
|
|
67
67
|
|
|
@@ -24,15 +24,15 @@ jobs:
|
|
|
24
24
|
security-events: write
|
|
25
25
|
contents: read
|
|
26
26
|
steps:
|
|
27
|
-
- uses: actions/checkout@
|
|
27
|
+
- uses: actions/checkout@v6
|
|
28
28
|
|
|
29
29
|
- name: Initialize CodeQL
|
|
30
|
-
uses: github/codeql-action/init@
|
|
30
|
+
uses: github/codeql-action/init@v4
|
|
31
31
|
with:
|
|
32
32
|
languages: python
|
|
33
33
|
queries: security-extended
|
|
34
34
|
|
|
35
35
|
- name: Perform CodeQL Analysis
|
|
36
|
-
uses: github/codeql-action/analyze@
|
|
36
|
+
uses: github/codeql-action/analyze@v4
|
|
37
37
|
with:
|
|
38
38
|
category: "/language:python"
|
|
@@ -15,10 +15,10 @@ jobs:
|
|
|
15
15
|
deploy:
|
|
16
16
|
runs-on: ubuntu-latest
|
|
17
17
|
steps:
|
|
18
|
-
- uses: actions/checkout@
|
|
18
|
+
- uses: actions/checkout@v6
|
|
19
19
|
|
|
20
20
|
- name: Install uv
|
|
21
|
-
uses: astral-sh/setup-uv@
|
|
21
|
+
uses: astral-sh/setup-uv@v8.1.0
|
|
22
22
|
with:
|
|
23
23
|
enable-cache: true
|
|
24
24
|
|
|
@@ -32,7 +32,7 @@ jobs:
|
|
|
32
32
|
|
|
33
33
|
- name: Deploy to GitHub Pages
|
|
34
34
|
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
35
|
-
uses: peaceiris/actions-gh-pages@
|
|
35
|
+
uses: peaceiris/actions-gh-pages@v4
|
|
36
36
|
with:
|
|
37
37
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
38
38
|
publish_dir: ./site
|
|
@@ -24,10 +24,10 @@ jobs:
|
|
|
24
24
|
# fork에는 secret이 없어 의미가 없으므로 upstream 레포에서만 실행
|
|
25
25
|
if: github.repository == 'choo121600/ecos-reader'
|
|
26
26
|
steps:
|
|
27
|
-
- uses: actions/checkout@
|
|
27
|
+
- uses: actions/checkout@v6
|
|
28
28
|
|
|
29
29
|
- name: Install uv
|
|
30
|
-
uses: astral-sh/setup-uv@
|
|
30
|
+
uses: astral-sh/setup-uv@v8.1.0
|
|
31
31
|
with:
|
|
32
32
|
enable-cache: true
|
|
33
33
|
|
|
@@ -27,10 +27,10 @@ jobs:
|
|
|
27
27
|
runs-on: ubuntu-latest
|
|
28
28
|
|
|
29
29
|
steps:
|
|
30
|
-
- uses: actions/checkout@
|
|
30
|
+
- uses: actions/checkout@v6
|
|
31
31
|
|
|
32
32
|
- name: Set up Python
|
|
33
|
-
uses: actions/setup-python@
|
|
33
|
+
uses: actions/setup-python@v6
|
|
34
34
|
with:
|
|
35
35
|
python-version: '3.10'
|
|
36
36
|
|
|
@@ -43,7 +43,7 @@ jobs:
|
|
|
43
43
|
run: python -m build
|
|
44
44
|
|
|
45
45
|
- name: Store the distribution packages
|
|
46
|
-
uses: actions/upload-artifact@
|
|
46
|
+
uses: actions/upload-artifact@v7
|
|
47
47
|
with:
|
|
48
48
|
name: python-package-distributions
|
|
49
49
|
path: dist/
|
|
@@ -61,7 +61,7 @@ jobs:
|
|
|
61
61
|
|
|
62
62
|
steps:
|
|
63
63
|
- name: Download all the dists
|
|
64
|
-
uses: actions/download-artifact@
|
|
64
|
+
uses: actions/download-artifact@v8
|
|
65
65
|
with:
|
|
66
66
|
name: python-package-distributions
|
|
67
67
|
path: dist/
|
|
@@ -78,10 +78,10 @@ jobs:
|
|
|
78
78
|
contents: write # IMPORTANT: mandatory for creating releases
|
|
79
79
|
|
|
80
80
|
steps:
|
|
81
|
-
- uses: actions/checkout@
|
|
81
|
+
- uses: actions/checkout@v6
|
|
82
82
|
|
|
83
83
|
- name: Download all the dists
|
|
84
|
-
uses: actions/download-artifact@
|
|
84
|
+
uses: actions/download-artifact@v8
|
|
85
85
|
with:
|
|
86
86
|
name: python-package-distributions
|
|
87
87
|
path: dist/
|
|
@@ -5,6 +5,22 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.4.0] - 2026-05-31
|
|
9
|
+
|
|
10
|
+
> Epic #57(Deprecation 정리)의 **BREAKING** 릴리스. v0.2.2(#20)에서
|
|
11
|
+
> `EcosDeprecationWarning` 과 함께 deprecated 처리됐던 레거시 frequency
|
|
12
|
+
> 단일 문자 표기를 제거합니다. 마이그레이션: 사용자 가이드 > v0.4.0 마이그레이션.
|
|
13
|
+
|
|
14
|
+
### Removed (BREAKING)
|
|
15
|
+
- 레거시 `frequency` 단일 문자 표기(`"D"`/`"M"`/`"Q"`/`"A"`) 제거. 이제 정식
|
|
16
|
+
어휘(`"daily"`/`"monthly"`/`"quarterly"`/`"annual"`)만 허용하며, 정식이 아닌
|
|
17
|
+
값은 경고 없이 즉시 `ValueError` 를 발생시킵니다. (#65)
|
|
18
|
+
- `EcosDeprecationWarning` 클래스 및 공개 export 제거. frequency 단일 문자
|
|
19
|
+
표기 전용 경고였으며, 해당 표기 제거와 함께 더 이상 노출되지 않습니다. (#65)
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
- v0.4.0 마이그레이션 가이드(사용자 가이드). (#66)
|
|
23
|
+
|
|
8
24
|
## [0.3.0] - 2026-05-31
|
|
9
25
|
|
|
10
26
|
> Epic #56(Partial-coverage 재설계)의 **BREAKING** 릴리스. 함수명이 전체 시리즈를
|
|
@@ -320,6 +336,7 @@ v0.1.6 라이브 e2e 검증에서 드러난 follow-up(#2 Reliability epic)을
|
|
|
320
336
|
- 기본 사용법 (`examples/basic_usage.py`)
|
|
321
337
|
- 거시경제 대시보드 (`examples/macro_dashboard.py`)
|
|
322
338
|
|
|
339
|
+
[0.4.0]: https://github.com/choo121600/ecos-reader/compare/v0.3.0...v0.4.0
|
|
323
340
|
[0.3.0]: https://github.com/choo121600/ecos-reader/compare/v0.2.2...v0.3.0
|
|
324
341
|
[0.1.2]: https://github.com/choo121600/ecos-reader/compare/v0.1.1...v0.1.2
|
|
325
342
|
[0.1.1]: https://github.com/choo121600/ecos-reader/compare/v0.1.0...v0.1.1
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frequency 표기 마이그레이션 (#20, #57)
|
|
2
|
+
|
|
3
|
+
이 문서는 `frequency` 인자 표기 변경(레거시 단일 문자 → 정식 풀네임)에 대한 안내입니다.
|
|
4
|
+
v0.4.0(#57)부터 레거시 단일 문자 표기는 **제거**되어 더 이상 허용되지 않습니다.
|
|
5
|
+
|
|
6
|
+
## 한눈에 보기
|
|
7
|
+
|
|
8
|
+
| 카테고리 | 함수 | 레거시(제거됨) | 정식(필수) |
|
|
9
|
+
|---|---|---|---|
|
|
10
|
+
| 성장 | `get_gdp`, `get_gdp_deflator` 등 | `Q`, `A` | `quarterly`, `annual` |
|
|
11
|
+
| 금리 | `get_base_rate` | `D`, `M` | `daily`, `monthly` |
|
|
12
|
+
| 주식 | `get_stock_index` | (없음) | `daily`, `monthly` |
|
|
13
|
+
|
|
14
|
+
## 권장 변경
|
|
15
|
+
|
|
16
|
+
```python
|
|
17
|
+
# Before (v0.3.x 이하, 이제 ValueError)
|
|
18
|
+
df = ecos.get_gdp(frequency="Q")
|
|
19
|
+
|
|
20
|
+
# After (정식)
|
|
21
|
+
df = ecos.get_gdp(frequency="quarterly")
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## 동작/타임라인
|
|
25
|
+
|
|
26
|
+
- v0.2.2: 정식 어휘 도입. 레거시 단일 문자는 `EcosDeprecationWarning` 과 함께 계속 동작.
|
|
27
|
+
- **v0.4.0: 레거시 단일 문자 제거.** 이제 정식 어휘만 허용하며, 정식이 아닌
|
|
28
|
+
값은 경고 없이 즉시 `ValueError` 입니다. frequency 전용 경고였던
|
|
29
|
+
`EcosDeprecationWarning` 도 함께 제거되었습니다.
|
|
30
|
+
|
|
31
|
+
v0.4.0 변경 상세는 [v0.4.0 마이그레이션](migration-v0.4.0.md) 을 참고하세요.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# v0.4.0 마이그레이션 가이드
|
|
2
|
+
|
|
3
|
+
v0.4.0은 deprecation cycle이 만료된 항목을 제거하는 **BREAKING** 릴리스입니다.
|
|
4
|
+
v0.2.2(#20)에서 `EcosDeprecationWarning` 과 함께 deprecated 처리된 레거시
|
|
5
|
+
frequency 단일 문자 표기가 제거되었습니다.
|
|
6
|
+
|
|
7
|
+
## 무엇이 바뀌었나
|
|
8
|
+
|
|
9
|
+
- 레거시 frequency 단일 문자 표기(`"D"` / `"M"` / `"Q"` / `"A"`)가 **제거**되었습니다.
|
|
10
|
+
- 이제 정식(canonical) 어휘만 허용합니다.
|
|
11
|
+
|
|
12
|
+
| 레거시 (제거됨) | 정식 어휘 |
|
|
13
|
+
| :-------------- | :---------- |
|
|
14
|
+
| `"D"` | `"daily"` |
|
|
15
|
+
| `"M"` | `"monthly"` |
|
|
16
|
+
| `"Q"` | `"quarterly"` |
|
|
17
|
+
| `"A"` | `"annual"` |
|
|
18
|
+
|
|
19
|
+
- 정식이 아닌 값은 경고 없이 **즉시 `ValueError`** 를 발생시킵니다.
|
|
20
|
+
(이전에는 레거시 표기를 `EcosDeprecationWarning` 과 함께 통과시켰습니다.)
|
|
21
|
+
- frequency 전용 경고였던 `EcosDeprecationWarning` 클래스가 제거되어
|
|
22
|
+
`ecos` 패키지에서 더 이상 export되지 않습니다.
|
|
23
|
+
|
|
24
|
+
## 영향을 받는 함수
|
|
25
|
+
|
|
26
|
+
frequency 인자를 받는 지표 함수들입니다.
|
|
27
|
+
|
|
28
|
+
- `get_gdp` 등 성장 지표: `"quarterly"` / `"annual"`
|
|
29
|
+
- `get_base_rate` 등 금리 지표: `"daily"` / `"monthly"`
|
|
30
|
+
- `get_stock_index` 등 주식 지표: `"daily"` / `"monthly"`
|
|
31
|
+
|
|
32
|
+
## 코드 변경 방법
|
|
33
|
+
|
|
34
|
+
레거시 단일 문자를 정식 어휘로 교체하세요.
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
import ecos
|
|
38
|
+
|
|
39
|
+
# 이전 (v0.3.x 이하) — deprecated, v0.4.0에서 제거됨 (이제 ValueError)
|
|
40
|
+
df = ecos.get_gdp(frequency="Q")
|
|
41
|
+
df = ecos.get_base_rate(frequency="D")
|
|
42
|
+
|
|
43
|
+
# 이후 (v0.4.0+)
|
|
44
|
+
df = ecos.get_gdp(frequency="quarterly")
|
|
45
|
+
df = ecos.get_base_rate(frequency="daily")
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
`EcosDeprecationWarning` 을 직접 참조하던 코드가 있다면 제거하세요.
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
# 이전 — 더 이상 동작하지 않음 (ImportError)
|
|
52
|
+
import warnings
|
|
53
|
+
from ecos import EcosDeprecationWarning
|
|
54
|
+
warnings.simplefilter("ignore", EcosDeprecationWarning)
|
|
55
|
+
|
|
56
|
+
# 이후 — 해당 경고가 제거되었으므로 이 코드는 불필요합니다.
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## 참고
|
|
60
|
+
|
|
61
|
+
- `_registry.py` 의 `DateFormat = Literal["D", "M", "Q", "A"]` 는 ECOS API의
|
|
62
|
+
내부 period 코드로, frequency 어휘와 무관하며 변경되지 않았습니다.
|
|
@@ -20,7 +20,7 @@ Examples
|
|
|
20
20
|
|
|
21
21
|
from __future__ import annotations
|
|
22
22
|
|
|
23
|
-
__version__ = "0.
|
|
23
|
+
__version__ = "0.4.0"
|
|
24
24
|
__author__ = "yeonguk"
|
|
25
25
|
|
|
26
26
|
# Config API
|
|
@@ -86,9 +86,6 @@ from .indicators import (
|
|
|
86
86
|
list_indicators,
|
|
87
87
|
)
|
|
88
88
|
|
|
89
|
-
# Warnings
|
|
90
|
-
from .indicators._frequency import EcosDeprecationWarning
|
|
91
|
-
|
|
92
89
|
# Logging API
|
|
93
90
|
from .logging import setup_logging
|
|
94
91
|
|
|
@@ -120,8 +117,6 @@ __all__ = [
|
|
|
120
117
|
"EcosRateLimitError",
|
|
121
118
|
"EcosServerError",
|
|
122
119
|
"EcosValidationError",
|
|
123
|
-
# Warnings
|
|
124
|
-
"EcosDeprecationWarning",
|
|
125
120
|
# 재정 지표
|
|
126
121
|
"get_fiscal_balance",
|
|
127
122
|
# 주식시장 지표
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""
|
|
2
|
+
frequency 어휘 통일 (#20, #57).
|
|
3
|
+
|
|
4
|
+
과거에는 카테고리마다 ``frequency`` 값 표기가 달랐고, 레거시 단일 문자
|
|
5
|
+
표기(``D``/``M``/``Q``/``A``)를 :class:`EcosDeprecationWarning` 과 함께
|
|
6
|
+
한시적으로 허용했다.
|
|
7
|
+
|
|
8
|
+
v0.4.0(#57)부터 레거시 표기는 **제거**되었으며, 정식(canonical) 풀네임
|
|
9
|
+
어휘만 허용한다::
|
|
10
|
+
|
|
11
|
+
daily | monthly | quarterly | annual
|
|
12
|
+
|
|
13
|
+
정식이 아닌 값은 경고 없이 즉시 :class:`ValueError` 로 처리한다.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def normalize_frequency(
|
|
20
|
+
value: str,
|
|
21
|
+
*,
|
|
22
|
+
allowed: tuple[str, ...],
|
|
23
|
+
func_name: str,
|
|
24
|
+
) -> str:
|
|
25
|
+
"""frequency 값을 검증한다.
|
|
26
|
+
|
|
27
|
+
Parameters
|
|
28
|
+
----------
|
|
29
|
+
value : str
|
|
30
|
+
호출자가 전달한 frequency 값
|
|
31
|
+
(정식 어휘 ``daily``/``monthly``/``quarterly``/``annual``).
|
|
32
|
+
allowed : tuple of str
|
|
33
|
+
해당 지표가 지원하는 정식 frequency 값의 튜플
|
|
34
|
+
(예: ``("quarterly", "annual")``).
|
|
35
|
+
func_name : str
|
|
36
|
+
에러 메시지에 쓰이는 공개 함수명(예: ``"get_gdp"``).
|
|
37
|
+
|
|
38
|
+
Returns
|
|
39
|
+
-------
|
|
40
|
+
str
|
|
41
|
+
검증된 frequency 값.
|
|
42
|
+
|
|
43
|
+
Raises
|
|
44
|
+
------
|
|
45
|
+
ValueError
|
|
46
|
+
``value`` 가 ``allowed`` 에 없을 때. 레거시 단일 문자 표기
|
|
47
|
+
(``D``/``M``/``Q``/``A``)는 v0.4.0에서 제거되었으므로 동일하게
|
|
48
|
+
``ValueError`` 로 처리된다.
|
|
49
|
+
"""
|
|
50
|
+
if value not in allowed:
|
|
51
|
+
allowed_str = " 또는 ".join(repr(a) for a in allowed)
|
|
52
|
+
raise ValueError(f"{func_name}(): frequency는 {allowed_str} 중 하나여야 합니다.")
|
|
53
|
+
|
|
54
|
+
return value
|
|
@@ -34,7 +34,7 @@ if TYPE_CHECKING:
|
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
def get_gdp(
|
|
37
|
-
frequency: Literal["quarterly", "annual"
|
|
37
|
+
frequency: Literal["quarterly", "annual"] = "quarterly",
|
|
38
38
|
basis: Literal["real", "nominal"] = "real",
|
|
39
39
|
start_date: str | None = None,
|
|
40
40
|
end_date: str | None = None,
|
|
@@ -48,9 +48,6 @@ def get_gdp(
|
|
|
48
48
|
조회 주기
|
|
49
49
|
- 'quarterly': 분기 (기본값)
|
|
50
50
|
- 'annual': 연간
|
|
51
|
-
|
|
52
|
-
레거시 'Q'/'A'도 당분간 허용되나 EcosDeprecationWarning과 함께
|
|
53
|
-
deprecated이며 v0.4.0에서 제거됩니다.
|
|
54
51
|
basis : str
|
|
55
52
|
GDP 기준
|
|
56
53
|
- 'real': 실질 GDP (기본값)
|
|
@@ -114,7 +111,7 @@ def get_gdp(
|
|
|
114
111
|
|
|
115
112
|
|
|
116
113
|
def get_gdp_deflator(
|
|
117
|
-
frequency: Literal["quarterly", "annual"
|
|
114
|
+
frequency: Literal["quarterly", "annual"] = "quarterly",
|
|
118
115
|
start_date: str | None = None,
|
|
119
116
|
end_date: str | None = None,
|
|
120
117
|
) -> pd.DataFrame:
|
|
@@ -130,9 +127,6 @@ def get_gdp_deflator(
|
|
|
130
127
|
조회 주기
|
|
131
128
|
- 'quarterly': 분기 (기본값)
|
|
132
129
|
- 'annual': 연간
|
|
133
|
-
|
|
134
|
-
레거시 'Q'/'A'도 당분간 허용되나 EcosDeprecationWarning과 함께
|
|
135
|
-
deprecated이며 v0.4.0에서 제거됩니다.
|
|
136
130
|
start_date : str, optional
|
|
137
131
|
조회 시작일
|
|
138
132
|
end_date : str, optional
|
|
@@ -188,7 +182,7 @@ def get_gdp_deflator(
|
|
|
188
182
|
|
|
189
183
|
|
|
190
184
|
def get_gdp_growth_rate(
|
|
191
|
-
frequency: Literal["quarterly", "annual"
|
|
185
|
+
frequency: Literal["quarterly", "annual"] = "quarterly",
|
|
192
186
|
start_date: str | None = None,
|
|
193
187
|
end_date: str | None = None,
|
|
194
188
|
) -> pd.DataFrame:
|
|
@@ -203,9 +197,6 @@ def get_gdp_growth_rate(
|
|
|
203
197
|
조회 주기
|
|
204
198
|
- 'quarterly': 분기 (기본값)
|
|
205
199
|
- 'annual': 연간
|
|
206
|
-
|
|
207
|
-
레거시 'Q'/'A'도 당분간 허용되나 EcosDeprecationWarning과 함께
|
|
208
|
-
deprecated이며 v0.4.0에서 제거됩니다.
|
|
209
200
|
start_date : str, optional
|
|
210
201
|
조회 시작일
|
|
211
202
|
- 분기: YYYYQN 형식 (예: 2020Q1)
|
|
@@ -271,7 +262,7 @@ def get_gdp_growth_rate(
|
|
|
271
262
|
def get_gdp_by_industry(
|
|
272
263
|
basis: Literal["real", "nominal"] = "real",
|
|
273
264
|
seasonal_adj: bool = True,
|
|
274
|
-
frequency: Literal["quarterly", "annual"
|
|
265
|
+
frequency: Literal["quarterly", "annual"] = "quarterly",
|
|
275
266
|
sub_category: str | None = None,
|
|
276
267
|
start_date: str | None = None,
|
|
277
268
|
end_date: str | None = None,
|
|
@@ -295,9 +286,6 @@ def get_gdp_by_industry(
|
|
|
295
286
|
조회 주기
|
|
296
287
|
- 'quarterly': 분기 (기본값)
|
|
297
288
|
- 'annual': 연간
|
|
298
|
-
|
|
299
|
-
레거시 'Q'/'A'도 당분간 허용되나 EcosDeprecationWarning과 함께
|
|
300
|
-
deprecated이며 v0.4.0에서 제거됩니다.
|
|
301
289
|
sub_category : str, optional
|
|
302
290
|
세부 산업(항목명 또는 item_code1). 지정 시 해당 산업 단일 시계열만
|
|
303
291
|
반환합니다. 미지정 시 전체 산업을 long-format으로 반환합니다.
|
|
@@ -395,7 +383,7 @@ def get_gdp_by_industry(
|
|
|
395
383
|
|
|
396
384
|
def get_gdp_by_expenditure(
|
|
397
385
|
basis: Literal["real", "nominal"] = "real",
|
|
398
|
-
frequency: Literal["quarterly", "annual"
|
|
386
|
+
frequency: Literal["quarterly", "annual"] = "quarterly",
|
|
399
387
|
sub_category: str | None = None,
|
|
400
388
|
start_date: str | None = None,
|
|
401
389
|
end_date: str | None = None,
|
|
@@ -417,9 +405,6 @@ def get_gdp_by_expenditure(
|
|
|
417
405
|
조회 주기
|
|
418
406
|
- 'quarterly': 분기 (기본값)
|
|
419
407
|
- 'annual': 연간
|
|
420
|
-
|
|
421
|
-
레거시 'Q'/'A'도 당분간 허용되나 EcosDeprecationWarning과 함께
|
|
422
|
-
deprecated이며 v0.4.0에서 제거됩니다.
|
|
423
408
|
sub_category : str, optional
|
|
424
409
|
세부 지출항목(항목명 또는 item_code1). 지정 시 해당 항목 단일 시계열만
|
|
425
410
|
반환합니다. 미지정 시 전체 지출항목을 long-format으로 반환합니다.
|
|
@@ -512,7 +497,7 @@ def get_gdp_by_expenditure(
|
|
|
512
497
|
|
|
513
498
|
|
|
514
499
|
def get_gdp_deflator_by_industry(
|
|
515
|
-
frequency: Literal["quarterly", "annual"
|
|
500
|
+
frequency: Literal["quarterly", "annual"] = "quarterly",
|
|
516
501
|
sub_category: str | None = None,
|
|
517
502
|
start_date: str | None = None,
|
|
518
503
|
end_date: str | None = None,
|
|
@@ -530,9 +515,6 @@ def get_gdp_deflator_by_industry(
|
|
|
530
515
|
조회 주기
|
|
531
516
|
- 'quarterly': 분기 (기본값)
|
|
532
517
|
- 'annual': 연간
|
|
533
|
-
|
|
534
|
-
레거시 'Q'/'A'도 당분간 허용되나 EcosDeprecationWarning과 함께
|
|
535
|
-
deprecated이며 v0.4.0에서 제거됩니다.
|
|
536
518
|
sub_category : str, optional
|
|
537
519
|
세부 산업(항목명 또는 item_code1). 지정 시 해당 산업 단일 시계열만
|
|
538
520
|
반환합니다. 미지정 시 전체 산업을 long-format으로 반환합니다.
|
|
@@ -32,7 +32,7 @@ from ._registry import get_indicator
|
|
|
32
32
|
def get_base_rate(
|
|
33
33
|
start_date: str | None = None,
|
|
34
34
|
end_date: str | None = None,
|
|
35
|
-
frequency: Literal["daily", "monthly"
|
|
35
|
+
frequency: Literal["daily", "monthly"] = "monthly",
|
|
36
36
|
) -> pd.DataFrame:
|
|
37
37
|
"""
|
|
38
38
|
한국은행 기준금리를 조회합니다.
|
|
@@ -50,10 +50,6 @@ def get_base_rate(
|
|
|
50
50
|
- 'daily': 일별 (날짜 YYYYMMDD). 기준금리는 변경일에만 갱신되어
|
|
51
51
|
결과가 sparse 합니다 (변경이 없는 날은 행이 없음).
|
|
52
52
|
|
|
53
|
-
레거시 단일 문자(``'M'``/``'D'``)도 당분간 허용되나
|
|
54
|
-
:class:`~ecos.EcosDeprecationWarning` 과 함께 deprecated이며
|
|
55
|
-
v0.4.0에서 제거됩니다.
|
|
56
|
-
|
|
57
53
|
Returns
|
|
58
54
|
-------
|
|
59
55
|
pd.DataFrame
|
|
@@ -74,7 +70,7 @@ def get_base_rate(
|
|
|
74
70
|
|
|
75
71
|
>>> # 일별 (변경일 단위) 조회
|
|
76
72
|
>>> df = ecos.get_base_rate(
|
|
77
|
-
... start_date="20200101", end_date="20231231", frequency="
|
|
73
|
+
... start_date="20200101", end_date="20231231", frequency="daily"
|
|
78
74
|
... )
|
|
79
75
|
"""
|
|
80
76
|
frequency = normalize_frequency( # type: ignore[assignment]
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"""frequency 정규화 동작 검증 (#20, #57).
|
|
2
|
+
|
|
3
|
+
정식 어휘(daily/monthly/quarterly/annual)만 허용한다. 레거시 단일 문자
|
|
4
|
+
(D/M/Q/A)는 v0.4.0(#57)에서 제거되어 즉시 ValueError로 처리된다.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import warnings
|
|
10
|
+
|
|
11
|
+
import pytest
|
|
12
|
+
|
|
13
|
+
from ecos.indicators._frequency import normalize_frequency
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class TestNormalizeFrequencyCanonical:
|
|
17
|
+
"""정식 어휘는 그대로 통과한다."""
|
|
18
|
+
|
|
19
|
+
def test_canonical_passthrough(self):
|
|
20
|
+
for value in ("daily", "monthly", "quarterly", "annual"):
|
|
21
|
+
assert (
|
|
22
|
+
normalize_frequency(
|
|
23
|
+
value,
|
|
24
|
+
allowed=("daily", "monthly", "quarterly", "annual"),
|
|
25
|
+
func_name="test",
|
|
26
|
+
)
|
|
27
|
+
== value
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
def test_canonical_no_warning(self):
|
|
31
|
+
with warnings.catch_warnings():
|
|
32
|
+
warnings.simplefilter("error")
|
|
33
|
+
result = normalize_frequency("monthly", allowed=("monthly",), func_name="test")
|
|
34
|
+
assert result == "monthly"
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class TestNormalizeFrequencyLegacyRemoved:
|
|
38
|
+
"""레거시 단일 문자는 제거되어 즉시 ValueError로 처리된다."""
|
|
39
|
+
|
|
40
|
+
def test_legacy_aliases_raise(self):
|
|
41
|
+
for legacy in ("D", "M", "Q", "A"):
|
|
42
|
+
with pytest.raises(ValueError, match="frequency"):
|
|
43
|
+
normalize_frequency(
|
|
44
|
+
legacy,
|
|
45
|
+
allowed=("daily", "monthly", "quarterly", "annual"),
|
|
46
|
+
func_name="test",
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
def test_legacy_raises_without_warning(self):
|
|
50
|
+
"""레거시 표기는 경고 없이 곧바로 ValueError."""
|
|
51
|
+
with warnings.catch_warnings():
|
|
52
|
+
warnings.simplefilter("error")
|
|
53
|
+
with pytest.raises(ValueError, match="frequency"):
|
|
54
|
+
normalize_frequency("Q", allowed=("quarterly", "annual"), func_name="get_gdp")
|
|
55
|
+
|
|
56
|
+
def test_invalid_raises_valueerror(self):
|
|
57
|
+
with pytest.raises(ValueError, match="frequency"):
|
|
58
|
+
normalize_frequency("W", allowed=("daily", "monthly"), func_name="test")
|
|
59
|
+
|
|
60
|
+
def test_canonical_outside_allowed_raises(self):
|
|
61
|
+
"""정식 어휘라도 allowed에 없으면 ValueError."""
|
|
62
|
+
with pytest.raises(ValueError, match="frequency"):
|
|
63
|
+
normalize_frequency("daily", allowed=("quarterly", "annual"), func_name="test")
|
|
64
|
+
|
|
65
|
+
def test_error_message_includes_func_name(self):
|
|
66
|
+
with pytest.raises(ValueError, match="get_gdp"):
|
|
67
|
+
normalize_frequency("Q", allowed=("quarterly", "annual"), func_name="get_gdp")
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class TestFrequencyWiringPerFunction:
|
|
71
|
+
"""per-function wiring: 레거시 표기는 ValueError로 거부된다."""
|
|
72
|
+
|
|
73
|
+
def test_get_gdp_legacy_quarterly_raises(self):
|
|
74
|
+
"""get_gdp(frequency='Q')는 ValueError."""
|
|
75
|
+
from ecos import get_gdp
|
|
76
|
+
|
|
77
|
+
with pytest.raises(ValueError, match="frequency"):
|
|
78
|
+
get_gdp(frequency="Q", start_date="2024Q1", end_date="2024Q1")
|
|
79
|
+
|
|
80
|
+
def test_get_base_rate_legacy_daily_raises(self):
|
|
81
|
+
"""get_base_rate(frequency='D')는 ValueError."""
|
|
82
|
+
from ecos import get_base_rate
|
|
83
|
+
|
|
84
|
+
with pytest.raises(ValueError, match="frequency"):
|
|
85
|
+
get_base_rate(frequency="D", start_date="20240101", end_date="20241231")
|
|
86
|
+
|
|
87
|
+
def test_get_stock_index_legacy_daily_raises(self):
|
|
88
|
+
"""get_stock_index(frequency='D')는 ValueError."""
|
|
89
|
+
from ecos import get_stock_index
|
|
90
|
+
|
|
91
|
+
with pytest.raises(ValueError, match="frequency"):
|
|
92
|
+
get_stock_index(frequency="D")
|
|
@@ -772,7 +772,7 @@ class TestE2ERegressionV016:
|
|
|
772
772
|
# ---- GDP 연간 fallback (#28) ----
|
|
773
773
|
|
|
774
774
|
def test_gdp_growth_rate_annual_fallback(self):
|
|
775
|
-
"""frequency='
|
|
775
|
+
"""frequency='annual'은 계절조정(분기 전용) 대신 원계열 200Y106으로 fallback해야 함."""
|
|
776
776
|
df = ecos.get_gdp_growth_rate(frequency="annual", start_date="2020", end_date="2023")
|
|
777
777
|
|
|
778
778
|
assert not df.empty
|