Skip to content

Commit

Permalink
Introduce ruff to check code style
Browse files Browse the repository at this point in the history
  • Loading branch information
yanghua committed Aug 17, 2024
1 parent 228c55e commit 67123d9
Show file tree
Hide file tree
Showing 11 changed files with 217 additions and 130 deletions.
6 changes: 0 additions & 6 deletions .pylintrc

This file was deleted.

10 changes: 4 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,15 @@ install: ## Install the project in dev mode.

.PHONY: fmt
fmt: ## Format code using black & isort.
$(ENV_PREFIX)poetry run ruff check tosfs/ --fix
$(ENV_PREFIX)isort tosfs/
$(ENV_PREFIX)black -l 79 tosfs/
$(ENV_PREFIX)black -l 79 tosfs/tests/
$(ENV_PREFIX)black -l 88 tosfs/

.PHONY: lint
lint: ## Run pep8, black, mypy linters.
set -e;
$(ENV_PREFIX)pylint tosfs/
$(ENV_PREFIX)flake8 tosfs/
$(ENV_PREFIX)black -l 79 --check tosfs/
$(ENV_PREFIX)black -l 79 --check tosfs/tests/
$(ENV_PREFIX)black -l 88 --check tosfs/
$(ENV_PREFIX)poetry run ruff check tosfs/
$(ENV_PREFIX)mypy --ignore-missing-imports tosfs/

.PHONY: test
Expand Down
29 changes: 28 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

72 changes: 70 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,82 @@ tos = ">=2.7.0"
[tool.poetry.group.dev.dependencies]
fsspec = ">=2023.5.0"
tos = ">=2.7.0"
pylint = "==3.2.6"
flake8 = "==7.0.0"
black = "==24.4.1"
isort = "==5.13.2"
mypy = "==1.10.0"
pytest = "==8.1.1"
pytest-cov = "==5.0.0"
coverage = "==7.5.0"
ruff = "==0.6.0"

[tool.pydocstyle]
convention = "numpy"

[tool.ruff]
target-version = "py39"
line-length = 88

[tool.ruff.lint]
select = [
"A", # Annotations rules
"ASYNC", # Asynchronous programming rules
"B", # Bugbear rules
"C", # Complexity rules
"D", # Docstring rules
"E", # Error rules
"F", # Pyflakes rules
"FURB", # FURB rules
"G", # General rules
"I", # Import rules
"LOG", # Logging rules
"N", # Naming rules
"PERF", # Performance rules
"PIE", # PIE rules
"PLC", # Pylint convention rules
"PLE", # Pylint error rules
"PLR", # Pylint refactor rules
"PLW", # Pylint warning rules
"PT", # Pytest rules
"PYI", # Pyright rules
"Q", # Quotes rules
"RUF", # Ruff-specific rules
"S", # Security rules
"SIM", # Similarity rules
"SLOT", # Slot rules
"T", # Testing rules
"W", # Whitespace rules
"YTT", # YTT rules
]
ignore = [
"S101", # Use of `assert` detected
"S311", # Standard pseudo-random generators are not suitable for cryptographic purposes
"D203", # no-blank-line-before-class
"D213", # multi-line-summary-second-line
"PLR0913", # Too many arguments in function definition
"SIM105", # Use `contextlib.suppress(IOError)` instead of `try`-`except`-`pass`
]

[tool.ruff.lint.per-file-ignores]
"tosfs/tests/*" = [
#D103 Missing docstring in public function
"D103",
#D100 Missing docstring in public module
"D100"
]
"tosfs/__init__.py" = [
#D104 Missing docstring in public package
"D104",
#D107 Missing docstring in __init__
"D107"
]

[tool.mypy]
python_version = "3.9"
ignore_missing_imports = true
disallow_untyped_calls = true
disallow_untyped_defs = true
strict_optional = true
exclude = "tosfs/tests/.*"

[build-system]
requires = ["poetry-core"]
Expand Down
136 changes: 69 additions & 67 deletions tosfs/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,16 @@
# See the License for the specific language governing permissions and
# limitations under the License.

"""
The core module of TOSFS.
"""
"""The core module of TOSFS."""
import logging
import os
from typing import Optional, Tuple
from typing import List, Optional, Tuple, Union

import tos
from fsspec import AbstractFileSystem
from fsspec.utils import setup_logging as setup_logger
from tos.models import CommonPrefixInfo
from tos.models2 import ListedObjectVersion
from tos.models2 import ListedObject, ListedObjectVersion

from tosfs.exceptions import TosfsError
from tosfs.utils import find_bucket_key
Expand All @@ -34,10 +32,8 @@
logger = logging.getLogger("tosfs")


