Skip to content
This repository has been archived by the owner on Oct 22, 2024. It is now read-only.

Commit

Permalink
Fix FileHandler
Browse files Browse the repository at this point in the history
  • Loading branch information
monosans committed Feb 8, 2024
1 parent 3a10811 commit 5e4949d
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 24 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,5 @@ repos:
- charset-normalizer<3
- rich<14
- types-aiofiles
- typing-extensions<5; python_version < "3.12"
- typing-extensions<5
- uvloop<0.20; implementation_name == "cpython" and (sys_platform == "darwin" or sys_platform == "linux")
35 changes: 35 additions & 0 deletions nitro_generator_checker/fs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from __future__ import annotations

import logging
from pathlib import Path

logger = logging.getLogger(__name__)


def add_permission(
path: Path, permission: int, /, *, missing_ok: bool = False
) -> None:
try:
current_permissions = path.stat().st_mode
new_permissions = current_permissions | permission
if current_permissions != new_permissions:
path.chmod(new_permissions)
logger.info(
"Changed permissions of %s from %o to %o",
path,
current_permissions,
new_permissions,
)
except FileNotFoundError:
if not missing_ok:
raise


def create_or_fix_dir(path: Path, /, *, permission: int) -> None:
try:
path.mkdir(parents=True)
except FileExistsError:
if not path.is_dir():
msg = f"{path} is not a directory"
raise ValueError(msg) from None
add_permission(path, permission)
2 changes: 1 addition & 1 deletion nitro_generator_checker/nitro_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import string
from typing import Iterator

from .typing_compat import override
from typing_extensions import override


class NitroGenerator(Iterator[str]):
Expand Down
21 changes: 14 additions & 7 deletions nitro_generator_checker/result_handlers.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
from __future__ import annotations

import asyncio
import stat
from abc import ABCMeta, abstractmethod
from pathlib import Path

import aiofiles
import aiofiles.os
import aiofiles.ospath
from aiohttp import ClientSession
from typing_extensions import override

from .typing_compat import override
from . import fs
from .utils import asyncify


class ABCResultHandler(metaclass=ABCMeta):
Expand All @@ -26,15 +28,20 @@ class FileHandler(ABCResultHandler):
__slots__ = ("_ready_event", "file_path")

def __init__(self, file_path: str) -> None:
self.file_path = file_path
self.file_path = Path(file_path)
self._ready_event = asyncio.Event()

@override
async def pre_run(self) -> None:
if await aiofiles.ospath.isdir(self.file_path):
msg = "FileName must be a file, not a directory"
if await asyncify(self.file_path.is_file)():
await asyncify(fs.add_permission)(self.file_path, stat.S_IWUSR)
elif await asyncify(self.file_path.exists)():
msg = f"{self.file_path} must be a file"
raise ValueError(msg)
await aiofiles.os.makedirs(self.file_path, exist_ok=True)
else:
await asyncify(fs.create_or_fix_dir)(
self.file_path.parent, permission=stat.S_IWUSR | stat.S_IXUSR
)
self._ready_event.set()

@override
Expand Down
10 changes: 0 additions & 10 deletions nitro_generator_checker/typing_compat.py

This file was deleted.

17 changes: 15 additions & 2 deletions nitro_generator_checker/utils.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
from __future__ import annotations

import asyncio
from typing import Coroutine, Set
import functools
from typing import Callable, Coroutine, Set

import charset_normalizer
from typing_extensions import Any, ParamSpec, TypeVar

T = TypeVar("T")
P = ParamSpec("P")

from .typing_compat import Any

background_tasks: Set[asyncio.Task[Any]] = set()

Expand All @@ -18,3 +22,12 @@ def create_background_task(coro: Coroutine[Any, Any, Any]) -> None:

def bytes_decode(b: bytes) -> str:
return str(charset_normalizer.from_bytes(b)[0])


def asyncify(f: Callable[P, T], /) -> Callable[P, asyncio.Future[T]]:
def wrapper(*args: P.args, **kwargs: P.kwargs) -> asyncio.Future[T]:
return asyncio.get_running_loop().run_in_executor(
None, functools.partial(f, *args, **kwargs)
)

return functools.update_wrapper(wrapper, f)
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
aiodns>=1.1,<4
aiofiles>=0.8
aiofiles
aiohttp-socks>=0.7,<0.9
aiohttp>=3.8.6,<4
brotli>=1,<2; implementation_name == "cpython"
brotlicffi<2; implementation_name != "cpython"
certifi
charset-normalizer>=2,<4
rich>=12,<14
typing-extensions>=4.4,<5; python_version < "3.12"
typing-extensions>=4.4,<5
uvloop>=0.14,<0.20; implementation_name == "cpython" and (sys_platform == "darwin" or sys_platform == "linux")
1 change: 0 additions & 1 deletion ruff.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ ignore = [
]
ignore-init-module-imports = true
select = ["ALL"]
typing-modules = ["nitro_generator_checker.typing_compat"]

[lint.flake8-self]
ignore-names = []
Expand Down

0 comments on commit 5e4949d

Please sign in to comment.