Update datetime parse helper
Allow non T in isotime format, add non T normal datetime parsing
This commit is contained in:
10
README.md
10
README.md
@@ -52,7 +52,7 @@ Have the following setup in `project.toml`
|
|||||||
|
|
||||||
```toml
|
```toml
|
||||||
[[tool.uv.index]]
|
[[tool.uv.index]]
|
||||||
name = "egra-gitea"
|
name = "opj-pypi"
|
||||||
url = "https://git.egplusww.jp/api/packages/PyPI/pypi/simple/"
|
url = "https://git.egplusww.jp/api/packages/PyPI/pypi/simple/"
|
||||||
publish-url = "https://git.egplusww.jp/api/packages/PyPI/pypi"
|
publish-url = "https://git.egplusww.jp/api/packages/PyPI/pypi"
|
||||||
explicit = true
|
explicit = true
|
||||||
@@ -60,15 +60,15 @@ explicit = true
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
uv build
|
uv build
|
||||||
uv publish --index egra-gitea --token <gitea token>
|
uv publish --index opj-pypi --token <gitea token>
|
||||||
```
|
```
|
||||||
|
|
||||||
## Test package
|
## Use package
|
||||||
|
|
||||||
We must set the full index URL here because we run with "--no-project"
|
We must set the full index URL here because we run with "--no-project"
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
uv run --with corelibs --index egra-gitea=https://git.egplusww.jp/api/packages/PyPI/pypi/simple/ --no-project -- python -c "import corelibs"
|
uv run --with corelibs --index opj-pypi=https://git.egplusww.jp/api/packages/PyPI/pypi/simple/ --no-project -- python -c "import corelibs"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Python tests
|
### Python tests
|
||||||
@@ -101,7 +101,7 @@ uv run test-run/<script>
|
|||||||
This will also add the index entry
|
This will also add the index entry
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
uv add corelibs --index egra-gitea=https://git.egplusww.jp/api/packages/PyPI/pypi/simple/
|
uv add corelibs --index opj-pypi=https://git.egplusww.jp/api/packages/PyPI/pypi/simple/
|
||||||
```
|
```
|
||||||
|
|
||||||
## Python venv setup
|
## Python venv setup
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ dependencies = [
|
|||||||
|
|
||||||
# MARK: build target
|
# MARK: build target
|
||||||
[[tool.uv.index]]
|
[[tool.uv.index]]
|
||||||
name = "egra-gitea"
|
name = "opj-pypi"
|
||||||
url = "https://git.egplusww.jp/api/packages/PyPI/pypi/simple/"
|
url = "https://git.egplusww.jp/api/packages/PyPI/pypi/simple/"
|
||||||
publish-url = "https://git.egplusww.jp/api/packages/PyPI/pypi"
|
publish-url = "https://git.egplusww.jp/api/packages/PyPI/pypi"
|
||||||
explicit = true
|
explicit = true
|
||||||
@@ -63,12 +63,13 @@ ignore = [
|
|||||||
[tool.pylint.MASTER]
|
[tool.pylint.MASTER]
|
||||||
# this is for the tests/etc folders
|
# this is for the tests/etc folders
|
||||||
init-hook='import sys; sys.path.append("src/")'
|
init-hook='import sys; sys.path.append("src/")'
|
||||||
|
|
||||||
|
# MARK: Testing
|
||||||
[tool.pytest.ini_options]
|
[tool.pytest.ini_options]
|
||||||
testpaths = [
|
testpaths = [
|
||||||
"tests",
|
"tests",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
[tool.coverage.run]
|
[tool.coverage.run]
|
||||||
omit = [
|
omit = [
|
||||||
"*/tests/*",
|
"*/tests/*",
|
||||||
|
|||||||
@@ -159,10 +159,14 @@ def parse_flexible_date(
|
|||||||
|
|
||||||
# Try different parsing methods
|
# Try different parsing methods
|
||||||
parsers: list[Callable[[str], datetime]] = [
|
parsers: list[Callable[[str], datetime]] = [
|
||||||
# ISO 8601 format
|
# ISO 8601 format, also with missing "T"
|
||||||
lambda x: datetime.fromisoformat(x), # pylint: disable=W0108
|
lambda x: datetime.fromisoformat(x), # pylint: disable=W0108
|
||||||
|
lambda x: datetime.fromisoformat(x.replace(' ', 'T')), # pylint: disable=W0108
|
||||||
# Simple date format
|
# Simple date format
|
||||||
lambda x: datetime.strptime(x, "%Y-%m-%d"),
|
lambda x: datetime.strptime(x, "%Y-%m-%d"),
|
||||||
|
# datetime without T
|
||||||
|
lambda x: datetime.strptime(x, "%Y-%m-%d %H:%M:%S"),
|
||||||
|
lambda x: datetime.strptime(x, "%Y-%m-%d %H:%M:%S.%f"),
|
||||||
# Alternative ISO formats (fallback)
|
# Alternative ISO formats (fallback)
|
||||||
lambda x: datetime.strptime(x, "%Y-%m-%dT%H:%M:%S"),
|
lambda x: datetime.strptime(x, "%Y-%m-%dT%H:%M:%S"),
|
||||||
lambda x: datetime.strptime(x, "%Y-%m-%dT%H:%M:%S.%f"),
|
lambda x: datetime.strptime(x, "%Y-%m-%dT%H:%M:%S.%f"),
|
||||||
|
|||||||
0
tests/integration/fixtures/__init__.py
Normal file
0
tests/integration/fixtures/__init__.py
Normal file
@@ -275,6 +275,53 @@ class TestParseFlexibleDate:
|
|||||||
assert isinstance(result, datetime)
|
assert isinstance(result, datetime)
|
||||||
assert result.tzinfo is not None
|
assert result.tzinfo is not None
|
||||||
|
|
||||||
|
def test_parse_flexible_date_missing_t_with_timezone_shift(self):
|
||||||
|
"""Test parse_flexible_date with timezone shift"""
|
||||||
|
result = parse_flexible_date('2023-12-25 15:30:45+00:00', timezone_tz='Asia/Tokyo', shift_time_zone=True)
|
||||||
|
assert isinstance(result, datetime)
|
||||||
|
assert result.tzinfo is not None
|
||||||
|
|
||||||
|
def test_parse_flexible_date_space_separated_datetime(self):
|
||||||
|
"""Test parse_flexible_date with space-separated datetime format"""
|
||||||
|
result = parse_flexible_date('2023-12-25 15:30:45')
|
||||||
|
assert isinstance(result, datetime)
|
||||||
|
assert result.year == 2023
|
||||||
|
assert result.month == 12
|
||||||
|
assert result.day == 25
|
||||||
|
assert result.hour == 15
|
||||||
|
assert result.minute == 30
|
||||||
|
assert result.second == 45
|
||||||
|
|
||||||
|
def test_parse_flexible_date_space_separated_with_microseconds(self):
|
||||||
|
"""Test parse_flexible_date with space-separated datetime and microseconds"""
|
||||||
|
result = parse_flexible_date('2023-12-25 15:30:45.123456')
|
||||||
|
assert isinstance(result, datetime)
|
||||||
|
assert result.year == 2023
|
||||||
|
assert result.month == 12
|
||||||
|
assert result.day == 25
|
||||||
|
assert result.hour == 15
|
||||||
|
assert result.minute == 30
|
||||||
|
assert result.second == 45
|
||||||
|
assert result.microsecond == 123456
|
||||||
|
|
||||||
|
def test_parse_flexible_date_t_separated_datetime(self):
|
||||||
|
"""Test parse_flexible_date with T-separated datetime (alternative ISO format)"""
|
||||||
|
result = parse_flexible_date('2023-12-25T15:30:45')
|
||||||
|
assert isinstance(result, datetime)
|
||||||
|
assert result.year == 2023
|
||||||
|
assert result.month == 12
|
||||||
|
assert result.day == 25
|
||||||
|
assert result.hour == 15
|
||||||
|
assert result.minute == 30
|
||||||
|
assert result.second == 45
|
||||||
|
|
||||||
|
def test_parse_flexible_date_t_separated_with_microseconds(self):
|
||||||
|
"""Test parse_flexible_date with T-separated datetime and microseconds"""
|
||||||
|
result = parse_flexible_date('2023-12-25T15:30:45.123456')
|
||||||
|
assert isinstance(result, datetime)
|
||||||
|
assert result.year == 2023
|
||||||
|
assert result.microsecond == 123456
|
||||||
|
|
||||||
def test_parse_flexible_date_invalid_format(self):
|
def test_parse_flexible_date_invalid_format(self):
|
||||||
"""Test parse_flexible_date with invalid format returns None"""
|
"""Test parse_flexible_date with invalid format returns None"""
|
||||||
result = parse_flexible_date('invalid-date')
|
result = parse_flexible_date('invalid-date')
|
||||||
|
|||||||
Reference in New Issue
Block a user