def setup_logging():
"""
Set up the logging configuration for TOSFS.
"""
def setup_logging() -> None:
"""Set up the logging configuration for TOSFS."""
setup_logger(
logger=logger,
level=os.environ.get(ENV_NAME_TOSFS_LOGGING_LEVEL, "INFO"),
Expand All @@ -52,21 +48,23 @@ def setup_logging():


class TosFileSystem(AbstractFileSystem):
"""
Tos file system. An implementation of AbstractFileSystem which is an
"""Tos file system.
It's an implementation of AbstractFileSystem which is an
abstract super-class for pythonic file-systems.
"""

def __init__(
self,
endpoint_url=None,
key="",
secret="",
region=None,
version_aware=False,
credentials_provider=None,
**kwargs,
):
endpoint_url: Optional[str] = None,
key: str = "",
secret: str = "",
region: Optional[str] = None,
version_aware: bool = False,
credentials_provider: Optional[object] = None,
**kwargs: Union[str, bool, float, None],
) -> None:
"""Initialise the TosFileSystem."""
self.tos_client = tos.TosClientV2(
key,
secret,
Expand All @@ -77,9 +75,16 @@ def __init__(
self.version_aware = version_aware
super().__init__(**kwargs)

def ls(self, path, detail=False, refresh=False, versions=False, **kwargs):
"""
List objects under the given path.
def ls(
self,
path: str,
detail: bool = False,
refresh: bool = False,
versions: bool = False,
**kwargs: Union[str, bool, float, None],
) -> Union[List[dict], List[str]]:
"""List objects under the given path.
:param path: The path to list.
:param detail: Whether to return detailed information.
:param refresh: Whether to refresh the cache.
Expand Down Expand Up @@ -108,9 +113,9 @@ def ls(self, path, detail=False, refresh=False, versions=False, **kwargs):

return files if detail else sorted([o["name"] for o in files])

def _lsbuckets(self, refresh=False):
"""
List all buckets in the account.
def _lsbuckets(self, refresh: bool = False) -> List[dict]:
"""List all buckets in the account.
:param refresh: Whether to refresh the cache.
:return: A list of buckets.
"""
Expand All @@ -125,40 +130,37 @@ def _lsbuckets(self, refresh=False):
raise e
except Exception as e:
logger.error("Tosfs failed with unknown error: %s", e)
raise TosfsError(
f"Tosfs failed with unknown error: {e}"
) from e

buckets = []
for bucket in resp.buckets:
buckets.append(
{
"Key": bucket.name,
"Size": 0,
"StorageClass": "BUCKET",
"size": 0,
"type": "directory",
"name": bucket.name,
}
)
raise TosfsError(f"Tosfs failed with unknown error: {e}") from e

buckets = [
{
"Key": bucket.name,
"Size": 0,
"StorageClass": "BUCKET",
"size": 0,
"type": "directory",
"name": bucket.name,
}
for bucket in resp.buckets
]
self.dircache[""] = buckets

return self.dircache[""]

def _lsdir(
self,
path,
refresh=False,
path: str,
refresh: bool = False,
max_items: int = 1000,
delimiter="/",
prefix="",
versions=False,
):
"""
List objects in a bucket, here we use cache to improve performance.
delimiter: str = "/",
prefix: str = "",
versions: bool = False,
) -> List[Union[CommonPrefixInfo, ListedObject, ListedObjectVersion]]:
"""List objects in a bucket, here we use cache to improve performance.
:param path: The path to list.
:param refresh: Whether to refresh the cache.
:param max_items: The maximum number of items to return, default is 1000. # noqa: E501
:param max_items: The maximum number of items to return, default is 1000.
:param delimiter: The delimiter to use for grouping objects.
:param prefix: The prefix to use for filtering objects.
:param versions: Whether to list object versions.
Expand Down Expand Up @@ -193,16 +195,16 @@ def _lsdir(

def _listdir(
self,
bucket,
bucket: str,
max_items: int = 1000,
delimiter="/",
prefix="",
versions=False,
):
"""
List objects in a bucket.
delimiter: str = "/",
prefix: str = "",
versions: bool = False,
) -> List[Union[CommonPrefixInfo, ListedObject, ListedObjectVersion]]:
"""List objects in a bucket.
:param bucket: The bucket name.
:param max_items: The maximum number of items to return, default is 1000. # noqa: E501
:param max_items: The maximum number of items to return, default is 1000.
:param delimiter: The delimiter to use for grouping objects.
:param prefix: The prefix to use for filtering objects.
:param versions: Whether to list object versions.
Expand Down Expand Up @@ -231,9 +233,7 @@ def _listdir(
)
is_truncated = resp.is_truncated
all_results.extend(
resp.versions
+ resp.common_prefixes
+ resp.delete_markers
resp.versions + resp.common_prefixes + resp.delete_markers
)
key_marker, version_id_marker = (
resp.next_key_marker,
Expand Down Expand Up @@ -270,9 +270,8 @@ def _listdir(
logger.error("Tosfs failed with unknown error: %s", e)
raise TosfsError(f"Tosfs failed with unknown error: {e}") from e

def _split_path(self, path) -> Tuple[str, str, Optional[str]]:
"""
Normalise tos path string into bucket and key.
def _split_path(self, path: str) -> Tuple[str, str, Optional[str]]:
"""Normalise tos path string into bucket and key.
Parameters
----------
Expand All @@ -284,8 +283,9 @@ def _split_path(self, path) -> Tuple[str, str, Optional[str]]:
>>> split_path("tos://mybucket/path/to/file")
['mybucket', 'path/to/file', None]
# pylint: disable=line-too-long
>>> split_path("tos://mybucket/path/to/versioned_file?versionId=some_version_id") # noqa: E501
>>> split_path("tos://mybucket/path/to/versioned_file?versionId=some_version_id")
['mybucket', 'path/to/versioned_file', 'some_version_id']
"""
path = self._strip_protocol(path)
path = path.lstrip("/")
Expand All @@ -301,7 +301,7 @@ def _split_path(self, path) -> Tuple[str, str, Optional[str]]:
)

@staticmethod
def _fill_common_prefix_info(common_prefix: CommonPrefixInfo, bucket):
def _fill_common_prefix_info(common_prefix: CommonPrefixInfo, bucket: str) -> dict:
return {
"name": common_prefix.prefix[:-1],
"Key": "/".join([bucket, common_prefix.prefix]),
Expand All @@ -310,7 +310,9 @@ def _fill_common_prefix_info(common_prefix: CommonPrefixInfo, bucket):
}

@staticmethod
def _fill_object_info(obj, bucket, versions=False):
def _fill_object_info(
obj: ListedObject, bucket: str, versions: bool = False
) -> dict:
result = {
"Key": f"{bucket}/{obj.key}",
"size": obj.size,
Expand Down
Loading

0 comments on commit 67123d9

Please sign in to comment.