Skip to content

Commit

Permalink
Use _StrPath in sphinx.util.i18n (#13050)
Browse files Browse the repository at this point in the history
  • Loading branch information
AA-Turner authored Oct 20, 2024
1 parent cb5318b commit bf77a40
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 43 deletions.
4 changes: 2 additions & 2 deletions sphinx/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -316,9 +316,9 @@ def _init_i18n(self) -> None:
catalog.write_mo(self.config.language,
self.config.gettext_allow_fuzzy_translations)

locale_dirs: list[str | None] = list(repo.locale_dirs)
locale_dirs: list[_StrPath | None] = list(repo.locale_dirs)
locale_dirs += [None]
locale_dirs += [path.join(package_dir, 'locale')]
locale_dirs += [_StrPath(package_dir, 'locale')]

self.translator, has_translation = locale.init(locale_dirs, self.config.language)
if has_translation or self.config.language == 'en':
Expand Down
2 changes: 1 addition & 1 deletion sphinx/environment/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ def find_files(self, config: Config, builder: Builder) -> None:
for docname in self.found_docs:
domain = docname_to_domain(docname, self.config.gettext_compact)
if domain in mo_paths:
self.dependencies[docname].add(mo_paths[domain])
self.dependencies[docname].add(str(mo_paths[domain]))
except OSError as exc:
raise DocumentError(
__('Failed to scan documents in %s: %r') % (self.srcdir, exc)
Expand Down
65 changes: 31 additions & 34 deletions sphinx/util/i18n.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import re
from datetime import datetime
from os import path
from typing import TYPE_CHECKING, NamedTuple
from typing import TYPE_CHECKING

import babel.dates
from babel.messages.mofile import write_mo
Expand All @@ -15,11 +15,11 @@
from sphinx.errors import SphinxError
from sphinx.locale import __
from sphinx.util import logging
from sphinx.util._pathlib import _StrPath
from sphinx.util.osutil import (
SEP,
_last_modified_time,
canon_path,
relpath,
)

if TYPE_CHECKING:
Expand Down Expand Up @@ -64,34 +64,36 @@ def __call__( # NoQA: E704
logger = logging.getLogger(__name__)


class LocaleFileInfoBase(NamedTuple):
base_dir: str
domain: str
charset: str
class CatalogInfo:
__slots__ = ('base_dir', 'domain', 'charset')

def __init__(
self, base_dir: str | os.PathLike[str], domain: str, charset: str
) -> None:
self.base_dir = _StrPath(base_dir)
self.domain = domain
self.charset = charset

class CatalogInfo(LocaleFileInfoBase):
@property
def po_file(self) -> str:
return self.domain + '.po'
return f'{self.domain}.po'

@property
def mo_file(self) -> str:
return self.domain + '.mo'
return f'{self.domain}.mo'

@property
def po_path(self) -> str:
return path.join(self.base_dir, self.po_file)
def po_path(self) -> _StrPath:
return self.base_dir / self.po_file

@property
def mo_path(self) -> str:
return path.join(self.base_dir, self.mo_file)
def mo_path(self) -> _StrPath:
return self.base_dir / self.mo_file

def is_outdated(self) -> bool:
return (
not path.exists(self.mo_path)
or _last_modified_time(self.mo_path) < _last_modified_time(self.po_path)
) # fmt: skip
return not self.mo_path.exists() or (
_last_modified_time(self.mo_path) < _last_modified_time(self.po_path)
)

def write_mo(self, locale: str, use_fuzzy: bool = False) -> None:
with open(self.po_path, encoding=self.charset) as file_po:
Expand All @@ -118,38 +120,33 @@ def __init__(
language: str,
encoding: str,
) -> None:
self.basedir = basedir
self.basedir = _StrPath(basedir)
self._locale_dirs = locale_dirs
self.language = language
self.encoding = encoding

@property
def locale_dirs(self) -> Iterator[str]:
def locale_dirs(self) -> Iterator[_StrPath]:
if not self.language:
return

for locale_dir in self._locale_dirs:
locale_dir = path.join(self.basedir, locale_dir)
locale_path = path.join(locale_dir, self.language, 'LC_MESSAGES')
if path.exists(locale_path):
yield locale_dir
locale_path = self.basedir / locale_dir / self.language / 'LC_MESSAGES'
if locale_path.exists():
yield self.basedir / locale_dir
else:
logger.verbose(__('locale_dir %s does not exist'), locale_path)

@property
def pofiles(self) -> Iterator[tuple[str, str]]:
def pofiles(self) -> Iterator[tuple[_StrPath, _StrPath]]:
for locale_dir in self.locale_dirs:
basedir = path.join(locale_dir, self.language, 'LC_MESSAGES')
for root, dirnames, filenames in os.walk(basedir):
locale_path = locale_dir / self.language / 'LC_MESSAGES'
for abs_path in locale_path.rglob('*.po'):
rel_path = abs_path.relative_to(locale_path)
# skip dot-directories
dot_directories = [d for d in dirnames if d.startswith('.')]
for dirname in dot_directories:
dirnames.remove(dirname)

for filename in filenames:
if filename.endswith('.po'):
fullpath = path.join(root, filename)
yield basedir, relpath(fullpath, basedir)
if any(part.startswith('.') for part in rel_path.parts[:-1]):
continue
yield locale_path, rel_path

@property
def catalogs(self) -> Iterator[CatalogInfo]:
Expand Down
14 changes: 8 additions & 6 deletions tests/test_util/test_util_i18n.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import datetime
import os
import time
from pathlib import Path

import babel
import pytest
Expand All @@ -18,16 +19,16 @@ def test_catalog_info_for_file_and_path():
cat = i18n.CatalogInfo('path', 'domain', 'utf-8')
assert cat.po_file == 'domain.po'
assert cat.mo_file == 'domain.mo'
assert cat.po_path == os.path.join('path', 'domain.po')
assert cat.mo_path == os.path.join('path', 'domain.mo')
assert cat.po_path == str(Path('path', 'domain.po'))
assert cat.mo_path == str(Path('path', 'domain.mo'))


def test_catalog_info_for_sub_domain_file_and_path():
cat = i18n.CatalogInfo('path', 'sub/domain', 'utf-8')
assert cat.po_file == 'sub/domain.po'
assert cat.mo_file == 'sub/domain.mo'
assert cat.po_path == os.path.join('path', 'sub/domain.po')
assert cat.mo_path == os.path.join('path', 'sub/domain.mo')
assert cat.po_path == str(Path('path', 'sub', 'domain.po'))
assert cat.mo_path == str(Path('path', 'sub', 'domain.mo'))


def test_catalog_outdated(tmp_path):
Expand All @@ -48,8 +49,9 @@ def test_catalog_write_mo(tmp_path):
(tmp_path / 'test.po').write_text('#', encoding='utf8')
cat = i18n.CatalogInfo(tmp_path, 'test', 'utf-8')
cat.write_mo('en')
assert os.path.exists(cat.mo_path)
with open(cat.mo_path, 'rb') as f:
mo_path = Path(cat.mo_path)
assert mo_path.exists()
with open(mo_path, 'rb') as f:
assert read_mo(f) is not None


Expand Down

0 comments on commit bf77a40

Please sign in to comment.