updated: 2025-03-24T16:17:19.123450768+00:00[Etc/UTC]
README
ry
ry = rust and python and bears, oh my!
DOCS: ryo3.dev (WIP)
ry
is a library of python shims/bindings to popular rust cratesryo3-*
is the collection of rust crates providing the shims used by ry and possibly yourpyo3
rust-python library
THIS IS A WORK IN PROGRESS ~ FEEDBACK/PRs WELCOME!
Install
pip install ry
uv add ry
Check install: python -m ry
Quickstart
Check out the examples directory for some quickstart examples.
What and why?
This is a collection of pyo3-wrappers for rust crates I wish existed in python.
It all started with me wanting a fast python xxhash
and fnv-64
Who?
- jessekrubin [email protected]
- possibly you!?
FAQ
(aka: questions that I have been asking myself)
- Q: Why?
- A: I (jesse) needed several hashing functions for python and then kept adding things as I needed them
- Q: Does this have anything to do with the (excellent) package manager
rye
?- A: short answer: no. long answer: no, it does not.
- Q: Why is the repo split into
ry
andryo3
?- A:
ry
is the python package,ryo3
is a rust crate setup to let you “register” functions you may want if you were writing your own pyo3-python bindings library; maybe someday theryo3::libs
module will be split up into separate packages
- A:
Crate bindings
ryo3-std
- wrapped crates:
heck
jiter
shlex
sqlformat
url
which
- compression:
brotli
bzip2
flate2
zstd
- hashing:
fnv
xxhash
- burnt-sushi:
globset
(formerly globsters)jiff
walkdir
FUTURE?
subprocess.redo
(subprocesses that are lessy finicky and support tee-ing)- wrappers:
ignore
http
regex
reqwest
(async http client / waiting on pyo3 asyncio to stabilize and for me to have more time)tokio
(fs
andprocess
)tracing
(could be nicer than python’s awful logging lib – currently a part of ry/ryo3 for my dev purposes - currently has impl thingy in utiles)tracing
(eg logging)uuid
- organization
- split up the
ryo3
type annotations? - chunk things into smaller sub-packages within the
ry
package?
- split up the
API
API
Table of Contents
ry.ryo3.__init__
ry.ryo3.errors
ry.ryo3.JSON
ry.ryo3._brotli
ry.ryo3._bytes
ry.ryo3._bzip2
ry.ryo3._dev
ry.ryo3._flate2
ry.ryo3._fnv
ry.ryo3._fspath
ry.ryo3._glob
ry.ryo3._globset
ry.ryo3._heck
ry.ryo3._jiff
ry.ryo3._jiter
ry.ryo3._quick_maths
ry.ryo3._regex
ry.ryo3._reqwest
ry.ryo3._same_file
ry.ryo3._shlex
ry.ryo3._size
ry.ryo3._sqlformat
ry.ryo3._std
ry.ryo3._tokio
ry.ryo3._unindent
ry.ryo3._url
ry.ryo3._walkdir
ry.ryo3._which
ry.dirs
ry.http
ry.xxhash
ry.zstd
ry.ryo3.__init__
"""ry api ~ type annotations"""
from __future__ import annotations
import datetime as pydt
import typing as t
from os import PathLike
from ry import dirs as dirs # noqa: RUF100
from ry import http as http # noqa: RUF100
from ry import xxhash as xxhash # noqa: RUF100
from ry import zstd as zstd # noqa: RUF100
from ry._types import Buffer as Buffer # noqa: RUF100
from ry.http import Headers as Headers # noqa: RUF100
from ry.http import HttpStatus as HttpStatus # noqa: RUF100
from ry.zstd import is_zstd as is_zstd
from ry.zstd import zstd_compress as zstd_compress
from ry.zstd import zstd_decode as zstd_decode
from ry.zstd import zstd_decompress as zstd_decompress
from ry.zstd import zstd_encode as zstd_encode
from ._brotli import brotli as brotli
from ._brotli import brotli_decode as brotli_decode
from ._brotli import brotli_encode as brotli_encode
from ._bytes import Bytes as Bytes
from ._bzip2 import bzip2 as bzip2
from ._bzip2 import bzip2_decode as bzip2_decode
from ._bzip2 import bzip2_encode as bzip2_encode
from ._flate2 import gunzip as gunzip
from ._flate2 import gzip as gzip
from ._flate2 import gzip_decode as gzip_decode
from ._flate2 import gzip_encode as gzip_encode
from ._flate2 import is_gzipped as is_gzipped
from ._fnv import FnvHasher as FnvHasher
from ._fnv import fnv1a as fnv1a
from ._fspath import FsPath as FsPath
from ._glob import Pattern as Pattern
from ._glob import glob as glob
from ._globset import Glob as Glob
from ._globset import GlobSet as GlobSet
from ._globset import Globster as Globster
from ._globset import globster as globster
from ._heck import camel_case as camel_case
from ._heck import kebab_case as kebab_case
from ._heck import pascal_case as pascal_case
from ._heck import shouty_kebab_case as shouty_kebab_case
from ._heck import shouty_snake_case as shouty_snake_case
from ._heck import snake_case as snake_case
from ._heck import snek_case as snek_case
from ._heck import title_case as title_case
from ._heck import train_case as train_case
from ._jiff import Date as Date
from ._jiff import DateDifference as DateDifference
from ._jiff import DateTime as DateTime
from ._jiff import DateTimeDifference as DateTimeDifference
from ._jiff import DateTimeRound as DateTimeRound
from ._jiff import ISOWeekDate as ISOWeekDate
from ._jiff import Offset as Offset
from ._jiff import SignedDuration as SignedDuration
from ._jiff import Time as Time
from ._jiff import TimeDifference as TimeDifference
from ._jiff import TimeSpan as TimeSpan
from ._jiff import Timestamp as Timestamp
from ._jiff import TimestampDifference as TimestampDifference
from ._jiff import TimestampRound as TimestampRound
from ._jiff import TimeZone as TimeZone
from ._jiff import TimeZoneDatabase as TimeZoneDatabase
from ._jiff import ZonedDateTime as ZonedDateTime
from ._jiff import ZonedDateTimeDifference as ZonedDateTimeDifference
from ._jiff import ZonedDateTimeRound as ZonedDateTimeRound
from ._jiff import date as date
from ._jiff import datetime as datetime
from ._jiff import offset as offset
from ._jiff import time as time
from ._jiff import timespan as timespan
from ._jiter import JsonParseKwargs as JsonParseKwargs
from ._jiter import JsonPrimitive as JsonPrimitive
from ._jiter import JsonValue as JsonValue
from ._jiter import json_cache_clear as json_cache_clear
from ._jiter import json_cache_usage as json_cache_usage
from ._jiter import parse_json as parse_json
from ._jiter import parse_json_bytes as parse_json_bytes
from ._quick_maths import quick_maths as quick_maths
from ._regex import Regex as Regex
from ._reqwest import HttpClient as HttpClient
from ._reqwest import ReqwestError as ReqwestError
from ._reqwest import Response as Response
from ._reqwest import ResponseStream as ResponseStream
from ._reqwest import fetch as fetch
from ._same_file import is_same_file as is_same_file
from ._shlex import shplit as shplit
from ._size import Size as Size
from ._size import SizeFormatter as SizeFormatter
from ._size import fmt_size as fmt_size
from ._size import parse_size as parse_size
from ._sqlformat import SqlfmtQueryParams as SqlfmtQueryParams
from ._sqlformat import sqlfmt as sqlfmt
from ._sqlformat import sqlfmt_params as sqlfmt_params
from ._std import Duration as Duration
from ._std import FileType as FileType
from ._std import Instant as Instant
from ._std import Metadata as Metadata
from ._std import canonicalize as canonicalize
from ._std import copy as copy
from ._std import create_dir as create_dir
from ._std import create_dir_all as create_dir_all
from ._std import exists as exists
from ._std import instant as instant
from ._std import is_dir as is_dir
from ._std import is_file as is_file
from ._std import is_symlink as is_symlink
from ._std import metadata as metadata
from ._std import read as read
from ._std import read_bytes as read_bytes
from ._std import read_stream as read_stream
from ._std import read_text as read_text
from ._std import remove_dir as remove_dir
from ._std import remove_dir_all as remove_dir_all
from ._std import remove_file as remove_file
from ._std import rename as rename
from ._std import sleep as sleep
from ._std import write as write
from ._std import write_bytes as write_bytes
from ._std import write_text as write_text
from ._tokio import asleep as asleep
from ._tokio import copy_async as copy_async
from ._tokio import create_dir_async as create_dir_async
from ._tokio import metadata_async as metadata_async
from ._tokio import read_async as read_async
from ._tokio import read_dir_async as read_dir_async
from ._tokio import remove_dir_async as remove_dir_async
from ._tokio import remove_file_async as remove_file_async
from ._tokio import rename_async as rename_async
from ._tokio import sleep_async as sleep_async
from ._tokio import write_async as write_async
from ._unindent import unindent as unindent
from ._unindent import unindent_bytes as unindent_bytes
from ._url import URL as URL
from ._walkdir import WalkDirEntry as WalkDirEntry
from ._walkdir import WalkdirGen as WalkdirGen
from ._walkdir import walkdir as walkdir
from ._which import which as which
from ._which import which_all as which_all
from ._which import which_re as which_re
from .errors import FeatureNotEnabledError as FeatureNotEnabledError
# =============================================================================
# CONSTANTS
# =============================================================================
__version__: str
__authors__: str
__build_profile__: str
__build_timestamp__: str
__pkg_name__: str
__description__: str
# =============================================================================
# SH
# =============================================================================
def pwd() -> str: ...
def home() -> str: ...
def cd(path: str | PathLike[str]) -> None: ...
@t.overload
def ls(
path: str | PathLike[str] | None = None, # defaults to '.' if None
*,
absolute: bool = False,
sort: bool = False,
objects: t.Literal[False] = False,
) -> list[str]:
"""List directory contents - returns list of strings"""
@t.overload
def ls(
path: str | PathLike[str] | None = None, # defaults to '.' if None
*,
absolute: bool = False,
sort: bool = False,
objects: t.Literal[True] = True,
) -> list[FsPath]:
"""List directory contents - returns list of FsPath objects"""
ry.ryo3.errors
from __future__ import annotations
class FeatureNotEnabledError(RuntimeError):
"""Raised when a feature is not enabled in the current build."""
ry.ryo3.JSON
"""ry.ryo3.JSON"""
from typing import Literal
JsonPrimitive = None | bool | int | float | str
JsonValue = (
JsonPrimitive
| dict[str, JsonPrimitive | JsonValue]
| list[JsonPrimitive | JsonValue]
)
def parse_json(
data: bytes | str,
/,
*,
allow_inf_nan: bool = True,
cache_mode: Literal[True, False, "all", "keys", "none"] = "all",
partial_mode: Literal[True, False, "off", "on", "trailing-strings"] = False,
catch_duplicate_keys: bool = False,
float_mode: Literal["float", "decimal", "lossless-float"] | bool = False,
) -> JsonValue: ...
def parse_json_bytes(
data: bytes,
/,
*,
allow_inf_nan: bool = True,
cache_mode: Literal[True, False, "all", "keys", "none"] = "all",
partial_mode: Literal[True, False, "off", "on", "trailing-strings"] = False,
catch_duplicate_keys: bool = False,
float_mode: Literal["float", "decimal", "lossless-float"] | bool = False,
) -> JsonValue: ...
def json_cache_clear() -> None: ...
def json_cache_usage() -> int: ...
ry.ryo3._brotli
"""ryo3-brotli types"""
from __future__ import annotations
# =============================================================================
# BROTLI
# =============================================================================
def brotli_encode(
input: bytes, quality: int = 11, magic_number: bool = False
) -> bytes: ...
def brotli_decode(input: bytes) -> bytes: ...
def brotli(
input: bytes, quality: int = 11, magic_number: bool = False
) -> bytes:
"""Alias for brotli_encode"""
ry.ryo3._bytes
import sys
from typing import overload
if sys.version_info >= (3, 12):
from collections.abc import Buffer as Buffer
else:
from typing_extensions import Buffer as Buffer
class Bytes(Buffer):
"""
A buffer implementing the Python buffer protocol, allowing zero-copy access
to underlying Rust memory.
You can pass this to `memoryview` for a zero-copy view into the underlying
data or to `bytes` to copy the underlying data into a Python `bytes`.
Many methods from the Python `bytes` class are implemented on this,
"""
def __init__(self, buf: Buffer = b"") -> None:
"""Construct a new Bytes object.
This will be a zero-copy view on the Python byte slice.
"""
def __add__(self, other: Buffer) -> Bytes: ...
def __buffer__(self, flags: int) -> memoryview[int]: ...
def __contains__(self, other: Buffer) -> bool: ...
def __eq__(self, other: object) -> bool: ...
@overload
def __getitem__(self, other: int) -> int: ...
@overload
def __getitem__(self, other: slice) -> Bytes: ...
def __mul__(self, other: Buffer) -> int: ...
def __len__(self) -> int: ...
def __repr__(self) -> str: ...
def removeprefix(self, prefix: Buffer, /) -> Bytes:
"""
If the binary data starts with the prefix string, return `bytes[len(prefix):]`.
Otherwise, return the original binary data.
"""
def removesuffix(self, suffix: Buffer, /) -> Bytes:
"""
If the binary data ends with the suffix string and that suffix is not empty,
return `bytes[:-len(suffix)]`. Otherwise, return the original binary data.
"""
def isalnum(self) -> bool:
"""
Return `True` if all bytes in the sequence are alphabetical ASCII characters or
ASCII decimal digits and the sequence is not empty, `False` otherwise.
Alphabetic ASCII characters are those byte values in the sequence
`b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'`. ASCII decimal digits
are those byte values in the sequence `b'0123456789'`.
"""
def isalpha(self) -> bool:
"""
Return `True` if all bytes in the sequence are alphabetic ASCII characters and
the sequence is not empty, `False` otherwise.
Alphabetic ASCII characters are those byte values in the sequence
`b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'`.
"""
def isascii(self) -> bool:
"""
Return `True` if the sequence is empty or all bytes in the sequence are ASCII,
`False` otherwise.
ASCII bytes are in the range `0-0x7F`.
"""
def isdigit(self) -> bool:
"""
Return `True` if all bytes in the sequence are ASCII decimal digits and the
sequence is not empty, `False` otherwise.
ASCII decimal digits are those byte values in the sequence `b'0123456789'`.
"""
def islower(self) -> bool:
"""
Return `True` if there is at least one lowercase ASCII character in the sequence
and no uppercase ASCII characters, `False` otherwise.
"""
def isspace(self) -> bool:
"""
Return `True` if all bytes in the sequence are ASCII whitespace and the sequence
is not empty, `False` otherwise.
ASCII whitespace characters are those byte values
in the sequence `b' \t\n\r\x0b\f'` (space, tab, newline, carriage return,
vertical tab, form feed).
"""
def isupper(self) -> bool:
"""
Return `True` if there is at least one uppercase alphabetic ASCII character in
the sequence and no lowercase ASCII characters, `False` otherwise.
"""
def lower(self) -> Bytes:
"""
Return a copy of the sequence with all the uppercase ASCII characters converted
to their corresponding lowercase counterpart.
"""
def upper(self) -> Bytes:
"""
Return a copy of the sequence with all the lowercase ASCII characters converted
to their corresponding uppercase counterpart.
"""
def to_bytes(self) -> bytes:
"""Copy this buffer's contents into a Python `bytes` object."""
# =========================================================================
# IMPL IN RY
# =========================================================================
def decode(self, encoding: str = "utf-8", errors: str = "strict") -> str:
"""Decode the binary data using the given encoding."""
def hex(
self, sep: str | None = None, bytes_per_sep: int | None = None
) -> str:
"""Return a hexadecimal representation of the binary data."""
@classmethod
def fromhex(cls, hexstr: str) -> Bytes:
"""Construct a `Bytes` object from a hexadecimal string."""
BytesLike = Buffer | bytes | bytearray | memoryview | Bytes
ry.ryo3._bzip2
"""ryo3-bzip2 types"""
from __future__ import annotations
from ry._types import Buffer
# =============================================================================
# BZIP2
# =============================================================================
def bzip2_encode(input: Buffer, quality: int = 9) -> bytes: ...
def bzip2_decode(input: Buffer) -> bytes: ...
def bzip2(input: Buffer, quality: int = 9) -> bytes:
"""Alias for bzip2_encode"""
ry.ryo3._dev
"""ry.ryo3.dev"""
from __future__ import annotations
import typing as t
# =============================================================================
# SUBPROCESS (VERY MUCH WIP)
# =============================================================================
def run(
*args: str | list[str],
capture_output: bool = True,
input: bytes | None = None,
) -> t.Any: ...
# =============================================================================
# STRING-DEV
# =============================================================================
def anystr_noop(s: t.AnyStr) -> t.AnyStr: ...
def string_noop(s: str) -> str: ...
def bytes_noop(s: bytes) -> bytes: ...
ry.ryo3._flate2
"""ryo3-flate2 types"""
from __future__ import annotations
from ry import Bytes
from ry._types import Buffer
# =============================================================================
# GZIP
# =============================================================================
def gzip_encode(input: Buffer, quality: int = 9) -> Bytes: ...
def gzip_decode(input: Buffer) -> Bytes: ...
def gzip(input: Buffer, quality: int = 9) -> Bytes:
"""Alias for gzip_encode"""
def gunzip(input: Buffer) -> Bytes:
"""Alias for gzip_decode"""
def is_gzipped(input: Buffer) -> bool: ...
ry.ryo3._fnv
"""ryo3-fnv types"""
import typing as t
from ry._types import Buffer
# =============================================================================
# FNV
# =============================================================================
class FnvHasher:
name: t.Literal["fnv1a"]
def __init__(self, input: Buffer | None = None) -> None: ...
def update(self, input: Buffer) -> None: ...
def digest(self) -> int: ...
def hexdigest(self) -> str: ...
def copy(self) -> FnvHasher: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def fnv1a(input: Buffer) -> FnvHasher: ...
ry.ryo3._fspath
"""ryo3-fspath types"""
from __future__ import annotations
import typing as t
from os import PathLike
from pathlib import Path
from ry import Bytes
from ry._types import Buffer, ToPy
# =============================================================================
# FSPATH
# =============================================================================
class FsPath(ToPy[Path]):
def __init__(self, path: PathLike[str] | str | None = None) -> None: ...
def __fspath__(self) -> str: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def __hash__(self) -> int: ...
def __eq__(self, other: object) -> bool: ...
def __ne__(self, other: object) -> bool: ...
def __lt__(self, other: PathLike[str] | str) -> bool: ...
def __le__(self, other: PathLike[str] | str) -> bool: ...
def __gt__(self, other: PathLike[str] | str) -> bool: ...
def __ge__(self, other: PathLike[str] | str) -> bool: ...
def __truediv__(self, other: PathLike[str] | str) -> FsPath: ...
def __rtruediv__(self, other: PathLike[str] | str) -> FsPath: ...
def __bytes__(self) -> bytes: ...
def to_py(self) -> Path: ...
def to_pathlib(self) -> Path: ...
def read(self) -> Bytes: ...
def read_text(self) -> str: ...
def read_bytes(self) -> bytes: ...
def absolute(self) -> FsPath: ...
def resolve(self) -> FsPath: ...
def write(self, data: Buffer | bytes) -> None: ...
def write_bytes(self, data: Buffer | bytes) -> None: ...
def write_text(self, data: str) -> None: ...
def joinpath(self, *paths: str) -> FsPath: ...
def exists(self) -> bool: ...
def with_name(self, name: str) -> FsPath: ...
def with_suffix(self, suffix: str) -> FsPath: ...
def iterdir(self) -> t.Iterator[FsPath]: ...
def relative_to(self, other: PathLike[str] | str | FsPath) -> FsPath: ...
def as_posix(self) -> str: ...
def as_uri(self) -> str: ...
def equiv(self, other: PathLike[str] | str | FsPath) -> bool: ...
def string(self) -> str: ...
def clone(self) -> FsPath: ...
# =========================================================================
# CLASSMETHODS
# =========================================================================
@classmethod
def cwd(cls) -> FsPath: ...
@classmethod
def home(cls) -> FsPath: ...
# =========================================================================
# PROPERTIES
# =========================================================================
@property
def anchor(self) -> str: ...
@property
def drive(self) -> str: ...
@property
def name(self) -> str: ...
@property
def parent(self) -> FsPath: ...
@property
def parents(self) -> t.Sequence[FsPath]: ...
@property
def parts(self) -> tuple[str, ...]: ...
@property
def root(self) -> str: ...
@property
def stem(self) -> str: ...
@property
def suffix(self) -> str: ...
@property
def suffixes(self) -> list[str]: ...
# =========================================================================
# std::path::PathBuf (deref -> std::path::Path)
# =========================================================================
def ancestors(self) -> t.Iterator[FsPath]: ...
def canonicalize(self) -> FsPath: ...
def components(self) -> t.Iterator[FsPath]: ...
def display(self) -> str: ...
def ends_with(self, path: PathLike[str] | str) -> bool: ...
def extension(self) -> str: ...
def file_name(self) -> str: ...
def file_prefix(self) -> FsPath: ...
def file_stem(self) -> str: ...
def has_root(self) -> bool: ...
def is_absolute(self) -> bool: ...
def is_dir(self) -> bool: ...
def is_file(self) -> bool: ...
def is_relative(self) -> bool: ...
def is_symlink(self) -> bool: ...
def starts_with(self, path: PathLike[str] | str) -> bool: ...
def strip_prefix(self, prefix: PathLike[str] | str) -> FsPath: ...
def with_extension(self, ext: str) -> FsPath: ...
def with_file_name(self, name: str) -> FsPath: ...
ry.ryo3._glob
"""ryo3-glob types"""
from __future__ import annotations
import typing as t
from os import PathLike
from pathlib import Path
import typing_extensions as te
T = t.TypeVar("T")
class _MatchOptions(t.TypedDict, total=False):
case_sensitive: bool
require_literal_separator: bool
require_literal_leading_dot: bool
class GlobPaths(t.Generic[T]):
"""glob::Paths iterable wrapper"""
def __next__(self) -> T: ...
def __iter__(self) -> t.Iterator[T]: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def collect(self) -> list[T]: ...
def take(self, n: int) -> list[T]: ...
def glob(
pattern: str,
**kwargs: te.Unpack[_MatchOptions],
) -> GlobPaths[Path]:
"""Return glob iterable for paths matching the pattern."""
class Pattern:
def __init__(self, pattern: str) -> None: ...
def __call__(
self,
ob: str | PathLike[str],
**kwargs: te.Unpack[_MatchOptions],
) -> bool: ...
def matches(self, s: str) -> bool: ...
def matches_path(self, path: PathLike[str]) -> bool: ...
def matches_with(
self,
s: str,
**kwargs: te.Unpack[_MatchOptions],
) -> bool: ...
def matches_path_with(
self,
path: PathLike[str],
**kwargs: te.Unpack[_MatchOptions],
) -> bool: ...
@staticmethod
def escape(pattern: str) -> str: ...
ry.ryo3._globset
"""ryo3-globset types"""
from __future__ import annotations
from os import PathLike
class Glob:
"""globset::Glob wrapper"""
def __init__(
self,
pattern: str,
/,
*,
case_insensitive: bool | None = None,
literal_separator: bool | None = None,
backslash_escape: bool | None = None,
) -> None: ...
def regex(self) -> str: ...
def is_match(self, path: str | PathLike[str]) -> bool: ...
def __call__(self, path: str | PathLike[str]) -> bool: ...
def __invert__(self) -> Glob: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def globset(self) -> GlobSet: ...
def globster(self) -> Globster: ...
class GlobSet:
"""globset::GlobSet wrapper"""
def __init__(
self,
patterns: list[str],
/,
*,
case_insensitive: bool | None = None,
literal_separator: bool | None = None,
backslash_escape: bool | None = None,
) -> None: ...
def is_empty(self) -> bool: ...
def is_match(self, path: str) -> bool: ...
def matches(self, path: str) -> list[int]: ...
def __call__(self, path: str) -> bool: ...
def __invert__(self) -> GlobSet: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def globster(self) -> Globster: ...
class Globster:
"""Globster is a matcher with claws!
Note: The north american `Globster` is similar to the european `Globset`
but allows for negative patterns (prefixed with '!')
"""
def __init__(
self,
patterns: list[str],
/,
*,
case_insensitive: bool | None = None,
literal_separator: bool | None = None,
backslash_escape: bool | None = None,
) -> None: ...
def is_empty(self) -> bool: ...
def is_match(self, path: str | PathLike[str]) -> bool: ...
def __call__(self, path: str | PathLike[str]) -> bool: ...
def __invert__(self) -> GlobSet: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def globster(
patterns: list[str] | tuple[str, ...],
/,
*,
case_insensitive: bool | None = None,
literal_separator: bool | None = None,
backslash_escape: bool | None = None,
) -> Globster: ...
ry.ryo3._heck
"""ryo3-heck types"""
from __future__ import annotations
def camel_case(string: str) -> str: ...
def kebab_case(string: str) -> str: ...
def pascal_case(string: str) -> str: ...
def shouty_kebab_case(string: str) -> str: ...
def shouty_snake_case(string: str) -> str: ...
def snake_case(string: str) -> str: ...
def snek_case(string: str) -> str: ...
def title_case(string: str) -> str: ...
def train_case(string: str) -> str: ...
ry.ryo3._jiff
"""jiff types"""
import datetime as pydt
import typing as t
from typing import Protocol
import typing_extensions as te
from ry._types import (
DateTimeTypedDict,
DateTypedDict,
TimeSpanTypedDict,
TimeTypedDict,
ToPy,
)
from ry.ryo3 import Duration
T = t.TypeVar("T")
# =============================================================================
# JIFF
# =============================================================================
JIFF_UNIT = t.Literal[
"year",
"month",
"week",
"day",
"hour",
"minute",
"second",
"millisecond",
"microsecond",
"nanosecond",
]
JIFF_ROUND_MODE = t.Literal[
"ceil",
"floor",
"expand",
"trunc",
"half_ceil",
"half_floor",
"half_expand",
"half_trunc",
"half_even",
]
WEEKDAY_STR = t.Literal[
"monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"
]
WEEKDAY_INT = t.Literal[
1, # Monday
2, # Tuesday
3, # Wednesday
4, # Thursday
5, # Friday
6, # Saturday
7, # Sunday
]
WEEKDAY: te.TypeAlias = WEEKDAY_STR | WEEKDAY_INT
class ToPyDate(Protocol):
def to_pydate(self) -> pydt.date: ...
class ToPyTime(Protocol):
def to_pytime(self) -> pydt.time: ...
class ToPyDateTime(Protocol):
def to_pydatetime(self) -> pydt.datetime: ...
class ToPyTimeDelta(Protocol):
def to_pytimedelta(self) -> pydt.timedelta: ...
class ToPyTzInfo(Protocol):
def to_pytzinfo(self) -> pydt.tzinfo: ...
class Date(ToPy[pydt.date], ToPyDate):
MIN: Date
MAX: Date
ZERO: Date
def __init__(self, year: int, month: int, day: int) -> None: ...
# =========================================================================
# STRING
# =========================================================================
def string(self) -> str: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
# =========================================================================
# PYTHON_CONVERSIONS
# =========================================================================
def to_py(self) -> pydt.date: ...
def to_pydate(self) -> pydt.date: ...
@classmethod
def from_pydate(cls: type[Date], date: pydt.date) -> Date: ...
# =========================================================================
# PROPERTIES
# =========================================================================
@property
def year(self) -> int: ...
@property
def month(self) -> int: ...
@property
def day(self) -> int: ...
@property
def weekday(self) -> int: ...
# =========================================================================
# CLASSMETHODS
# =========================================================================
@classmethod
def from_iso_week_date(
cls: type[Date], year: int, week: int, weekday: int
) -> Date: ...
@classmethod
def today(cls: type[Date]) -> Date: ...
# =========================================================================
# STRPTIME/STRFTIME
# =========================================================================
@classmethod
def strptime(cls: type[Date], format: str, string: str) -> Date: ...
def strftime(self, format: str) -> str: ...
# =========================================================================
# OPERATORS
# =========================================================================
def __add__(self, other: TimeSpan | SignedDuration | Duration) -> Date: ...
@t.overload
def __sub__(self, other: Date) -> TimeSpan: ...
@t.overload
def __sub__(self, other: TimeSpan | SignedDuration | Duration) -> Date: ...
@t.overload
def __isub__(self, other: Date) -> TimeSpan: ...
@t.overload
def __isub__(self, other: TimeSpan | SignedDuration | Duration) -> Date: ...
# =========================================================================
# INSTANCE METHODS
# =========================================================================
def at(
self, hour: int, minute: int, second: int, nanosecond: int
) -> DateTime: ...
def asdict(self) -> DateTypedDict: ...
def astuple(self) -> tuple[int, int, int]: ...
def checked_add(
self, other: TimeSpan | SignedDuration | Duration
) -> Date: ...
def day_of_year(self) -> int: ...
def day_of_year_no_leap(self) -> int | None: ...
def days_in_month(self) -> int: ...
def days_in_year(self) -> int: ...
def duration_since(self, other: Date) -> Date: ...
def duration_until(self, other: Date) -> Date: ...
def era_year(self) -> tuple[int, t.Literal["BCE", "CE"]]: ...
def first_of_month(self) -> Date: ...
def first_of_year(self) -> Date: ...
def iso_week_date(self) -> ISOWeekDate: ...
def in_leap_year(self) -> bool: ...
def in_tz(self, tz: str) -> ZonedDateTime: ...
def intz(self, tz: str) -> ZonedDateTime: ...
def last_of_month(self) -> Date: ...
def last_of_year(self) -> Date: ...
def nth_weekday(self, nth: int, weekday: WEEKDAY) -> Date: ...
def nth_weekday_of_month(self, nth: int, weekday: WEEKDAY) -> Date: ...
def saturating_add(
self, other: TimeSpan | SignedDuration | Duration
) -> Date: ...
def saturating_sub(
self, other: TimeSpan | SignedDuration | Duration
) -> Date: ...
def series(self, span: TimeSpan) -> JiffSeries[Date]: ...
def sub_date(self, other: Date) -> TimeSpan: ...
def to_datetime(self, time: Time) -> DateTime: ...
def to_zoned(self, tz: TimeZone) -> ZonedDateTime: ...
def tomorrow(self) -> Date: ...
def yesterday(self) -> Date: ...
# =========================================================================
# SINCE/UNTIL
# =========================================================================
def _since(self, other: DateDifference) -> TimeSpan: ...
def _until(self, other: DateDifference) -> TimeSpan: ...
def since(
self,
other: Date | DateTime | ZonedDateTime,
*,
smallest: JIFF_UNIT | None = None,
largest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> TimeSpan: ...
def until(
self,
other: Date | DateTime | ZonedDateTime,
*,
smallest: JIFF_UNIT | None = None,
largest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> TimeSpan: ...
# =========================================================================
# INSTANCE METHODS W/ OVERLOADS
# =========================================================================
@t.overload
def checked_sub(self, other: Date) -> TimeSpan: ...
@t.overload
def checked_sub(
self, other: TimeSpan | SignedDuration | Duration
) -> Date: ...
class DateDifference:
def __init__(
self,
date: Date,
*,
smallest: JIFF_UNIT | None = None,
largest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> None: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def smallest(self, unit: JIFF_UNIT) -> DateDifference: ...
def largest(self, unit: JIFF_UNIT) -> DateDifference: ...
def mode(self, mode: JIFF_ROUND_MODE) -> DateDifference: ...
def increment(self, increment: int) -> DateDifference: ...
class Time(ToPy[pydt.time], ToPyTime):
MIN: Time
MAX: Time
def __init__(
self,
hour: int = 0,
minute: int = 0,
second: int = 0,
nanosecond: int = 0,
) -> None: ...
# =========================================================================
# STRING
# =========================================================================
def string(self) -> str: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
# =========================================================================
# OPERATORS/DUNDERS
# =========================================================================
def __add__(self, other: TimeSpan | SignedDuration | Duration) -> Time: ...
@t.overload
def __sub__(self, other: Time) -> TimeSpan: ...
@t.overload
def __sub__(self, other: TimeSpan | SignedDuration | Duration) -> Time: ...
@t.overload
def __isub__(self, other: Time) -> TimeSpan: ...
@t.overload
def __isub__(self, other: TimeSpan | SignedDuration | Duration) -> Time: ...
# =========================================================================
# STRPTIME/STRFTIME/PARSE
# =========================================================================
@classmethod
def strptime(cls: type[Time], format: str, string: str) -> Time: ...
def strftime(self, format: str) -> str: ...
# =========================================================================
# PYTHON CONVERSIONS
# =========================================================================
def to_py(self) -> pydt.time: ...
def to_pytime(self) -> pydt.time: ...
@classmethod
def from_pytime(cls: type[Time], t: pydt.time) -> Time: ...
# =========================================================================
# CLASS METHODS
# =========================================================================
@classmethod
def midnight(cls: type[Time]) -> Time: ...
@classmethod
def now(cls: type[Time]) -> Time: ...
@classmethod
def parse(cls: type[Time], s: str) -> Time: ...
# =========================================================================
# PROPERTIES
# =========================================================================
@property
def hour(self) -> int: ...
@property
def minute(self) -> int: ...
@property
def second(self) -> int: ...
@property
def millisecond(self) -> int: ...
@property
def microsecond(self) -> int: ...
@property
def nanosecond(self) -> int: ...
@property
def subsec_nanosecond(self) -> None: ...
# =========================================================================
# INSTANCE METHODS
# =========================================================================
def astuple(self) -> tuple[int, int, int, int]: ...
def asdict(self) -> TimeTypedDict: ...
def series(self, span: TimeSpan) -> JiffSeries[Time]: ...
def checked_add(
self, other: TimeSpan | SignedDuration | Duration
) -> Time: ...
@t.overload
def checked_sub(self, other: Time) -> TimeSpan: ...
@t.overload
def checked_sub(
self, other: TimeSpan | SignedDuration | Duration
) -> Time: ...
def saturating_add(
self, other: TimeSpan | SignedDuration | Duration
) -> Time: ...
def saturating_sub(
self, other: TimeSpan | SignedDuration | Duration
) -> Time: ...
def wrapping_add(
self, other: TimeSpan | SignedDuration | Duration
) -> Time: ...
def wrapping_sub(
self, other: TimeSpan | SignedDuration | Duration
) -> Time: ...
def on(self, year: int, month: int, day: int) -> DateTime: ...
def duration_until(self, other: Time) -> SignedDuration: ...
def duration_since(self, other: Time) -> SignedDuration: ...
def round(
self,
smallest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> Time: ...
def to_datetime(self, d: Date) -> DateTime: ...
# =========================================================================
# SINCE/UNTIL
# =========================================================================
def _since(self, other: TimeDifference) -> TimeSpan: ...
def _until(self, other: TimeDifference) -> TimeSpan: ...
def since(
self,
other: Time | DateTime | ZonedDateTime,
*,
smallest: JIFF_UNIT | None = None,
largest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> TimeSpan: ...
def until(
self,
other: Time | DateTime | ZonedDateTime,
*,
smallest: JIFF_UNIT | None = None,
largest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> TimeSpan: ...
class TimeDifference:
def __init__(
self,
date: Time,
*,
smallest: JIFF_UNIT | None = None,
largest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> None: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def smallest(self, unit: JIFF_UNIT) -> TimeDifference: ...
def largest(self, unit: JIFF_UNIT) -> TimeDifference: ...
def mode(self, mode: JIFF_ROUND_MODE) -> TimeDifference: ...
def increment(self, increment: int) -> TimeDifference: ...
class DateTime(ToPy[pydt.datetime], ToPyDate, ToPyTime, ToPyDateTime):
MIN: DateTime
MAX: DateTime
ZERO: DateTime
def __init__(
self,
year: int,
month: int,
day: int,
hour: int = 0,
minute: int = 0,
second: int = 0,
nanosecond: int = 0,
) -> None: ...
def __str__(self) -> str: ...
def string(self) -> str: ...
# =========================================================================
# STRPTIME/STRFTIME/PARSE
# =========================================================================
def strftime(self, format: str) -> str: ...
@classmethod
def strptime(cls: type[DateTime], format: str, string: str) -> DateTime: ...
@classmethod
def parse(cls: type[DateTime], s: str) -> DateTime: ...
# =========================================================================
# PYTHON CONVERSIONS
# =========================================================================
@classmethod
def from_pydatetime(cls: type[DateTime], dt: pydt.datetime) -> DateTime: ...
def to_py(self) -> pydt.datetime: ...
def to_pydate(self) -> pydt.date: ...
def to_pydatetime(self) -> pydt.datetime: ...
def to_pytime(self) -> pydt.time: ...
# =========================================================================
# CLASS METHODS
# =========================================================================
@classmethod
def now(cls: type[DateTime]) -> DateTime: ...
@classmethod
def from_parts(cls: type[DateTime], date: Date, time: Time) -> DateTime: ...
# =========================================================================
# OPERATORS
# =========================================================================
def __repr__(self) -> str: ...
def __add__(
self, other: TimeSpan | SignedDuration | Duration
) -> DateTime: ...
@t.overload
def __sub__(self, other: DateTime) -> TimeSpan: ...
@t.overload
def __sub__(
self, other: TimeSpan | SignedDuration | Duration
) -> DateTime: ...
@t.overload
def __isub__(self, other: DateTime) -> TimeSpan: ...
@t.overload
def __isub__(
self, other: TimeSpan | SignedDuration | Duration
) -> DateTime: ...
# =========================================================================
# INSTANCE METHODS
# =========================================================================
def asdict(self) -> DateTimeTypedDict: ...
def checked_add(
self, other: TimeSpan | SignedDuration | Duration
) -> DateTime: ...
def date(self) -> Date: ...
def day_of_year(self) -> int: ...
def day_of_year_no_leap(self) -> int | None: ...
def days_in_month(self) -> int: ...
def days_in_year(self) -> int: ...
def duration_since(self, other: DateTime) -> SignedDuration: ...
def duration_until(self, other: DateTime) -> SignedDuration: ...
def end_of_day(self) -> DateTime: ...
def era_year(self) -> tuple[int, t.Literal["BCE", "CE"]]: ...
def first_of_month(self) -> DateTime: ...
def first_of_year(self) -> DateTime: ...
def in_leap_year(self) -> bool: ...
def in_tz(self, tz: str) -> ZonedDateTime: ...
def intz(self, tz: str) -> ZonedDateTime: ...
def iso_week_date(self) -> ISOWeekDate: ...
def last_of_month(self) -> DateTime: ...
def last_of_year(self) -> DateTime: ...
def nth_weekday(self, nth: int, weekday: WEEKDAY) -> DateTime: ...
def nth_weekday_of_month(self, nth: int, weekday: WEEKDAY) -> DateTime: ...
def round(
self,
smallest: JIFF_UNIT | None = None,
*,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> DateTime: ...
def _round(self, options: DateTimeRound) -> DateTime: ...
def saturating_add(
self, other: TimeSpan | SignedDuration | Duration
) -> DateTime: ...
def series(self, span: TimeSpan) -> JiffSeries[DateTime]: ...
def start_of_day(self) -> DateTime: ...
def time(self) -> Time: ...
def to_zoned(self, tz: TimeZone) -> ZonedDateTime: ...
def tomorrow(self) -> DateTime: ...
def yesterday(self) -> DateTime: ...
# =========================================================================
# INSTANCE METHODS W/ OVERLOADS
# =========================================================================
@t.overload
def checked_sub(self, other: DateTime) -> TimeSpan: ...
@t.overload
def checked_sub(
self, other: TimeSpan | SignedDuration | Duration
) -> DateTime: ...
@t.overload
def saturating_sub(self, other: DateTime) -> TimeSpan: ...
@t.overload
def saturating_sub(
self, other: TimeSpan | SignedDuration | Duration
) -> DateTime: ...
# =========================================================================
# PROPERTIES
# =========================================================================
@property
def year(self) -> int: ...
@property
def month(self) -> int: ...
@property
def day(self) -> int: ...
@property
def hour(self) -> int: ...
@property
def minute(self) -> int: ...
@property
def second(self) -> int: ...
@property
def millisecond(self) -> int: ...
@property
def microsecond(self) -> int: ...
@property
def nanosecond(self) -> int: ...
@property
def subsec_nanosecond(self) -> int: ...
@property
def weekday(self) -> int: ...
# =========================================================================
# SINCE/UNTIL
# =========================================================================
def _since(self, other: DateTimeDifference) -> TimeSpan: ...
def _until(self, other: DateTimeDifference) -> TimeSpan: ...
def since(
self,
other: Date | Time | DateTime | ZonedDateTime,
*,
smallest: JIFF_UNIT | None = None,
largest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> TimeSpan: ...
def until(
self,
other: Date | Time | DateTime | ZonedDateTime,
*,
smallest: JIFF_UNIT | None = None,
largest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> TimeSpan: ...
class DateTimeDifference:
def __init__(
self,
date: DateTime,
*,
smallest: JIFF_UNIT | None = None,
largest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> None: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def smallest(self, unit: JIFF_UNIT) -> DateTimeDifference: ...
def largest(self, unit: JIFF_UNIT) -> DateTimeDifference: ...
def mode(self, mode: JIFF_ROUND_MODE) -> DateTimeDifference: ...
def increment(self, increment: int) -> DateTimeDifference: ...
class TimeZone(ToPy[pydt.tzinfo], ToPyTzInfo):
def __init__(self, name: str) -> None: ...
def __eq__(self, other: object) -> bool: ...
# =========================================================================
# STRING
# =========================================================================
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
# =========================================================================
# PYTHON CONVERSIONS
# =========================================================================
def to_py(self) -> pydt.tzinfo: ...
def to_pytzinfo(self) -> pydt.tzinfo: ...
@classmethod
def from_pytzinfo(cls: type[TimeZone], tz: pydt.tzinfo) -> TimeZone: ...
# =========================================================================
# PROPERTIES
# =========================================================================
@property
def name(self) -> str: ...
# =========================================================================
# CLASS METHODS
# =========================================================================
@classmethod
def fixed(cls: type[TimeZone], offset: Offset) -> TimeZone: ...
@classmethod
def get(cls: type[TimeZone], name: str) -> TimeZone: ...
@classmethod
def posix(cls: type[TimeZone], name: str) -> TimeZone: ...
@classmethod
def system(cls: type[TimeZone]) -> TimeZone: ...
@classmethod
def try_system(cls: type[TimeZone]) -> TimeZone: ...
@classmethod
def tzif(cls: type[TimeZone], name: str, data: bytes) -> TimeZone: ...
@classmethod
def utc(cls: type[TimeZone]) -> TimeZone: ...
# =========================================================================
# INSTANCE METHODS
# =========================================================================
def iana_name(self) -> str | None: ...
def to_datetime(self, dt: Timestamp) -> DateTime: ...
def to_offset(self, timestamp: Timestamp) -> Offset: ...
def to_timestamp(self, dt: DateTime) -> Timestamp: ...
def to_zoned(self, other: DateTime) -> ZonedDateTime: ...
# =========================================================================
# NOT IMPLEMENTED
# =========================================================================
def to_ambiguous_timestamp(self) -> t.NoReturn: ...
def to_ambiguous_zoned(self) -> t.NoReturn: ...
class SignedDuration(ToPy[pydt.timedelta], ToPyTimeDelta):
MIN: SignedDuration
MAX: SignedDuration
ZERO: SignedDuration
def __init__(self, secs: int = 0, nanos: int = 0) -> None: ...
# =========================================================================
# OPERATORS/DUNDERS
# =========================================================================
def __hash__(self) -> int: ...
def __mul__(self, other: int) -> SignedDuration: ...
def __rmul__(self, other: int) -> SignedDuration: ...
def __eq__(self, other: object) -> bool: ...
def __ne__(self, other: object) -> bool: ...
def __lt__(self, other: object) -> bool: ...
def __le__(self, other: object) -> bool: ...
def __gt__(self, other: object) -> bool: ...
def __ge__(self, other: object) -> bool: ...
def __neg__(self) -> SignedDuration: ...
def __add__(self, other: SignedDuration) -> SignedDuration: ...
def __abs__(self) -> SignedDuration: ...
def __div__(self, other: int) -> SignedDuration: ...
def abs(self) -> SignedDuration: ...
def unsigned_abs(self) -> Duration: ...
def __richcmp__(
self, other: SignedDuration | pydt.timedelta, op: int
) -> bool: ...
# =========================================================================
# STRING
# =========================================================================
def __str__(self) -> str: ...
def string(self, human: bool = False) -> str: ...
# =========================================================================
# PYTHON CONVERSIONS
# =========================================================================
@classmethod
def from_pytimedelta(
cls: type[SignedDuration], td: pydt.timedelta
) -> SignedDuration: ...
def to_py(self) -> pydt.timedelta: ...
def to_pytimedelta(self) -> pydt.timedelta: ...
# =========================================================================
# CLASS METHODS
# =========================================================================
@classmethod
def parse(cls: type[SignedDuration], s: str) -> SignedDuration: ...
@classmethod
def from_hours(cls: type[SignedDuration], n: int) -> SignedDuration: ...
@classmethod
def from_micros(cls: type[SignedDuration], n: int) -> SignedDuration: ...
@classmethod
def from_millis(cls: type[SignedDuration], n: int) -> SignedDuration: ...
@classmethod
def from_mins(cls: type[SignedDuration], n: int) -> SignedDuration: ...
@classmethod
def from_nanos(cls: type[SignedDuration], n: int) -> SignedDuration: ...
@classmethod
def from_secs(cls: type[SignedDuration], n: int) -> SignedDuration: ...
@classmethod
def from_secs_f32(
cls: type[SignedDuration], n: float
) -> SignedDuration: ...
@classmethod
def from_secs_f64(
cls: type[SignedDuration], n: float
) -> SignedDuration: ...
# =========================================================================
# PROPERTIES
# =========================================================================
@property
def is_negative(self) -> bool: ...
@property
def is_zero(self) -> bool: ...
@property
def secs(self) -> int: ...
@property
def nanos(self) -> int: ...
@property
def days(self) -> int: ...
@property
def seconds(self) -> int: ...
@property
def microseconds(self) -> int: ...
# =========================================================================
# INSTANCE METHODS
# =========================================================================
def as_hours(self) -> int: ...
def as_micros(self) -> int: ...
def as_millis(self) -> int: ...
def as_millis_f32(self) -> float: ...
def as_millis_f64(self) -> float: ...
def as_mins(self) -> int: ...
def as_nanos(self) -> int: ...
def as_secs(self) -> int: ...
def as_secs_f32(self) -> float: ...
def as_secs_f64(self) -> float: ...
def checked_add(self, other: SignedDuration) -> SignedDuration | None: ...
def checked_div(self, other: int) -> SignedDuration | None: ...
def checked_mul(self, other: int) -> SignedDuration | None: ...
def checked_neg(self) -> SignedDuration | None: ...
def checked_sub(self, other: SignedDuration) -> SignedDuration | None: ...
def div_duration_f32(self, other: SignedDuration) -> float: ...
def div_duration_f64(self, other: SignedDuration) -> float: ...
def div_f32(self, other: int) -> float: ...
def div_f64(self, other: int) -> float: ...
def is_positive(self) -> bool: ...
def mul_f32(self, other: int) -> SignedDuration: ...
def mul_f64(self, other: int) -> SignedDuration: ...
def saturating_add(self, other: SignedDuration) -> SignedDuration: ...
def saturating_mul(self, other: int) -> SignedDuration: ...
def saturating_sub(self, other: SignedDuration) -> SignedDuration: ...
def signum(self) -> t.Literal[-1, 0, 1]: ...
def subsec_micros(self) -> int: ...
def subsec_millis(self) -> int: ...
def subsec_nanos(self) -> int: ...
def to_timespan(self) -> TimeSpan: ...
# put in quotes to avoid ruff F821 - undefined name
_TimeSpanArithmeticSingle = TimeSpan | Duration | SignedDuration
_TimeSpanArithmeticTuple = tuple[
_TimeSpanArithmeticSingle, ZonedDateTime | Date | DateTime
]
TimeSpanArithmetic = _TimeSpanArithmeticSingle | _TimeSpanArithmeticTuple
class TimeSpan(ToPy[pydt.timedelta], ToPyTimeDelta):
def __init__(
self,
years: int = 0,
months: int = 0,
weeks: int = 0,
days: int = 0,
hours: int = 0,
minutes: int = 0,
seconds: int = 0,
milliseconds: int = 0,
microseconds: int = 0,
nanoseconds: int = 0,
) -> None: ...
# =========================================================================
# STRING
# =========================================================================
def string(self, human: bool = False) -> str: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def repr_full(self) -> str: ...
# =========================================================================
# PYTHON CONVERSIONS
# =========================================================================
@classmethod
def from_pytimedelta(cls, td: pydt.timedelta) -> TimeSpan: ...
def to_pytimedelta(self) -> pydt.timedelta: ...
def to_py(self) -> pydt.timedelta: ...
# =========================================================================
# CLASS METHODS
# =========================================================================
@classmethod
def parse(cls, s: str) -> TimeSpan: ...
# =========================================================================
# PROPERTIES
# =========================================================================
@property
def is_positive(self) -> bool: ...
@property
def is_negative(self) -> bool: ...
@property
def is_zero(self) -> bool: ...
@property
def years(self) -> int: ...
@property
def months(self) -> int: ...
@property
def weeks(self) -> int: ...
@property
def days(self) -> int: ...
@property
def hours(self) -> int: ...
@property
def minutes(self) -> int: ...
@property
def seconds(self) -> int: ...
@property
def milliseconds(self) -> int: ...
@property
def microseconds(self) -> int: ...
@property
def nanoseconds(self) -> int: ...
# =========================================================================
# OPERATORS
# =========================================================================
def __add__(
self,
val: TimeSpanArithmetic,
) -> te.Self: ...
def __sub__(
self,
val: TimeSpanArithmetic,
) -> te.Self: ...
def __mul__(self, other: int) -> te.Self: ...
def __neg__(self) -> te.Self: ...
def __abs__(self) -> te.Self: ...
def __invert__(self) -> te.Self: ...
def __eq__(self, other: object) -> bool: ...
def __ge__(self, other: TimeSpan) -> bool: ...
def __gt__(self, other: TimeSpan) -> bool: ...
def __le__(self, other: TimeSpan) -> bool: ...
def __lt__(self, other: TimeSpan) -> bool: ...
def __ne__(self, other: object) -> bool: ...
def __rmul__(self, other: TimeSpan) -> bool: ...
def __hash__(self) -> int: ...
# =========================================================================
# INSTANCE METHODS
# =========================================================================
def abs(self) -> te.Self: ...
def asdict(self) -> TimeSpanTypedDict: ...
def checked_add(self, val: TimeSpanArithmetic) -> te.Self: ...
def checked_mul(self, other: int) -> te.Self: ...
def checked_sub(self, val: TimeSpanArithmetic) -> te.Self: ...
def compare(
self,
other: TimeSpan,
relative: ZonedDateTime | DateTime | Date | None = None,
days_are_24_hours: bool = False,
) -> int: ...
def negate(self) -> te.Self: ...
def replace(
self,
years: int | None = None,
months: int | None = None,
weeks: int | None = None,
days: int | None = None,
hours: int | None = None,
minutes: int | None = None,
seconds: int | None = None,
milliseconds: int | None = None,
microseconds: int | None = None,
nanoseconds: int | None = None,
) -> te.Self: ...
def round(
self,
smallest: JIFF_UNIT,
increment: int = 1,
*,
relative: ZonedDateTime | Date | DateTime | None = None,
largest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
) -> te.Self: ...
def signum(self) -> t.Literal[-1, 0, 1]: ...
def to_signed_duration(
self, relative: ZonedDateTime | Date | DateTime
) -> SignedDuration: ...
def total(
self,
unit: JIFF_UNIT,
relative: ZonedDateTime | Date | DateTime | None = None,
days_are_24_hours: bool = False,
) -> int: ...
def total_seconds(self) -> int: ...
def try_years(self, years: int) -> te.Self: ...
def try_months(self, months: int) -> te.Self: ...
def try_weeks(self, weeks: int) -> te.Self: ...
def try_days(self, days: int) -> te.Self: ...
def try_hours(self, hours: int) -> te.Self: ...
def try_minutes(self, minutes: int) -> te.Self: ...
def try_seconds(self, seconds: int) -> te.Self: ...
def try_milliseconds(self, milliseconds: int) -> te.Self: ...
def try_microseconds(self, microseconds: int) -> te.Self: ...
def try_nanoseconds(self, nanoseconds: int) -> te.Self: ...
# -------------------------------------------------------------------------
# PANIC-INDUCING METHODS
# -------------------------------------------------------------------------
def _years(self, years: int) -> te.Self: ...
def _months(self, months: int) -> te.Self: ...
def _weeks(self, weeks: int) -> te.Self: ...
def _days(self, days: int) -> te.Self: ...
def _hours(self, hours: int) -> te.Self: ...
def _minutes(self, minutes: int) -> te.Self: ...
def _seconds(self, seconds: int) -> te.Self: ...
def _milliseconds(self, milliseconds: int) -> te.Self: ...
def _microseconds(self, microseconds: int) -> te.Self: ...
def _nanoseconds(self, nanoseconds: int) -> te.Self: ...
class Timestamp(ToPy[pydt.datetime], ToPyDate, ToPyTime, ToPyDateTime):
"""
A representation of a timestamp with second and nanosecond precision.
"""
MIN: Timestamp
MAX: Timestamp
UNIX_EPOCH: Timestamp
def __init__(
self, second: int | None = None, nanosecond: int | None = None
) -> None: ...
# =========================================================================
# CLASS METHODS
# =========================================================================
@classmethod
def now(cls) -> Timestamp: ...
@classmethod
def parse(cls, s: str) -> Timestamp: ...
@classmethod
def from_millisecond(cls, millisecond: int) -> Timestamp: ...
@classmethod
def from_microsecond(cls, microsecond: int) -> Timestamp: ...
@classmethod
def from_nanosecond(cls, nanosecond: int) -> Timestamp: ...
@classmethod
def from_second(cls, second: int) -> Timestamp: ...
# =========================================================================
# STRING
# =========================================================================
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
# =========================================================================
# OPERATORS/DUNDERS
# =========================================================================
def __add__(
self, other: TimeSpan | SignedDuration | Duration
) -> te.Self: ...
def __eq__(self, other: object) -> bool: ...
def __ge__(self, other: Timestamp) -> bool: ...
def __gt__(self, other: Timestamp) -> bool: ...
def __le__(self, other: Timestamp) -> bool: ...
def __lt__(self, other: Timestamp) -> bool: ...
def __ne__(self, other: object) -> bool: ...
def __richcmp__(self, other: Timestamp, op: int) -> bool: ...
# =========================================================================
# OPERATORS/DUNDERS W/ OVERLOADS
# =========================================================================
@t.overload
def __isub__(self, other: Timestamp) -> TimeSpan: ...
@t.overload
def __isub__(
self, other: TimeSpan | SignedDuration | Duration
) -> te.Self: ...
@t.overload
def __sub__(self, other: Timestamp) -> TimeSpan: ...
@t.overload
def __sub__(
self, other: TimeSpan | SignedDuration | Duration
) -> te.Self: ...
# =========================================================================
# PYTHON CONVERSIONS
# =========================================================================
@classmethod
def from_pydatetime(cls, dt: pydt.datetime) -> Timestamp: ...
def to_py(self) -> pydt.datetime: ...
def to_pydate(self) -> pydt.date: ...
def to_pydatetime(self) -> pydt.datetime: ...
def to_pytime(self) -> pydt.time: ...
# =========================================================================
# STRPTIME/STRFTIME
# =========================================================================
def strftime(self, format: str) -> str: ...
@classmethod
def strptime(cls, format: str, input: str) -> Timestamp: ...
# =========================================================================
# INSTANCE METHODS
# =========================================================================
def as_microsecond(self) -> int: ...
def as_millisecond(self) -> int: ...
def as_nanosecond(self) -> int: ...
def as_second(self) -> int: ...
def checked_add(
self, other: TimeSpan | SignedDuration | Duration
) -> Timestamp: ...
@t.overload
def checked_sub(self, other: Timestamp) -> TimeSpan: ...
@t.overload
def checked_sub(
self, other: TimeSpan | SignedDuration | Duration
) -> Timestamp: ...
def display_with_offset(self, offset: Offset) -> str: ...
def in_tz(self, tz: str) -> ZonedDateTime: ...
def intz(self, tz: str) -> ZonedDateTime:
"""Deprecated ~ use `in_tz`"""
def is_zero(self) -> bool: ...
def saturating_add(
self, other: TimeSpan | SignedDuration | Duration
) -> Timestamp: ...
def saturating_sub(
self, other: TimeSpan | SignedDuration | Duration
) -> Timestamp: ...
def series(self, span: TimeSpan) -> JiffSeries[Timestamp]: ...
def signum(self) -> t.Literal[-1, 0, 1]: ...
def string(self) -> str: ...
def subsec_microsecond(self) -> int: ...
def subsec_millisecond(self) -> int: ...
def subsec_nanosecond(self) -> int: ...
def to_zoned(self, time_zone: TimeZone) -> ZonedDateTime: ...
# =========================================================================
# SINCE/UNTIL
# =========================================================================
def _since(self, other: TimestampDifference) -> TimeSpan: ...
def _until(self, other: TimestampDifference) -> TimeSpan: ...
def since(
self,
other: Timestamp | ZonedDateTime,
*,
smallest: JIFF_UNIT | None = None,
largest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> TimeSpan: ...
def until(
self,
other: Timestamp | ZonedDateTime,
*,
smallest: JIFF_UNIT | None = None,
largest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> TimeSpan: ...
def duration_since(self, other: Timestamp) -> SignedDuration: ...
def duration_until(self, other: Timestamp) -> SignedDuration: ...
def round(
self,
unit: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> Timestamp: ...
def _round(self, options: TimestampRound) -> Timestamp: ...
class TimestampDifference:
def __init__(
self,
date: Timestamp,
*,
smallest: JIFF_UNIT | None = None,
largest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> None: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def smallest(self, unit: JIFF_UNIT) -> TimestampDifference: ...
def largest(self, unit: JIFF_UNIT) -> TimestampDifference: ...
def mode(self, mode: JIFF_ROUND_MODE) -> TimestampDifference: ...
def increment(self, increment: int) -> TimestampDifference: ...
class ZonedDateTime(
ToPy[pydt.datetime], ToPyDate, ToPyTime, ToPyDateTime, ToPyTzInfo
):
def __init__(self, timestamp: Timestamp, time_zone: TimeZone) -> None: ...
# =========================================================================
# PYTHON CONVERSIONS
# =========================================================================
@classmethod
def from_pydatetime(
cls: type[ZonedDateTime], dt: pydt.datetime
) -> ZonedDateTime: ...
def to_py(self) -> pydt.datetime: ...
def to_pydate(self) -> pydt.date: ...
def to_pydatetime(self) -> pydt.datetime: ...
def to_pytime(self) -> pydt.time: ...
def to_pytzinfo(self) -> pydt.tzinfo: ...
# =========================================================================
# CLASS METHODS
# =========================================================================
@classmethod
def now(
cls: type[ZonedDateTime], tz: str | None = None
) -> ZonedDateTime: ...
@classmethod
def utcnow(cls: type[ZonedDateTime]) -> ZonedDateTime: ...
@classmethod
def parse(cls: type[ZonedDateTime], s: str) -> ZonedDateTime: ...
@classmethod
def from_rfc2822(cls: type[ZonedDateTime], s: str) -> ZonedDateTime: ...
# =========================================================================
# STRPTIME/STRFTIME
# =========================================================================
@classmethod
def strptime(
cls: type[ZonedDateTime], format: str, input: str
) -> ZonedDateTime: ...
def strftime(self, format: str) -> str: ...
# =========================================================================
# PROPERTIES
# =========================================================================
@property
def year(self) -> int: ...
@property
def month(self) -> int: ...
@property
def day(self) -> int: ...
@property
def hour(self) -> int: ...
@property
def minute(self) -> int: ...
@property
def second(self) -> int: ...
@property
def millisecond(self) -> int: ...
@property
def microsecond(self) -> int: ...
@property
def nanosecond(self) -> int: ...
@property
def subsec_nanosecond(self) -> int: ...
@property
def weekday(self) -> int: ...
# =========================================================================
# STRING
# =========================================================================
def __str__(self) -> str: ...
def string(self) -> str: ...
# =========================================================================
# OPERATORS/DUNDERS
# =========================================================================
def __add__(
self, other: TimeSpan | SignedDuration | Duration
) -> te.Self: ...
def __eq__(self, other: object) -> bool: ...
def __ge__(self, other: ZonedDateTime) -> bool: ...
def __gt__(self, other: ZonedDateTime) -> bool: ...
def __hash__(self) -> int: ...
def __le__(self, other: ZonedDateTime) -> bool: ...
def __lt__(self, other: ZonedDateTime) -> bool: ...
def __ne__(self, other: object) -> bool: ...
def __richcmp__(self, other: ZonedDateTime, op: int) -> bool: ...
# =========================================================================
# OPERATORS/DUNDERS W/ OVERLOADS
# =========================================================================
@t.overload
def __isub__(self, other: ZonedDateTime) -> TimeSpan: ...
@t.overload
def __isub__(
self, other: TimeSpan | SignedDuration | Duration
) -> te.Self: ...
@t.overload
def __sub__(self, other: ZonedDateTime) -> TimeSpan: ...
@t.overload
def __sub__(
self, other: TimeSpan | SignedDuration | Duration
) -> te.Self: ...
# =========================================================================
# INSTANCE METHODS
# =========================================================================
def astimezone(self, tz: str) -> ZonedDateTime: ...
def checked_add(
self, other: TimeSpan | SignedDuration | Duration
) -> te.Self: ...
@t.overload
def checked_sub(self, other: ZonedDateTime) -> TimeSpan: ...
@t.overload
def checked_sub(
self, other: TimeSpan | SignedDuration | Duration
) -> te.Self: ...
def date(self) -> Date: ...
def datetime(self) -> DateTime: ...
def iso_week_date(self) -> ISOWeekDate: ...
def day_of_year(self) -> int: ...
def day_of_year_no_leap(self) -> int | None: ...
def days_in_month(self) -> int: ...
def days_in_year(self) -> int: ...
def duration_since(self, other: ZonedDateTime) -> SignedDuration: ...
def duration_until(self, other: ZonedDateTime) -> SignedDuration: ...
def end_of_day(self) -> ZonedDateTime: ...
def era_year(self) -> tuple[int, t.Literal["CE", "BCE"]]: ...
def first_of_month(self) -> ZonedDateTime: ...
def first_of_year(self) -> ZonedDateTime: ...
def in_leap_year(self) -> bool: ...
def in_tz(self, tz: str) -> te.Self: ...
def intz(self, tz: str) -> te.Self: ...
def inutc(self) -> ZonedDateTime: ...
def last_of_month(self) -> ZonedDateTime: ...
def last_of_year(self) -> ZonedDateTime: ...
def nth_weekday(self, nth: int, weekday: WEEKDAY) -> Date: ...
def nth_weekday_of_month(self, nth: int, weekday: WEEKDAY) -> Date: ...
def offset(self) -> Offset: ...
def round(
self,
smallest: JIFF_UNIT | None = None,
*,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> DateTime: ...
def _round(self, options: ZonedDateTimeRound) -> DateTime: ...
def saturating_add(
self, other: TimeSpan | SignedDuration | Duration
) -> te.Self: ...
@t.overload
def saturating_sub(self, other: ZonedDateTime) -> TimeSpan: ...
@t.overload
def saturating_sub(
self, other: TimeSpan | SignedDuration | Duration
) -> te.Self: ...
def start_of_day(self) -> ZonedDateTime: ...
def time(self) -> Time: ...
def time_zone(self) -> TimeZone: ...
def timestamp(self) -> Timestamp: ...
def timezone(self) -> TimeZone: ...
def to_rfc2822(self) -> str: ...
def tomorrow(self) -> ZonedDateTime: ...
def with_time_zone(self, tz: TimeZone) -> ZonedDateTime: ...
def yesterday(self) -> ZonedDateTime: ...
# =========================================================================
# SINCE/UNTIL
# =========================================================================
def since(
self,
other: ZonedDateTime,
*,
smallest: JIFF_UNIT | None = None,
largest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> TimeSpan: ...
def until(
self,
other: ZonedDateTime,
*,
smallest: JIFF_UNIT | None = None,
largest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> TimeSpan: ...
class ZonedDateTimeDifference:
def __init__(
self,
date: ZonedDateTime,
*,
smallest: JIFF_UNIT | None = None,
largest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> None: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def smallest(self, unit: JIFF_UNIT) -> ZonedDateTimeDifference: ...
def largest(self, unit: JIFF_UNIT) -> ZonedDateTimeDifference: ...
def mode(self, mode: JIFF_ROUND_MODE) -> ZonedDateTimeDifference: ...
def increment(self, increment: int) -> ZonedDateTimeDifference: ...
class ISOWeekDate:
MIN: ISOWeekDate
MAX: ISOWeekDate
ZERO: ISOWeekDate
def __init__(self, year: int, week: int, weekday: WEEKDAY) -> None: ...
# =========================================================================
# OPERATORS/DUNDERS
# =========================================================================
def __eq__(self, other: object) -> bool: ...
def __ne__(self, other: object) -> bool: ...
def __lt__(self, other: ISOWeekDate) -> bool: ...
def __le__(self, other: ISOWeekDate) -> bool: ...
def __gt__(self, other: ISOWeekDate) -> bool: ...
def __ge__(self, other: ISOWeekDate) -> bool: ...
def __hash__(self) -> int: ...
# =========================================================================
# STRING
# =========================================================================
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
# =========================================================================
# CLASS METHODS
# =========================================================================
@classmethod
def from_date(cls: type[ISOWeekDate], date: Date) -> ISOWeekDate: ...
@classmethod
def today(cls: type[ISOWeekDate]) -> ISOWeekDate: ...
# =========================================================================
# PROPERTIES
# =========================================================================
@property
def year(self) -> int: ...
@property
def week(self) -> int: ...
@property
def weekday(self) -> WEEKDAY_INT: ...
# =========================================================================
# INSTANCE METHODS
# =========================================================================
def date(self) -> Date: ...
class TimestampRound:
def __init__(
self,
smallest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int = 1,
) -> None: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def __eq__(self, other: object) -> bool: ...
def mode(self, mode: JIFF_ROUND_MODE) -> TimestampRound: ...
def smallest(self, smallest: JIFF_UNIT) -> TimestampRound: ...
def increment(self, increment: int) -> TimestampRound: ...
def _smallest(self) -> JIFF_UNIT: ...
def _mode(self) -> JIFF_ROUND_MODE: ...
def _increment(self) -> int: ...
def replace(
self,
smallest: JIFF_UNIT | None,
mode: JIFF_ROUND_MODE | None,
increment: int | None,
) -> TimestampRound: ...
class DateTimeRound:
def __init__(
self,
smallest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int = 1,
) -> None: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def __eq__(self, other: object) -> bool: ...
def mode(self, mode: JIFF_ROUND_MODE) -> DateTimeRound: ...
def smallest(self, smallest: JIFF_UNIT) -> DateTimeRound: ...
def increment(self, increment: int) -> DateTimeRound: ...
def _smallest(self) -> JIFF_UNIT: ...
def _mode(self) -> JIFF_ROUND_MODE: ...
def _increment(self) -> int: ...
def replace(
self,
smallest: JIFF_UNIT | None,
mode: JIFF_ROUND_MODE | None,
increment: int | None,
) -> DateTimeRound: ...
class ZonedDateTimeRound:
def __init__(
self,
smallest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int = 1,
) -> None: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def __eq__(self, other: object) -> bool: ...
def mode(self, mode: JIFF_ROUND_MODE) -> DateTimeRound: ...
def smallest(self, smallest: JIFF_UNIT) -> DateTimeRound: ...
def increment(self, increment: int) -> DateTimeRound: ...
def _smallest(self) -> JIFF_UNIT: ...
def _mode(self) -> JIFF_ROUND_MODE: ...
def _increment(self) -> int: ...
def replace(
self,
smallest: JIFF_UNIT | None,
mode: JIFF_ROUND_MODE | None,
increment: int | None,
) -> DateTimeRound: ...
class Offset(ToPy[pydt.tzinfo], ToPyTzInfo):
MIN: Offset
MAX: Offset
UTC: Offset
ZERO: Offset
def __init__(
self, hours: int | None = None, seconds: int | None = None
) -> None: ...
# =========================================================================
# STRING
# =========================================================================
def string(self) -> str: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
# =========================================================================
# OPERATORS/DUNDERS
# =========================================================================
def __neg__(self) -> Offset: ...
def __eq__(self, other: object) -> bool: ...
def __ne__(self, other: object) -> bool: ...
def __lt__(self, other: Offset) -> bool: ...
def __le__(self, other: Offset) -> bool: ...
def __gt__(self, other: Offset) -> bool: ...
def __ge__(self, other: Offset) -> bool: ...
def __hash__(self) -> int: ...
# =========================================================================
# PYTHON CONVERSIONS
# =========================================================================
# __FROM__
@classmethod
def from_pytzinfo(cls: type[Offset], tz: pydt.tzinfo) -> Offset: ...
# __TO__
def to_py(self) -> pydt.tzinfo: ...
def to_pytzinfo(self) -> pydt.tzinfo: ...
# =========================================================================
# PROPERTIES
# =========================================================================
@property
def seconds(self) -> int: ...
@property
def is_negative(self) -> bool: ...
@property
def is_positive(self) -> bool: ...
# =========================================================================
# FROM
# =========================================================================
@classmethod
def utc(cls: type[Offset]) -> Offset: ...
@classmethod
def from_hours(cls: type[Offset], hours: int) -> Offset: ...
@classmethod
def from_seconds(cls: type[Offset], seconds: int) -> Offset: ...
# =========================================================================
# TO
# =========================================================================
def to_datetime(self, timestamp: Timestamp) -> DateTime: ...
def to_timestamp(self, datetime: DateTime) -> Timestamp: ...
def to_timezone(self) -> TimeZone: ...
# =========================================================================
# INSTANCE METHODS
# =========================================================================
def checked_add(
self, other: Duration | SignedDuration | TimeSpan
) -> Offset: ...
def checked_sub(
self, other: Duration | SignedDuration | TimeSpan
) -> Offset: ...
def duration_since(self, other: Offset) -> SignedDuration: ...
def duration_until(self, other: Offset) -> SignedDuration: ...
def negate(self) -> Offset: ...
def saturating_add(
self, other: Duration | SignedDuration | TimeSpan
) -> Offset: ...
def saturating_sub(
self, other: Duration | SignedDuration | TimeSpan
) -> Offset: ...
def since(self, other: Offset) -> TimeSpan: ...
def until(self, other: Offset) -> TimeSpan: ...
class JiffSeries(
t.Generic[T],
):
def __iter__(self) -> t.Iterator[T]: ...
def __next__(self) -> T: ...
def take(self, n: int) -> list[T]: ...
def date(year: int, month: int, day: int) -> Date: ...
def time(
hour: int = 0, minute: int = 0, second: int = 0, nanosecond: int = 0
) -> Time: ...
def datetime(
year: int,
month: int,
day: int,
hour: int = 0,
minute: int = 0,
second: int = 0,
nanosecond: int = 0,
) -> DateTime: ...
def timespan(
*,
years: int = 0,
months: int = 0,
weeks: int = 0,
days: int = 0,
hours: int = 0,
minutes: int = 0,
seconds: int = 0,
milliseconds: int = 0,
microseconds: int = 0,
nanoseconds: int = 0,
unchecked: bool = False,
) -> TimeSpan: ...
def offset(hours: int) -> Offset: ...
# =============================================================================
# TIMEZONE-DATABASE
# =============================================================================
class TimeZoneDatabase:
def __init__(self) -> None:
"""Defaults to using the `self.from_env`"""
@t.overload
def get(self, name: str, err: t.Literal[False]) -> TimeZone | None:
"""Returns TimeZone or None if the timezone is not found"""
@t.overload
def get(self, name: str, err: t.Literal[True] = True) -> TimeZone:
"""Returns TimeZone, if not found raises a ValueError"""
def available(self) -> list[str]: ...
def __getitem__(self, name: str) -> TimeZone: ...
def __len__(self) -> int: ...
def is_definitively_empty(self) -> bool: ...
@classmethod
def from_env(cls) -> TimeZoneDatabase: ...
@classmethod
def from_dir(cls, path: str) -> TimeZoneDatabase: ...
@classmethod
def from_concatenated_path(cls, path: str) -> TimeZoneDatabase: ...
ry.ryo3._jiter
from __future__ import annotations
import typing as t
import typing_extensions as te
from ry._types import Buffer
# =============================================================================
# JSON
# =============================================================================
JsonPrimitive = None | bool | int | float | str
JsonValue = (
JsonPrimitive
| dict[str, JsonPrimitive | JsonValue]
| list[JsonPrimitive | JsonValue]
)
class JsonParseKwargs(t.TypedDict, total=False):
allow_inf_nan: bool
"""Allow parsing of `Infinity`, `-Infinity`, `NaN` ~ default: True"""
cache_mode: t.Literal[True, False, "all", "keys", "none"]
"""Cache mode for JSON parsing ~ default: `all` """
partial_mode: t.Literal[True, False, "off", "on", "trailing-strings"]
"""Partial mode for JSON parsing ~ default: False"""
catch_duplicate_keys: bool
"""Catch duplicate keys in JSON objects ~ default: False"""
float_mode: t.Literal["float", "decimal", "lossless-float"] | bool
"""Mode for parsing JSON floats ~ default: False"""
def parse_json(
data: Buffer | bytes | str,
/,
**kwargs: te.Unpack[JsonParseKwargs],
) -> JsonValue: ...
def parse_json_bytes(
data: bytes,
/,
**kwargs: te.Unpack[JsonParseKwargs],
) -> JsonValue: ...
def json_cache_clear() -> None: ...
def json_cache_usage() -> int: ...
ry.ryo3._quick_maths
"""ryo3-quick-maths types"""
from __future__ import annotations
import typing as t
def quick_maths() -> t.Literal[3]:
"""Performs quick-maths
Implements the algorithm for performing "quick-maths" as described by
Big Shaq in his PHD thesis, 2017, in which he states:
> "2 plus 2 is 4, minus one that's 3, quick maths." (Big Shaq et al., 2017)
Reference:
https://youtu.be/3M_5oYU-IsU?t=60
Example:
>>> import ry
>>> result = ry.quick_maths()
>>> assert result == 3
NOTE: THIS IS FROM MY TEMPLATE RY03-MODULE
"""
ry.ryo3._regex
"""ryo3-regex types"""
from __future__ import annotations
# =============================================================================
# Regex
# =============================================================================
class Regex:
def __init__(
self,
pattern: str,
*,
case_insensitive: bool = False,
crlf: bool = False,
dot_matches_new_line: bool = False,
ignore_whitespace: bool = False,
line_terminator: str | None = None,
multi_line: bool = False,
octal: bool = False,
size_limit: int | None = None,
swap_greed: bool = False,
unicode: bool = False,
) -> None: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def is_match(self, string: str) -> bool: ...
ry.ryo3._reqwest
import typing as t
from http import HTTPStatus
import ry
if t.TYPE_CHECKING:
from ry.http import Headers
from ry.ryo3 import URL, Duration
class HttpClient:
def __init__(
self,
*,
headers: dict[str, str] | None = None,
user_agent: str | None = None, # default ~ 'ry-reqwest/<VERSION> ...'
timeout: Duration | None = None,
connect_timeout: Duration | None = None,
read_timeout: Duration | None = None,
gzip: bool = True,
brotli: bool = True,
deflate: bool = True,
) -> None: ...
async def get(
self, url: str | URL, *, headers: dict[str, str] | None = None
) -> Response: ...
async def post(
self,
url: str | URL,
*,
body: bytes | None = None,
headers: dict[str, str] | None = None,
) -> Response: ...
async def put(
self,
url: str | URL,
*,
body: bytes | None = None,
headers: dict[str, str] | None = None,
) -> Response: ...
async def delete(
self, url: str | URL, *, headers: dict[str, str] | None = None
) -> Response: ...
async def patch(
self,
url: str | URL,
*,
body: bytes | None = None,
headers: dict[str, str] | None = None,
) -> Response: ...
async def head(
self, url: str | URL, *, headers: dict[str, str] | None = None
) -> Response: ...
async def fetch(
self,
url: str | URL,
*,
method: str = "GET",
body: bytes | None = None,
headers: dict[str, str] | None = None,
) -> Response: ...
class ReqwestError(Exception):
def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def __dbg__(self) -> str: ...
def is_body(self) -> bool: ...
def is_builder(self) -> bool: ...
def is_connect(self) -> bool: ...
def is_decode(self) -> bool: ...
def is_redirect(self) -> bool: ...
def is_request(self) -> bool: ...
def is_status(self) -> bool: ...
def is_timeout(self) -> bool: ...
def status(self) -> HTTPStatus | None: ...
def url(self) -> URL | None: ...
class Response:
status_code: int
@property
def headers(self) -> Headers: ...
async def text(self) -> str: ...
async def json(self) -> t.Any: ...
async def bytes(self) -> ry.Bytes: ...
def bytes_stream(self) -> ResponseStream: ...
class ResponseStream:
def __aiter__(self) -> ResponseStream: ...
async def __anext__(self) -> ry.Bytes: ...
async def fetch(
url: str | URL,
*,
client: HttpClient | None = None,
method: str = "GET",
body: bytes | None = None,
headers: dict[str, str] | None = None,
) -> Response: ...
ry.ryo3._same_file
"""ryo3-same-file types"""
from __future__ import annotations
from os import PathLike
def is_same_file(a: PathLike[str], b: PathLike[str]) -> bool: ...
ry.ryo3._shlex
"""ryo3-shlex types"""
from __future__ import annotations
def shplit(s: str) -> list[str]:
"""shlex::split wrapper much like python's stdlib shlex.split but faster"""
...
ry.ryo3._size
from __future__ import annotations
from typing import Literal
FORMAT_SIZE_BASE = Literal[2, 10] # default=2
FORMAT_SIZE_STYLE = Literal[ # default="default"
"default",
"abbreviated",
"abbreviated_lowercase",
"abbreviated-lowercase",
"full",
"full-lowercase",
"full_lowercase",
]
def fmt_size(
n: int,
*,
base: FORMAT_SIZE_BASE | None = 2,
style: FORMAT_SIZE_STYLE | None = "default",
) -> str:
"""Return human-readable string representation of bytes-size."""
def parse_size(s: str) -> int:
"""Return integer representation of human-readable bytes-size string.
Raises:
ValueError: If string is not a valid human-readable bytes-size string.
"""
class SizeFormatter:
"""Human-readable bytes-size formatter."""
def __init__(
self,
base: FORMAT_SIZE_BASE | None = 2,
style: FORMAT_SIZE_STYLE | None = "default",
) -> None:
"""Initialize human-readable bytes-size formatter."""
def format(self, n: int) -> str:
"""Return human-readable string representation of bytes-size."""
def __call__(self, n: int) -> str:
"""Return human-readable string representation of bytes-size."""
def __repr__(self) -> str: ...
def __str__(self) -> str: ...
class Size:
"""Bytes-size object."""
def __init__(self, size: int) -> None: ...
def __int__(self) -> int: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def __hash__(self) -> int: ...
def __abs__(self) -> Size: ...
def __neg__(self) -> Size: ...
def __eq__(self, other: object) -> bool: ...
def __ne__(self, other: object) -> bool: ...
def __lt__(self, other: Size | int | float) -> bool: ...
def __le__(self, other: Size | int | float) -> bool: ...
def __gt__(self, other: Size | int | float) -> bool: ...
def __ge__(self, other: Size | int | float) -> bool: ...
def __bool__(self) -> bool: ...
def __pos__(self) -> Size: ...
def __invert__(self) -> Size: ...
def __add__(self, other: Size | int | float) -> Size: ...
def __sub__(self, other: Size | int | float) -> Size: ...
def __mul__(self, other: Size | int | float) -> Size: ...
def __rmul__(self, other: Size | int | float) -> Size: ...
@property
def bytes(self) -> int: ...
def format(
self,
base: FORMAT_SIZE_BASE | None = 2,
style: FORMAT_SIZE_STYLE | None = "default",
) -> str: ...
# =========================================================================
# CLASS-METHODS
# =========================================================================
# -------------------------------------------------------------------------
# PARSING
# -------------------------------------------------------------------------
@classmethod
def parse(cls: type[Size], size: str) -> Size: ...
@classmethod
def from_str(cls: type[Size], size: str) -> Size: ...
# -------------------------------------------------------------------------
# BYTES
# -------------------------------------------------------------------------
@classmethod
def from_bytes(cls: type[Size], size: int | float) -> Size: ...
# -------------------------------------------------------------------------
# KILOBYTES
# -------------------------------------------------------------------------
@classmethod
def from_kb(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_kib(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_kibibytes(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_kilobytes(cls: type[Size], size: int | float) -> Size: ...
# -------------------------------------------------------------------------
# MEGABYTES
# -------------------------------------------------------------------------
@classmethod
def from_mb(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_mebibytes(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_megabytes(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_mib(cls: type[Size], size: int | float) -> Size: ...
# -------------------------------------------------------------------------
# GIGABYTES
# -------------------------------------------------------------------------
@classmethod
def from_gb(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_gib(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_gibibytes(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_gigabytes(cls: type[Size], size: int | float) -> Size: ...
# -------------------------------------------------------------------------
# TERABYTES
# -------------------------------------------------------------------------
@classmethod
def from_tb(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_tebibytes(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_terabytes(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_tib(cls: type[Size], size: int | float) -> Size: ...
# -------------------------------------------------------------------------
# PETABYTES
# -------------------------------------------------------------------------
@classmethod
def from_pb(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_pebibytes(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_petabytes(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_pib(cls: type[Size], size: int | float) -> Size: ...
# -------------------------------------------------------------------------
# EXABYTES
# -------------------------------------------------------------------------
@classmethod
def from_eb(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_eib(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_exabytes(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_exbibytes(cls: type[Size], size: int | float) -> Size: ...
ry.ryo3._sqlformat
from __future__ import annotations
import typing as t
# =============================================================================
# SQLFORMAT
# =============================================================================
SqlfmtParamValue = str | int | float | bool
TSqlfmtParamValue_co = t.TypeVar(
"TSqlfmtParamValue_co", bound=SqlfmtParamValue, covariant=True
)
SqlfmtParamsLike = (
dict[str, TSqlfmtParamValue_co]
| t.Sequence[tuple[str, TSqlfmtParamValue_co]]
| t.Sequence[TSqlfmtParamValue_co]
)
class SqlfmtQueryParams:
def __init__(
self, params: SqlfmtParamsLike[TSqlfmtParamValue_co]
) -> None: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def sqlfmt_params(
params: SqlfmtParamsLike[TSqlfmtParamValue_co] | SqlfmtQueryParams,
) -> SqlfmtQueryParams: ...
def sqlfmt(
sql: str,
params: SqlfmtParamsLike[TSqlfmtParamValue_co]
| SqlfmtQueryParams
| None = None,
*,
indent: int = 2, # -1 or any negative value will use tabs
uppercase: bool | None = True,
lines_between_statements: int = 1,
) -> str: ...
ry.ryo3._std
"""ryo3-std types"""
from __future__ import annotations
import datetime as pydt
import typing as t
from ry import Bytes, FsPath
from ry._types import Buffer, FsPathLike
# =============================================================================
# STD::TIME
# =============================================================================
class Duration:
ZERO: Duration
MIN: Duration
MAX: Duration
NANOSECOND: Duration
MICROSECOND: Duration
MILLISECOND: Duration
SECOND: Duration
def __init__(self, secs: int = 0, nanos: int = 0) -> None: ...
def __eq__(self, other: object) -> bool: ...
def __ne__(self, other: object) -> bool: ...
def __lt__(self, other: Duration) -> bool: ...
def __le__(self, other: Duration) -> bool: ...
def __gt__(self, other: Duration) -> bool: ...
def __ge__(self, other: Duration) -> bool: ...
def __hash__(self) -> int: ...
def __richcmp__(
self, other: Duration | pydt.timedelta, op: int
) -> bool: ...
def __str__(self) -> str: ...
def abs_diff(self, other: Duration) -> Duration: ...
def sleep(self) -> None: ...
# =========================================================================
# PYTHON_CONVERSIONS
# =========================================================================
@classmethod
def from_pytimedelta(
cls: type[Duration], td: pydt.timedelta
) -> Duration: ...
def to_pytimedelta(self) -> pydt.timedelta: ...
# =========================================================================
# PROPERTIES
# =========================================================================
@property
def is_zero(self) -> bool: ...
@property
def nanos(self) -> int: ...
@property
def secs(self) -> int: ...
@property
def days(self) -> int: ...
@property
def seconds(self) -> int: ...
@property
def microseconds(self) -> int: ...
@property
def subsec_micros(self) -> int: ...
@property
def subsec_millis(self) -> int: ...
@property
def subsec_nanos(self) -> int: ...
# =========================================================================
# CLASSMETHODS
# =========================================================================
@classmethod
def from_hours(cls, hours: int) -> Duration: ...
@classmethod
def from_micros(cls, micros: int) -> Duration: ...
@classmethod
def from_millis(cls, millis: int) -> Duration: ...
@classmethod
def from_mins(cls, mins: int) -> Duration: ...
@classmethod
def from_nanos(cls, nanos: int) -> Duration: ...
@classmethod
def from_secs(cls, secs: int) -> Duration: ...
@classmethod
def from_secs_f32(cls, secs: float) -> Duration: ...
@classmethod
def from_secs_f64(cls, secs: float) -> Duration: ...
@classmethod
def from_days(cls, days: int) -> Duration: ...
@classmethod
def from_weeks(cls, weeks: int) -> Duration: ...
def as_micros(self) -> int: ...
def as_millis(self) -> int: ...
def as_nanos(self) -> int: ...
def as_secs(self) -> int: ...
def as_secs_f32(self) -> float: ...
def as_secs_f64(self) -> float: ...
# =========================================================================
# NOT IMPLEMENTED
# =========================================================================
def checked_add(self, other: Duration) -> Duration | None: ...
def checked_div(self, other: Duration) -> Duration | None: ...
def checked_mul(self, other: Duration) -> Duration | None: ...
def checked_sub(self, other: Duration) -> Duration | None: ...
def div_duration_f32(self, other: Duration) -> float: ...
def div_duration_f64(self, other: Duration) -> float: ...
def div_f32(self, other: float) -> Duration: ...
def div_f64(self, other: float) -> Duration: ...
def mul_f32(self, other: float) -> Duration: ...
def mul_f64(self, other: float) -> Duration: ...
def saturating_add(self, other: Duration) -> Duration: ...
def saturating_mul(self, other: Duration) -> Duration: ...
def saturating_sub(self, other: Duration) -> Duration: ...
class Instant:
def __init__(self) -> None: ...
@classmethod
def now(cls) -> Instant: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def __eq__(self, other: object) -> bool: ...
def __ne__(self, other: object) -> bool: ...
def __lt__(self, other: Instant) -> bool: ...
def __le__(self, other: Instant) -> bool: ...
def __gt__(self, other: Instant) -> bool: ...
def __ge__(self, other: Instant) -> bool: ...
def __hash__(self) -> int: ...
def __add__(self, other: Duration) -> Instant: ...
@t.overload
def __sub__(self, other: Duration) -> Instant: ...
@t.overload
def __sub__(self, other: Instant) -> Duration: ...
# =========================================================================
# INSTANCE METHODS
# =========================================================================
def checked_add(self, other: Duration) -> Instant | None: ...
def checked_duration_since(self, earlier: Instant) -> Duration | None: ...
def checked_sub(self, other: Duration) -> Instant | None: ...
def duration_since(self, earlier: Instant) -> Duration: ...
def elapsed(self) -> Duration: ...
def saturating_duration_since(self, earlier: Instant) -> Duration: ...
def instant() -> Instant: ...
def sleep(seconds: float) -> float: ...
# =============================================================================
# STD::FS
# =============================================================================
class FileType:
def __repr__(self) -> str: ...
@property
def is_dir(self) -> bool: ...
@property
def is_file(self) -> bool: ...
@property
def is_symlink(self) -> bool: ...
class Metadata:
def __repr__(self) -> str: ...
@property
def file_type(self) -> FileType: ...
@property
def len(self) -> int: ...
@property
def is_empty(self) -> bool: ...
@property
def modified(self) -> pydt.datetime: ...
@property
def accessed(self) -> pydt.datetime: ...
@property
def created(self) -> pydt.datetime: ...
@property
def is_dir(self) -> bool: ...
@property
def is_file(self) -> bool: ...
@property
def is_symlink(self) -> bool: ...
# =============================================================================
# STD::FS ~ functions
# =============================================================================
def read(path: FsPathLike) -> Bytes: ...
def read_bytes(path: FsPathLike) -> bytes: ...
def read_text(path: FsPathLike) -> str: ...
def read_stream(
path: FsPathLike,
chunk_size: int = 65536,
*,
offset: int = 0,
) -> t.Iterator[Bytes]: ...
def write(path: FsPathLike, data: Buffer | str) -> int: ...
def write_bytes(path: FsPathLike, data: bytes) -> int: ...
def write_text(path: FsPathLike, data: str) -> int: ...
def canonicalize(path: FsPathLike) -> FsPath: ...
def copy(from_path: FsPathLike, to_path: FsPathLike) -> int: ...
def create_dir(path: FsPathLike) -> None: ...
def create_dir_all(path: FsPathLike) -> None: ...
def exists(path: FsPathLike) -> bool: ...
def is_dir(path: FsPathLike) -> bool: ...
def is_file(path: FsPathLike) -> bool: ...
def is_symlink(path: FsPathLike) -> bool: ...
def metadata(path: FsPathLike) -> Metadata: ...
def remove_dir(path: FsPathLike) -> None: ...
def remove_dir_all(path: FsPathLike) -> None: ...
def remove_file(path: FsPathLike) -> None: ...
def rename(from_path: FsPathLike, to_path: FsPathLike) -> None: ...
ry.ryo3._tokio
"""ryo3-tokio types"""
from __future__ import annotations
from typing import NoReturn
from ry import Bytes
from ry._types import Buffer, FsPathLike
# =============================================================================
# FS
# =============================================================================
async def copy_async(src: FsPathLike, dst: FsPathLike) -> None: ...
async def create_dir_async(path: FsPathLike) -> None: ...
async def metadata_async(path: FsPathLike) -> None: ...
async def read_async(path: FsPathLike) -> Bytes: ...
async def read_dir_async(path: FsPathLike) -> NoReturn: ...
async def remove_dir_async(path: FsPathLike) -> None: ...
async def remove_file_async(path: FsPathLike) -> None: ...
async def rename_async(src: FsPathLike, dst: FsPathLike) -> None: ...
async def write_async(path: FsPathLike, data: Buffer) -> None: ...
# =============================================================================
# SLEEP
# =============================================================================
async def sleep_async(seconds: float) -> float: ...
async def asleep(seconds: float) -> float:
"""Alias for sleep_async"""
...
ry.ryo3._unindent
"""ryo3-unindent types"""
from __future__ import annotations
def unindent(string: str) -> str: ...
def unindent_bytes(string: bytes) -> bytes: ...
ry.ryo3._url
from __future__ import annotations
from ipaddress import IPv4Address
class URL:
def __init__(
self, url: str | URL, *, params: dict[str, str] | None = None
) -> None: ...
# =========================================================================
# CLASSMETHODS
# =========================================================================
@classmethod
def parse(cls, url: str) -> URL: ...
@classmethod
def parse_with_params(cls, url: str, params: dict[str, str]) -> URL: ...
@classmethod
def from_directory_path(cls, path: str) -> URL: ...
# =========================================================================
# STRING
# =========================================================================
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def __fspath__(self) -> str: ...
# =========================================================================
# OPERATORS/DUNDER
# =========================================================================
def __eq__(self, other: object) -> bool: ...
def __ge__(self, other: URL) -> bool: ...
def __gt__(self, other: URL) -> bool: ...
def __hash__(self) -> int: ...
def __le__(self, other: URL) -> bool: ...
def __lt__(self, other: URL) -> bool: ...
def __ne__(self, other: object) -> bool: ...
def __rtruediv__(self, relative: str) -> URL: ...
def __truediv__(self, relative: str) -> URL: ...
# =========================================================================
# PROPERTIES
# =========================================================================
@property
def authority(self) -> str: ...
@property
def fragment(self) -> str | None: ...
@property
def host(self) -> str | None: ...
@property
def host_str(self) -> str | None: ...
@property
def netloc(self) -> str: ...
@property
def password(self) -> str | None: ...
@property
def path(self) -> str: ...
@property
def path_segments(self) -> tuple[str, ...]: ...
@property
def port(self) -> int | None: ...
@property
def port_or_known_default(self) -> int | None: ...
@property
def query(self) -> str | None: ...
@property
def query_pairs(self) -> list[tuple[str, str]]: ...
@property
def scheme(self) -> str: ...
@property
def username(self) -> str: ...
@property
def origin(self) -> str: ...
# =========================================================================
# INSTANCE METHODS
# =========================================================================
def has_authority(self) -> bool: ...
def has_host(self) -> bool: ...
def is_special(self) -> bool: ...
def join(self, *parts: str) -> URL: ...
def to_filepath(self) -> str: ...
def replace_fragment(self, fragment: str | None = None) -> URL: ...
def replace_host(self, host: str | None = None) -> URL: ...
def replace_ip_host(self, host: IPv4Address | IPv4Address) -> URL: ...
def replace_password(self, password: str | None = None) -> URL: ...
def replace_path(self, path: str) -> URL: ...
def replace_port(self, port: int | None = None) -> URL: ...
def replace_query(self, query: str | None = None) -> URL: ...
def replace_scheme(self, scheme: str) -> URL: ...
def replace_username(self, username: str) -> URL: ...
def socket_addrs(self) -> None: ...
def replace(
self,
*,
fragment: str | None = None,
host: str | None = None,
ip_host: IPv4Address | None = None,
password: str | None = None,
path: str | None = None,
port: int | None = None,
query: str | None = None,
scheme: str | None = None,
username: str | None = None,
) -> URL: ...
ry.ryo3._walkdir
"""ryo3-walkdir types"""
from __future__ import annotations
import typing as t
from os import PathLike
from ry import FileType, FsPath, Glob, GlobSet, Globster
class WalkDirEntry:
def __fspath__(self) -> str: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
@property
def path(self) -> FsPath: ...
@property
def file_name(self) -> str: ...
@property
def depth(self) -> int: ...
@property
def path_is_symlink(self) -> bool: ...
@property
def file_type(self) -> FileType: ...
@property
def is_dir(self) -> bool: ...
@property
def is_file(self) -> bool: ...
@property
def is_symlink(self) -> bool: ...
@property
def len(self) -> int: ...
class WalkdirGen:
"""walkdir::Walkdir iterable wrapper"""
def __next__(self) -> str: ...
def __iter__(self) -> t.Iterator[str]: ...
def collect(self) -> list[str]: ...
def take(self, n: int) -> list[str]: ...
def __str__(self) -> str: ...
def walkdir(
path: str | PathLike[str] | None = None,
*,
files: bool = True,
dirs: bool = True,
contents_first: bool = False,
min_depth: int = 0,
max_depth: int | None = None,
follow_links: bool = False,
same_file_system: bool = False,
glob: Glob | GlobSet | Globster | t.Sequence[str] | str | None = None,
) -> WalkdirGen: ...
ry.ryo3._which
"""ryo3-which types"""
from __future__ import annotations
from pathlib import Path
from ry.ryo3._regex import Regex
def which(cmd: str, path: None | str = None) -> Path | None: ...
def which_all(cmd: str, path: None | str = None) -> list[Path]: ...
def which_re(regex: str | Regex, path: None | str = None) -> list[Path]: ...
ry.dirs
def audio() -> str | None: ...
def audio_dir() -> str | None: ...
def cache() -> str | None: ...
def cache_dir() -> str | None: ...
def config() -> str | None: ...
def config_dir() -> str | None: ...
def config_local() -> str | None: ...
def config_local_dir() -> str | None: ...
def data() -> str | None: ...
def data_dir() -> str | None: ...
def data_local() -> str | None: ...
def data_local_dir() -> str | None: ...
def desktop() -> str | None: ...
def desktop_dir() -> str | None: ...
def document() -> str | None: ...
def document_dir() -> str | None: ...
def download() -> str | None: ...
def download_dir() -> str | None: ...
def executable() -> str | None: ...
def executable_dir() -> str | None: ...
def font() -> str | None: ...
def font_dir() -> str | None: ...
def home() -> str | None: ...
def home_dir() -> str | None: ...
def picture() -> str | None: ...
def picture_dir() -> str | None: ...
def preference() -> str | None: ...
def preference_dir() -> str | None: ...
def public() -> str | None: ...
def public_dir() -> str | None: ...
def runtime() -> str | None: ...
def runtime_dir() -> str | None: ...
def state() -> str | None: ...
def state_dir() -> str | None: ...
def template() -> str | None: ...
def template_dir() -> str | None: ...
def video() -> str | None: ...
def video_dir() -> str | None: ...
ry.http
from __future__ import annotations
import typing as t
class Headers:
"""python-ryo3-http `http::HeadersMap` wrapper"""
def __init__(self, headers: dict[str, str | t.Sequence[str]]) -> None: ...
# =========================================================================
# STRING
# =========================================================================
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def __dbg__(self) -> str: ...
# =========================================================================
# MAGIC METHODS
# =========================================================================
def __len__(self) -> int: ...
def __getitem__(self, key: str) -> str: ...
def __setitem__(self, key: str, value: str) -> None: ...
def __delitem__(self, key: str) -> None: ...
def __contains__(self, key: str) -> bool: ...
def __or__(self, other: Headers | dict[str, str]) -> Headers: ...
def asdict(self) -> dict[str, str | t.Sequence[str]]: ...
# =========================================================================
# INSTANCE METHODS
# =========================================================================
def append(self, key: str, value: str) -> None: ...
def get(self, key: str) -> str | None: ...
def get_all(self, key: str) -> list[str]: ...
def keys_len(self) -> int: ...
def len(self) -> int: ...
def remove(self, key: str) -> None: ...
def clear(self) -> None: ...
def pop(self, key: str) -> str: ...
def keys(self) -> list[str]: ...
def update(self, headers: Headers | dict[str, str]) -> None: ...
class HttpStatus:
def __init__(self, code: int) -> None: ...
def __int__(self) -> int: ...
def __bool__(self) -> bool: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def __hash__(self) -> int: ...
def __eq__(self, other: object) -> bool: ...
def __ne__(self, other: object) -> bool: ...
def __lt__(self, other: HttpStatus | int) -> bool: ...
def __le__(self, other: HttpStatus | int) -> bool: ...
def __gt__(self, other: HttpStatus | int) -> bool: ...
def __ge__(self, other: HttpStatus | int) -> bool: ...
def reason(self) -> str: ...
def is_informational(self) -> bool: ...
def is_success(self) -> bool: ...
def is_redirect(self) -> bool: ...
def is_client_error(self) -> bool: ...
def is_server_error(self) -> bool: ...
def is_ok(self) -> bool: ...
@property
def ok(self) -> bool: ...
# =========================================================================
# CONST STATUS CODES
# =========================================================================
CONTINUE: HttpStatus # 100 ~ Continue
SWITCHING_PROTOCOLS: HttpStatus # 101 ~ Switching Protocols
PROCESSING: HttpStatus # 102 ~ Processing
OK: HttpStatus # 200 ~ OK
CREATED: HttpStatus # 201 ~ Created
ACCEPTED: HttpStatus # 202 ~ Accepted
NON_AUTHORITATIVE_INFORMATION: (
HttpStatus # 203 ~ Non Authoritative Information
)
NO_CONTENT: HttpStatus # 204 ~ No Content
RESET_CONTENT: HttpStatus # 205 ~ Reset Content
PARTIAL_CONTENT: HttpStatus # 206 ~ Partial Content
MULTI_STATUS: HttpStatus # 207 ~ Multi-Status
ALREADY_REPORTED: HttpStatus # 208 ~ Already Reported
IM_USED: HttpStatus # 226 ~ IM Used
MULTIPLE_CHOICES: HttpStatus # 300 ~ Multiple Choices
MOVED_PERMANENTLY: HttpStatus # 301 ~ Moved Permanently
FOUND: HttpStatus # 302 ~ Found
SEE_OTHER: HttpStatus # 303 ~ See Other
NOT_MODIFIED: HttpStatus # 304 ~ Not Modified
USE_PROXY: HttpStatus # 305 ~ Use Proxy
TEMPORARY_REDIRECT: HttpStatus # 307 ~ Temporary Redirect
PERMANENT_REDIRECT: HttpStatus # 308 ~ Permanent Redirect
BAD_REQUEST: HttpStatus # 400 ~ Bad Request
UNAUTHORIZED: HttpStatus # 401 ~ Unauthorized
PAYMENT_REQUIRED: HttpStatus # 402 ~ Payment Required
FORBIDDEN: HttpStatus # 403 ~ Forbidden
NOT_FOUND: HttpStatus # 404 ~ Not Found
METHOD_NOT_ALLOWED: HttpStatus # 405 ~ Method Not Allowed
NOT_ACCEPTABLE: HttpStatus # 406 ~ Not Acceptable
PROXY_AUTHENTICATION_REQUIRED: (
HttpStatus # 407 ~ Proxy Authentication Required
)
REQUEST_TIMEOUT: HttpStatus # 408 ~ Request Timeout
CONFLICT: HttpStatus # 409 ~ Conflict
GONE: HttpStatus # 410 ~ Gone
LENGTH_REQUIRED: HttpStatus # 411 ~ Length Required
PRECONDITION_FAILED: HttpStatus # 412 ~ Precondition Failed
PAYLOAD_TOO_LARGE: HttpStatus # 413 ~ Payload Too Large
URI_TOO_LONG: HttpStatus # 414 ~ URI Too Long
UNSUPPORTED_MEDIA_TYPE: HttpStatus # 415 ~ Unsupported Media Type
RANGE_NOT_SATISFIABLE: HttpStatus # 416 ~ Range Not Satisfiable
EXPECTATION_FAILED: HttpStatus # 417 ~ Expectation Failed
IM_A_TEAPOT: HttpStatus # 418 ~ I'm a teapot
MISDIRECTED_REQUEST: HttpStatus # 421 ~ Misdirected Request
UNPROCESSABLE_ENTITY: HttpStatus # 422 ~ Unprocessable Entity
LOCKED: HttpStatus # 423 ~ Locked
FAILED_DEPENDENCY: HttpStatus # 424 ~ Failed Dependency
TOO_EARLY: HttpStatus # 425 ~ Too Early
UPGRADE_REQUIRED: HttpStatus # 426 ~ Upgrade Required
PRECONDITION_REQUIRED: HttpStatus # 428 ~ Precondition Required
TOO_MANY_REQUESTS: HttpStatus # 429 ~ Too Many Requests
REQUEST_HEADER_FIELDS_TOO_LARGE: (
HttpStatus # 431 ~ Request Header Fields Too Large
)
UNAVAILABLE_FOR_LEGAL_REASONS: (
HttpStatus # 451 ~ Unavailable For Legal Reasons
)
INTERNAL_SERVER_ERROR: HttpStatus # 500 ~ Internal Server Error
NOT_IMPLEMENTED: HttpStatus # 501 ~ Not Implemented
BAD_GATEWAY: HttpStatus # 502 ~ Bad Gateway
SERVICE_UNAVAILABLE: HttpStatus # 503 ~ Service Unavailable
GATEWAY_TIMEOUT: HttpStatus # 504 ~ Gateway Timeout
HTTP_VERSION_NOT_SUPPORTED: HttpStatus # 505 ~ HTTP Version Not Supported
VARIANT_ALSO_NEGOTIATES: HttpStatus # 506 ~ Variant Also Negotiates
INSUFFICIENT_STORAGE: HttpStatus # 507 ~ Insufficient Storage
LOOP_DETECTED: HttpStatus # 508 ~ Loop Detected
NOT_EXTENDED: HttpStatus # 510 ~ Not Extended
NETWORK_AUTHENTICATION_REQUIRED: (
HttpStatus # 511 ~ Network Authentication Required
)
ry.xxhash
from __future__ import annotations
import typing as t
from ry._types import Buffer
@t.final
class Xxh32:
name: t.Literal["xxh32"]
def __init__(self, input: Buffer = ..., seed: int | None = ...) -> None: ...
def update(self, input: Buffer) -> None: ...
def digest(self) -> bytes: ...
def hexdigest(self) -> str: ...
def intdigest(self) -> int: ...
def copy(self) -> Xxh32: ...
def reset(self, seed: int | None = ...) -> None: ...
@property
def seed(self) -> int: ...
@t.final
class Xxh64:
name: t.Literal["xxh64"]
def __init__(
self, input: Buffer | None = None, seed: int | None = ...
) -> None: ...
def update(self, input: Buffer) -> None: ...
def digest(self) -> bytes: ...
def hexdigest(self) -> str: ...
def intdigest(self) -> int: ...
def copy(self) -> Xxh32: ...
def reset(self, seed: int | None = ...) -> None: ...
@property
def seed(self) -> int: ...
@t.final
class Xxh3:
name: t.Literal["xxh3"]
def __init__(
self,
input: Buffer = ...,
seed: int | None = ...,
secret: bytes | None = ...,
) -> None: ...
def update(self, input: Buffer) -> None: ...
def digest(self) -> bytes: ...
def hexdigest(self) -> str: ...
def intdigest(self) -> int: ...
@property
def seed(self) -> int: ...
def digest128(self) -> bytes: ...
def hexdigest128(self) -> str: ...
def intdigest128(self) -> int: ...
def copy(self) -> Xxh3: ...
def reset(self) -> None: ...
def xxh32(input: Buffer | None = None, seed: int | None = None) -> Xxh32: ...
def xxh64(input: Buffer | None = None, seed: int | None = None) -> Xxh64: ...
def xxh3(
input: Buffer | None = None,
seed: int | None = None,
secret: bytes | None = None,
) -> Xxh3: ...
# xxh32
def xxh32_digest(input: Buffer, seed: int | None = None) -> bytes: ...
def xxh32_hexdigest(input: Buffer, seed: int | None = None) -> str: ...
def xxh32_intdigest(input: Buffer, seed: int | None = None) -> int: ...
# xxh64
def xxh64_digest(input: Buffer, seed: int | None = None) -> bytes: ...
def xxh64_hexdigest(input: Buffer, seed: int | None = None) -> str: ...
def xxh64_intdigest(input: Buffer, seed: int | None = None) -> int: ...
# xxh128
def xxh128_digest(input: Buffer, seed: int | None = None) -> bytes: ...
def xxh128_hexdigest(input: Buffer, seed: int | None = None) -> str: ...
def xxh128_intdigest(input: Buffer, seed: int | None = None) -> int: ...
# xxh3
def xxh3_64_digest(input: Buffer, seed: int | None = None) -> bytes: ...
def xxh3_64_intdigest(input: Buffer, seed: int | None = None) -> int: ...
def xxh3_64_hexdigest(input: Buffer, seed: int | None = None) -> str: ...
def xxh3_digest(input: Buffer, seed: int | None = None) -> bytes: ...
def xxh3_intdigest(input: Buffer, seed: int | None = None) -> int: ...
def xxh3_hexdigest(input: Buffer, seed: int | None = None) -> str: ...
# xxh128
def xxh3_128_digest(input: Buffer, seed: int | None = None) -> bytes: ...
def xxh3_128_intdigest(input: Buffer, seed: int | None = None) -> int: ...
def xxh3_128_hexdigest(input: Buffer, seed: int | None = None) -> str: ...
ry.zstd
from ry import Bytes
from ry._types import Buffer
__zstd_version__: str # zstd version string ("1.5.7" as of 2025-03-14)
BLOCKSIZELOG_MAX: int
BLOCKSIZE_MAX: int
CLEVEL_DEFAULT: int # default=3 (as of 2025-03-14)
CONTENTSIZE_ERROR: int
CONTENTSIZE_UNKNOWN: int
MAGICNUMBER: int
MAGIC_DICTIONARY: int
MAGIC_SKIPPABLE_MASK: int
MAGIC_SKIPPABLE_START: int
VERSION_MAJOR: int
VERSION_MINOR: int
VERSION_NUMBER: int
VERSION_RELEASE: int
# =============================================================================
# PYFUNCTIONS
# =============================================================================
# __COMPRESSION__
def compress(data: Buffer, level: int = CLEVEL_DEFAULT) -> Bytes: ...
def encode(data: Buffer, level: int = CLEVEL_DEFAULT) -> Bytes: ...
def zstd(data: Buffer, level: int = CLEVEL_DEFAULT) -> Bytes: ...
def zstd_compress(data: Buffer, level: int = CLEVEL_DEFAULT) -> Bytes: ...
def zstd_encode(data: Buffer, level: int = CLEVEL_DEFAULT) -> Bytes: ...
# __DECOMPRESSION__
def decode(data: Buffer) -> Bytes: ...
def decompress(data: Buffer) -> Bytes: ...
def unzstd(data: Buffer) -> Bytes: ...
def zstd_decode(data: Buffer) -> Bytes: ...
def zstd_decompress(data: Buffer) -> Bytes: ...
# __MAGIC__
def is_zstd(data: Buffer) -> bool: ...
DEV
just
is used to run tasks- Do not use the phrase
blazing fast
or any emojis in any PRs or issues or docs - type annotations are required
ruff
used for formatting and linting
SEE ALSO
- utiles (web-map tile utils): https://github.com/jessekrubin/utiles
- jsonc2json (jsonc to json converter): https://github.com/jessekrubin/jsonc2json
DEVELOPMENT
OPEN TO PRS!
goals
- Provide a really nice ergonomic API to work with (this is the highest priority)
- Get naming right (this is a hard one!)
- Be fast
development-setup
- clone repo
- install
just
(cargo install just
) - create a virtual env (using ye olde
venv
oruv
or dare I sayconda
) – I am still working out the kinks of usinguv
with maturin - install the dev-requirements (
pip install -r requirements.dev.txt
) - run
just dev
to build and test the library - run
just fmt
to format the python and rust code
style guide
- NO UNWRAPPING
- NO PANICS
- NO
blazingly-fast
–ry
is fast and does not need an adverb - USE CLIPPY
just clippy
orjust ci
- USE RUSTFMT AND RUFF
just fmt
- avoid using macros as they are not as easy to reason about and/or debug, but feel free to say ‘yolo’
- library style guide:
- python objects/structs/classes defined in the library should be named either
Py<CLASSNAME>
orRy<CLASSNAME>
and the prefix should be consistent throughout the library (egryo3-jiff
usesRy
as the internal prefix to not conflict with thePy<CLASSNAME>
structs provided bypyo3
) - if a
pyclass
orpyfunction
is not mirroring a rust function prefer names that are puns but also semi-descriptive (egGlobsters
inryo3-globset
) - attempt to mirror the structure of the og library as much as possible
- wrapper libraries should be of the form
ryo3-<LIB_NAME>
where<LIB_NAME>
is the name of the library they - library directories should be
kebab-case
and should beryo3-<LIB_NAME>
- MUST PROVIDE TYPE ANNOTATIONS
- python objects/structs/classes defined in the library should be named either
Creating a new library/wrapper-thing
- copy the template library
ryo3-quick-maths
library to your new library name - refer to the above style guide for naming conventions
tools
python
- we use
maturin
for building the python wheels - we support
python-3.9+
- we use
pytest
for testing as well as the following plugins:pytest-benchmark
pytest-asyncio
(may switch toanyio
in the future)hypothesis
just
cargo install just
- we use
just
for task running - to see all tasks run
just
orjust --list
(our default task echos the list of tasks)
tasks as of 2024-12-03:
Available recipes:
dev # dev run build + tests
develop # maturin develop
cargo-test # cargo test
build # build
build-release # build release
dev-rel # maturin develop release
pytest # run pytest
pytestv # run pytest (printing captured output)
test # run all test
test-release # test ry package
bench # benchmark ry python package
ci # ci rust checks
cargo-fmt # cargo format
cargo-fmtc # cargo format check
sort-all-check # ruff check sorting of '__all__'
sort-all # ruff sort '__all__'
ruff-fmt # ruff format
ruff-fmtc # ruff format check
black # python format black
fmtpy # python format
fmtcpy # python format check
justfilefmt # justfile format
justfilefmtc # justfile format check
fmt # format
fmtc # format check
ruff # run ruff linter
ruffix # run ruff + fix
clippy # run clippy
lint # lint python and rust
mypy # run mypy type checker
pyright # run pyright
pip-compile # pip compile requirements
gen # generate code tasks
ACKNOWLEDGEMENTS
This project would not be possible without the incredible work of many others.
THANK YOU
- pyo3 developers
- all authors of all libraries used in this project!
- burnt-sushi for the incredible set of libraries
- Kyle Barron for working on
pyo3-bytes
and letting me contribute to it - The academy and the hollywood foreign press
If you want to be added to this list, please open an issue or PR! Happy to add you if you’ve helped in any way!
CHANGELOG
v0.0.39 [2025-03-14]
- internal
- cleaned up several dependencies and features
ryo3-zstd
- actually changed to use py buffer protocol this time… I dont know how it got missed before…
- re-factored a decent bit and made submodule with future plans to expand encoding/decoding dictionary support
- submodule is
ry.zstd
and/orry.ryo3.zstd
v0.0.38 [2025-03-13]
ryo3-reqwest
- client configuration for pickling
- allow buffer-protocol for
body
fetching methods (should add string maybe?)
ryo3-walkdir
- Few more options added
ryo3-glob
- new wrapper around
glob
crate
- new wrapper around
ryo3-jiff
- Switched to use conversions from
jiff
feature ofpyo3-v24
as opposed to hand-rolled conversions we had before
- Switched to use conversions from
v0.0.37 [2025-03-11]
- pyo3 version
0.24.0
ryo3-which
functions returnpathlib.Path
now due to changes in pyo3-v24; this may change in the near future…
v0.0.36 [2025-03-11]
- dependencies updated
- pickling support and tests for several types
- bytes/buffer-protocol support for several sub-packages/packages:
ryo3-brotli
ryo3-bzip2
ryo3-flate2
ryo3-fnv
ryo3-xxhash
ryo3-zstd
v0.0.35 [2025-03-06]
- internal
- types split up and cleaned up
ryo3-size
ry.Size
object
ryo3-jiff
series
iterators havetake
function that takes ausize
returns a list of sizeusize
- updated series types to be
JiffSeries
class
v0.0.34 [2025-02-28]
ryo3-std
fs
:read_stream
function that returns an iterator ofry.Bytes
objects from aPathLike
object- Several more fs functions added
ryo3-tokio
- Several more tokio fs functions added
- internal
- reorganized type annotations to be not a HUGE file…
v0.0.33 [2025-02-26]
- update to pyo3 v0.23.5
v0.0.32 [2025-02-25]
ryo3-jiter
- Allow
PyBytes
wrapper/buffer protocol to be given - renamed
jiter_cache_clear
tojson_cache_clear
andjiter_cache_usage
tojson_cache_usage
- Removed
parse_json_str
just useparse_json
withstr
input
- Allow
ryo3-fspath
- Allow read/write to take
ry.Bytes
orBytes
objects
- Allow read/write to take
v0.0.31 [2025-02-21]
ryo3-core
- got rid of
ryo3-types
and moved intoryo3-core
- got rid of
ryo3-tokio
read_async
andwrite_async
async functions
ryo3-which
which_re
functions acceptsry.Regex
orstr
now
ryo3-std
read
andwrite
functions which take/returnry.Bytes
objects
internal
- Changed many many many of the structs/classes to be pyo3
frozen
behaviour should not be different
- Changed many many many of the structs/classes to be pyo3
v0.0.30 [2025-02-18]
jiff
- Upgraded jiff to version 2
- internal
- Switch all lints from
#[allow(...)]
/#![allow(...)]
to#[expect(...)]
/#![expect(...)]
- Removed a bunch o commented out code
- Switch all lints from
ryo3-std
- added several
std::fs
structs
- added several
ryo3-fspath
- conversion to
pathlib.Path
by way ofFsPath.to_pathlib()
- conversion to
v0.0.29 [2025-02-03]
- internal
- Made sure each
ryo3-*
crate has aREADME.md
- Made sure each
ryo3-bytes
&ryo3-fspath
- added
__hash__
dunders to bothBytes
andFsPath
structs
- added
v0.0.28 [2025-01-31]
jiff
- Per Mr. Sushi’s thoughts changed all
until
/since
methods to use kwargs instead of the rust-like tuples that implFrom
/Into
as it does not translate well to python - Gets rid of the following inane types:
- Per Mr. Sushi’s thoughts changed all
IntoDateDifference = (
DateDifference
| Date
| DateTime
| ZonedDateTime
| tuple[JIFF_UNIT_STRING, Date]
| tuple[JIFF_UNIT_STRING, DateTime]
| tuple[JIFF_UNIT_STRING, ZonedDateTime]
)
IntoTimeDifference = (
TimeDifference
| Time
| DateTime
| ZonedDateTime
| tuple[JIFF_UNIT_STRING, Time]
| tuple[JIFF_UNIT_STRING, DateTime]
| tuple[JIFF_UNIT_STRING, ZonedDateTime]
)
IntoDateTimeDifference = (
DateTimeDifference
| Date
| Time
| DateTime
| ZonedDateTime
| tuple[JIFF_UNIT_STRING, Date]
| tuple[JIFF_UNIT_STRING, Time]
| tuple[JIFF_UNIT_STRING, DateTime]
| tuple[JIFF_UNIT_STRING, ZonedDateTime]
)
IntoTimestampDifference = (
TimestampDifference
| Timestamp
| ZonedDateTime
| tuple[JIFF_UNIT_STRING, Timestamp]
| tuple[JIFF_UNIT_STRING, ZonedDateTime]
)
v0.0.27 [2025-01-23]
ry
- Warning on
debug
build
- Warning on
reqwest
- headers-property response returns
Headers
object instead of python dict
- headers-property response returns
same-file
- wrapper module added with
is_same_file
py-fn (yet another piece of burnt sushi)
- wrapper module added with
jiff
- jiff-version
0.1.25
~ addin_tz
methods and point oldintz
at newin_tz
methods and raiseDeprecationWarning
for oldintz
methods - Continued adding implementations that previously raised
NotImplementedError
Date.nth_weekday_of_month
Date.nth_weekday
DateTime.nth_weekday_of_month
DateTime.nth_weekday
TimeSpan.compare
TimeSpan.total
ZonedDateTime.nth_weekday_of_month
ZonedDateTime.nth_weekday
- jiff-version
v0.0.26 [2025-01-13]
reqwest
AsyncClient
renamed toHttpClient
jiff
- human timespan strings for
TimeSpan
andSignedDuration
objects:ry.TimeSpan.parse("P2M10DT2H30M").string(human=True) == "2mo 10d 2h 30m"
ry.SignedDuration.parse("PT2H30M").string(human=True) == "2h 30m"
- human timespan strings for
- internal
- workspace-ified all the deps
v0.0.25 [2024-01-07] (25 for 2025)
jiff
- Updated to
0.1.21
which has span and signed duration strings with capital letters
- Updated to
v0.0.24 [2024-12-24] (the night b4 xmas…)
http
- basic headers struct/obj – WIP
reqwest
- reqwest client (currently root-export)
- default client + root
fetch
function likely needs work… - response
byte_stream
!
v0.0.23 [2024-12-19]
python -m ry.dev
repl for ipython/python repl ~ handy nifty secret tool makes it into repo- internal
- in process of renaming all python-rust
#[new]
functions to be namedfn py_new(...)
- in process of renaming all python-rust
unindent
- Added
unindent
module for unindenting strings will move toryo3-unindent
- Added
FsPath
- creeping ever closer to being a full-fledged pathlib.Path replacement
- Added bindings to all rust
std::path::Path(buf)
methods forFsPath
- sub-packaging
xxhash
is own sub package nowry.xxhash
JSON
is own subpackage right now – namedry.JSON
to avoid conflict withjson
module but maybe will change…- food-for-thought-ing how
ryo3
andry
should be organized w/ respsect to sub-packages and where that organization should be
- type-annotations
- required to break up the type annotations due to migration to sub-packages
- breaking up the type annotations file into smaller files under
<REPO>/python/ry/ryo3/*.pyi
v0.0.22 [2024-12-16]
regex
- Super simple regex wrapper (must to do here, but was added for
ryo3-which::which_re
)
- Super simple regex wrapper (must to do here, but was added for
jiff
until
/since
- Basic
until
/since
implementation but I do not like them and they confusingly named*Difference
structs/py-objects, so I may change how they work…
- Basic
jiff
seems to be about as performant aswhenever
~ yay! also the whenever dude appears to be watching this repo (as of 2024-12-16)
walkdir
collect
added toWalkdirGen
to collect the results into a list
- deps
thiserror
version2.0.7
->2.0.8
v0.0.21 [2024-12-13] (friday the 13th… spoogidy oogidity)
walkdir
- add
glob
kwarg that takes ary.Glob
orry.GlobSet
orry.Globster
obj to filter the walk on
- add
globset
- Internal refactoring
- added
globster()
method tory.Glob
andry.GlobSet
to return ary.Globster
obj - added
globset()
method tory.Glob
to return ary.GlobSet
obj from ary.Glob
obj
url
- python
Url
changed nameURL
; aligns with jawascript and other python libs
- python
bzip2
- update to v5
jiff
- conversions for jiff-round-mode/unit/weekday
- not-implemented placeholders and new impls
-
RyDateTime
-
RyDate
-
RyOffset
-
RySignedDuration
-
RySpan
-
RyTimeZone
-
RyTime
-
RyZoned
-
- span builder functions use form
s._hours(1)
for panic-inducing building, ands.try_hours(1)
for non-panic-inducing building
- type-annotations
- fixes and updates and a hacky script I wrote to check for discrepancies
v0.0.20 [2024-12-10]
regex
- Templated out regex package but nothing added
ry
- python 3.13 yay!
jiter
- Updated jiter version thanks depbot!
v0.0.19 [2024-12-05]
jiff
- py-conversions
-
JiffDateTime
- FromPyObject
- IntoPyObject
- IntoPyObject (REF)
-
JiffDate
- FromPyObject
- IntoPyObject
- IntoPyObject (REF)
-
JiffOffset
- FromPyObject
- IntoPyObject
- IntoPyObject (REF)
-
JiffSignedDuration
- FromPyObject
- IntoPyObject
- IntoPyObject (REF)
-
JiffSpan
- FromPyObject
- IntoPyObject
- IntoPyObject (REF)
-
JiffTimeZone
- FromPyObject
- IntoPyObject
- IntoPyObject (REF)
-
JiffTime
- FromPyObject
- IntoPyObject
- IntoPyObject (REF)
-
JiffZoned
- FromPyObject
- IntoPyObject
- IntoPyObject (REF)
-
- py-conversions
v0.0.18 [2024-12-03]
jiff
- Renamed
ry.Span
tory.TimeSpan
- Renamed
ry.Zoned
tory.ZonedDateTime
- Updated type stubs to reflect renames
- Renamed
- docs
- init-ed the docs
- style guide under
DEVELOPMENT.md
file
v0.0.17 [2024-12-02]
jiff
ry.TimeZone
testing and to/fromdatetime.tzinfo
conversions- Using nu-types for
jiff
intermediate types bc of the classic orphans problem (aka batman) w/ traits - hypothesis tests
jiter
- Updated to
jiter
v0.8.1
- Updated to
v0.0.16 [2024-11-29]
- Moved walkdir to
ryo3-walkdir
- added
ryo3-types
for custom and shared types heck
wrapper(s)- jiff
- Added operators
+
/+=
/-
/-=
to date/time/datetime/etc - TODO: figure out how to take refs in the union enum for the operators
- Added operators
- fspath
- further beefing out as well as testing
v0.0.15 [2024-11-20]
from __future__ import annotations
added to all modules- cicd updated to include more targets
v0.0.14 [2024-11-20]
- Primitive/crude wrappers around Mr. Sushi’s
jiff
library - Updated to use pyo3 (had to use jiter git repo dep)
ry.FsPath
beefed out- Added iterdir gen wrapper
- (todo undo when jiter + pyo3 23 is public)
v0.0.13 [2024-11-20]
- VERSION SKIPPED DUE TO
13
BEING SPOOKY AND ME BEING MODERATELY-STITCHOUS (AKA fully ‘superstitchous’)
v0.0.12 [2024-11-14]
- sqlformat wrapper(s) (this is the first
ryo3-*
sub-crate)
v0.0.11 [2024-09-22]
- dependencies updated
- prepare for python 3.13
v0.0.10 [2024-09-22]
- dependencies updated
v0.0.9 [2024-08-22]
- Added
globset
wrapper(s) - Added
__init__.py
generator
- Upgraded to pyo3-v0.22
v0.0.8 [2024-06-25]
- Upgraded to pyo3-v0.22
v0.0.7 [2024-06-08]
- internal refactoring
v0.0.6 [2024-06-05]
- Added zstd (
zstd_encode
/zstd
andzstd_decode
) - Added gzip (
gzip_encode
/gzip
andgzip_decode
/gunzip
) - Added bzip2 (
bzip2_encode
/bzip2
andbzip2_decode
) - Added walkdir
- Reorg libs
v0.0.5 [2024-04-19]
- Added brotli (
brotli_encode
andbrotli_decode
) - xxhash
- const functions
- hasher streaming objects
Examples
TODO: Add examples
API
API
Table of Contents
ry.ryo3.__init__
ry.ryo3.errors
ry.ryo3.JSON
ry.ryo3._brotli
ry.ryo3._bytes
ry.ryo3._bzip2
ry.ryo3._dev
ry.ryo3._flate2
ry.ryo3._fnv
ry.ryo3._fspath
ry.ryo3._glob
ry.ryo3._globset
ry.ryo3._heck
ry.ryo3._jiff
ry.ryo3._jiter
ry.ryo3._quick_maths
ry.ryo3._regex
ry.ryo3._reqwest
ry.ryo3._same_file
ry.ryo3._shlex
ry.ryo3._size
ry.ryo3._sqlformat
ry.ryo3._std
ry.ryo3._tokio
ry.ryo3._unindent
ry.ryo3._url
ry.ryo3._walkdir
ry.ryo3._which
ry.dirs
ry.http
ry.xxhash
ry.zstd
ry.ryo3.__init__
"""ry api ~ type annotations"""
from __future__ import annotations
import datetime as pydt
import typing as t
from os import PathLike
from ry import dirs as dirs # noqa: RUF100
from ry import http as http # noqa: RUF100
from ry import xxhash as xxhash # noqa: RUF100
from ry import zstd as zstd # noqa: RUF100
from ry._types import Buffer as Buffer # noqa: RUF100
from ry.http import Headers as Headers # noqa: RUF100
from ry.http import HttpStatus as HttpStatus # noqa: RUF100
from ry.zstd import is_zstd as is_zstd
from ry.zstd import zstd_compress as zstd_compress
from ry.zstd import zstd_decode as zstd_decode
from ry.zstd import zstd_decompress as zstd_decompress
from ry.zstd import zstd_encode as zstd_encode
from ._brotli import brotli as brotli
from ._brotli import brotli_decode as brotli_decode
from ._brotli import brotli_encode as brotli_encode
from ._bytes import Bytes as Bytes
from ._bzip2 import bzip2 as bzip2
from ._bzip2 import bzip2_decode as bzip2_decode
from ._bzip2 import bzip2_encode as bzip2_encode
from ._flate2 import gunzip as gunzip
from ._flate2 import gzip as gzip
from ._flate2 import gzip_decode as gzip_decode
from ._flate2 import gzip_encode as gzip_encode
from ._flate2 import is_gzipped as is_gzipped
from ._fnv import FnvHasher as FnvHasher
from ._fnv import fnv1a as fnv1a
from ._fspath import FsPath as FsPath
from ._glob import Pattern as Pattern
from ._glob import glob as glob
from ._globset import Glob as Glob
from ._globset import GlobSet as GlobSet
from ._globset import Globster as Globster
from ._globset import globster as globster
from ._heck import camel_case as camel_case
from ._heck import kebab_case as kebab_case
from ._heck import pascal_case as pascal_case
from ._heck import shouty_kebab_case as shouty_kebab_case
from ._heck import shouty_snake_case as shouty_snake_case
from ._heck import snake_case as snake_case
from ._heck import snek_case as snek_case
from ._heck import title_case as title_case
from ._heck import train_case as train_case
from ._jiff import Date as Date
from ._jiff import DateDifference as DateDifference
from ._jiff import DateTime as DateTime
from ._jiff import DateTimeDifference as DateTimeDifference
from ._jiff import DateTimeRound as DateTimeRound
from ._jiff import ISOWeekDate as ISOWeekDate
from ._jiff import Offset as Offset
from ._jiff import SignedDuration as SignedDuration
from ._jiff import Time as Time
from ._jiff import TimeDifference as TimeDifference
from ._jiff import TimeSpan as TimeSpan
from ._jiff import Timestamp as Timestamp
from ._jiff import TimestampDifference as TimestampDifference
from ._jiff import TimestampRound as TimestampRound
from ._jiff import TimeZone as TimeZone
from ._jiff import TimeZoneDatabase as TimeZoneDatabase
from ._jiff import ZonedDateTime as ZonedDateTime
from ._jiff import ZonedDateTimeDifference as ZonedDateTimeDifference
from ._jiff import ZonedDateTimeRound as ZonedDateTimeRound
from ._jiff import date as date
from ._jiff import datetime as datetime
from ._jiff import offset as offset
from ._jiff import time as time
from ._jiff import timespan as timespan
from ._jiter import JsonParseKwargs as JsonParseKwargs
from ._jiter import JsonPrimitive as JsonPrimitive
from ._jiter import JsonValue as JsonValue
from ._jiter import json_cache_clear as json_cache_clear
from ._jiter import json_cache_usage as json_cache_usage
from ._jiter import parse_json as parse_json
from ._jiter import parse_json_bytes as parse_json_bytes
from ._quick_maths import quick_maths as quick_maths
from ._regex import Regex as Regex
from ._reqwest import HttpClient as HttpClient
from ._reqwest import ReqwestError as ReqwestError
from ._reqwest import Response as Response
from ._reqwest import ResponseStream as ResponseStream
from ._reqwest import fetch as fetch
from ._same_file import is_same_file as is_same_file
from ._shlex import shplit as shplit
from ._size import Size as Size
from ._size import SizeFormatter as SizeFormatter
from ._size import fmt_size as fmt_size
from ._size import parse_size as parse_size
from ._sqlformat import SqlfmtQueryParams as SqlfmtQueryParams
from ._sqlformat import sqlfmt as sqlfmt
from ._sqlformat import sqlfmt_params as sqlfmt_params
from ._std import Duration as Duration
from ._std import FileType as FileType
from ._std import Instant as Instant
from ._std import Metadata as Metadata
from ._std import canonicalize as canonicalize
from ._std import copy as copy
from ._std import create_dir as create_dir
from ._std import create_dir_all as create_dir_all
from ._std import exists as exists
from ._std import instant as instant
from ._std import is_dir as is_dir
from ._std import is_file as is_file
from ._std import is_symlink as is_symlink
from ._std import metadata as metadata
from ._std import read as read
from ._std import read_bytes as read_bytes
from ._std import read_stream as read_stream
from ._std import read_text as read_text
from ._std import remove_dir as remove_dir
from ._std import remove_dir_all as remove_dir_all
from ._std import remove_file as remove_file
from ._std import rename as rename
from ._std import sleep as sleep
from ._std import write as write
from ._std import write_bytes as write_bytes
from ._std import write_text as write_text
from ._tokio import asleep as asleep
from ._tokio import copy_async as copy_async
from ._tokio import create_dir_async as create_dir_async
from ._tokio import metadata_async as metadata_async
from ._tokio import read_async as read_async
from ._tokio import read_dir_async as read_dir_async
from ._tokio import remove_dir_async as remove_dir_async
from ._tokio import remove_file_async as remove_file_async
from ._tokio import rename_async as rename_async
from ._tokio import sleep_async as sleep_async
from ._tokio import write_async as write_async
from ._unindent import unindent as unindent
from ._unindent import unindent_bytes as unindent_bytes
from ._url import URL as URL
from ._walkdir import WalkDirEntry as WalkDirEntry
from ._walkdir import WalkdirGen as WalkdirGen
from ._walkdir import walkdir as walkdir
from ._which import which as which
from ._which import which_all as which_all
from ._which import which_re as which_re
from .errors import FeatureNotEnabledError as FeatureNotEnabledError
# =============================================================================
# CONSTANTS
# =============================================================================
__version__: str
__authors__: str
__build_profile__: str
__build_timestamp__: str
__pkg_name__: str
__description__: str
# =============================================================================
# SH
# =============================================================================
def pwd() -> str: ...
def home() -> str: ...
def cd(path: str | PathLike[str]) -> None: ...
@t.overload
def ls(
path: str | PathLike[str] | None = None, # defaults to '.' if None
*,
absolute: bool = False,
sort: bool = False,
objects: t.Literal[False] = False,
) -> list[str]:
"""List directory contents - returns list of strings"""
@t.overload
def ls(
path: str | PathLike[str] | None = None, # defaults to '.' if None
*,
absolute: bool = False,
sort: bool = False,
objects: t.Literal[True] = True,
) -> list[FsPath]:
"""List directory contents - returns list of FsPath objects"""
ry.ryo3.errors
from __future__ import annotations
class FeatureNotEnabledError(RuntimeError):
"""Raised when a feature is not enabled in the current build."""
ry.ryo3.JSON
"""ry.ryo3.JSON"""
from typing import Literal
JsonPrimitive = None | bool | int | float | str
JsonValue = (
JsonPrimitive
| dict[str, JsonPrimitive | JsonValue]
| list[JsonPrimitive | JsonValue]
)
def parse_json(
data: bytes | str,
/,
*,
allow_inf_nan: bool = True,
cache_mode: Literal[True, False, "all", "keys", "none"] = "all",
partial_mode: Literal[True, False, "off", "on", "trailing-strings"] = False,
catch_duplicate_keys: bool = False,
float_mode: Literal["float", "decimal", "lossless-float"] | bool = False,
) -> JsonValue: ...
def parse_json_bytes(
data: bytes,
/,
*,
allow_inf_nan: bool = True,
cache_mode: Literal[True, False, "all", "keys", "none"] = "all",
partial_mode: Literal[True, False, "off", "on", "trailing-strings"] = False,
catch_duplicate_keys: bool = False,
float_mode: Literal["float", "decimal", "lossless-float"] | bool = False,
) -> JsonValue: ...
def json_cache_clear() -> None: ...
def json_cache_usage() -> int: ...
ry.ryo3._brotli
"""ryo3-brotli types"""
from __future__ import annotations
# =============================================================================
# BROTLI
# =============================================================================
def brotli_encode(
input: bytes, quality: int = 11, magic_number: bool = False
) -> bytes: ...
def brotli_decode(input: bytes) -> bytes: ...
def brotli(
input: bytes, quality: int = 11, magic_number: bool = False
) -> bytes:
"""Alias for brotli_encode"""
ry.ryo3._bytes
import sys
from typing import overload
if sys.version_info >= (3, 12):
from collections.abc import Buffer as Buffer
else:
from typing_extensions import Buffer as Buffer
class Bytes(Buffer):
"""
A buffer implementing the Python buffer protocol, allowing zero-copy access
to underlying Rust memory.
You can pass this to `memoryview` for a zero-copy view into the underlying
data or to `bytes` to copy the underlying data into a Python `bytes`.
Many methods from the Python `bytes` class are implemented on this,
"""
def __init__(self, buf: Buffer = b"") -> None:
"""Construct a new Bytes object.
This will be a zero-copy view on the Python byte slice.
"""
def __add__(self, other: Buffer) -> Bytes: ...
def __buffer__(self, flags: int) -> memoryview[int]: ...
def __contains__(self, other: Buffer) -> bool: ...
def __eq__(self, other: object) -> bool: ...
@overload
def __getitem__(self, other: int) -> int: ...
@overload
def __getitem__(self, other: slice) -> Bytes: ...
def __mul__(self, other: Buffer) -> int: ...
def __len__(self) -> int: ...
def __repr__(self) -> str: ...
def removeprefix(self, prefix: Buffer, /) -> Bytes:
"""
If the binary data starts with the prefix string, return `bytes[len(prefix):]`.
Otherwise, return the original binary data.
"""
def removesuffix(self, suffix: Buffer, /) -> Bytes:
"""
If the binary data ends with the suffix string and that suffix is not empty,
return `bytes[:-len(suffix)]`. Otherwise, return the original binary data.
"""
def isalnum(self) -> bool:
"""
Return `True` if all bytes in the sequence are alphabetical ASCII characters or
ASCII decimal digits and the sequence is not empty, `False` otherwise.
Alphabetic ASCII characters are those byte values in the sequence
`b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'`. ASCII decimal digits
are those byte values in the sequence `b'0123456789'`.
"""
def isalpha(self) -> bool:
"""
Return `True` if all bytes in the sequence are alphabetic ASCII characters and
the sequence is not empty, `False` otherwise.
Alphabetic ASCII characters are those byte values in the sequence
`b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'`.
"""
def isascii(self) -> bool:
"""
Return `True` if the sequence is empty or all bytes in the sequence are ASCII,
`False` otherwise.
ASCII bytes are in the range `0-0x7F`.
"""
def isdigit(self) -> bool:
"""
Return `True` if all bytes in the sequence are ASCII decimal digits and the
sequence is not empty, `False` otherwise.
ASCII decimal digits are those byte values in the sequence `b'0123456789'`.
"""
def islower(self) -> bool:
"""
Return `True` if there is at least one lowercase ASCII character in the sequence
and no uppercase ASCII characters, `False` otherwise.
"""
def isspace(self) -> bool:
"""
Return `True` if all bytes in the sequence are ASCII whitespace and the sequence
is not empty, `False` otherwise.
ASCII whitespace characters are those byte values
in the sequence `b' \t\n\r\x0b\f'` (space, tab, newline, carriage return,
vertical tab, form feed).
"""
def isupper(self) -> bool:
"""
Return `True` if there is at least one uppercase alphabetic ASCII character in
the sequence and no lowercase ASCII characters, `False` otherwise.
"""
def lower(self) -> Bytes:
"""
Return a copy of the sequence with all the uppercase ASCII characters converted
to their corresponding lowercase counterpart.
"""
def upper(self) -> Bytes:
"""
Return a copy of the sequence with all the lowercase ASCII characters converted
to their corresponding uppercase counterpart.
"""
def to_bytes(self) -> bytes:
"""Copy this buffer's contents into a Python `bytes` object."""
# =========================================================================
# IMPL IN RY
# =========================================================================
def decode(self, encoding: str = "utf-8", errors: str = "strict") -> str:
"""Decode the binary data using the given encoding."""
def hex(
self, sep: str | None = None, bytes_per_sep: int | None = None
) -> str:
"""Return a hexadecimal representation of the binary data."""
@classmethod
def fromhex(cls, hexstr: str) -> Bytes:
"""Construct a `Bytes` object from a hexadecimal string."""
BytesLike = Buffer | bytes | bytearray | memoryview | Bytes
ry.ryo3._bzip2
"""ryo3-bzip2 types"""
from __future__ import annotations
from ry._types import Buffer
# =============================================================================
# BZIP2
# =============================================================================
def bzip2_encode(input: Buffer, quality: int = 9) -> bytes: ...
def bzip2_decode(input: Buffer) -> bytes: ...
def bzip2(input: Buffer, quality: int = 9) -> bytes:
"""Alias for bzip2_encode"""
ry.ryo3._dev
"""ry.ryo3.dev"""
from __future__ import annotations
import typing as t
# =============================================================================
# SUBPROCESS (VERY MUCH WIP)
# =============================================================================
def run(
*args: str | list[str],
capture_output: bool = True,
input: bytes | None = None,
) -> t.Any: ...
# =============================================================================
# STRING-DEV
# =============================================================================
def anystr_noop(s: t.AnyStr) -> t.AnyStr: ...
def string_noop(s: str) -> str: ...
def bytes_noop(s: bytes) -> bytes: ...
ry.ryo3._flate2
"""ryo3-flate2 types"""
from __future__ import annotations
from ry import Bytes
from ry._types import Buffer
# =============================================================================
# GZIP
# =============================================================================
def gzip_encode(input: Buffer, quality: int = 9) -> Bytes: ...
def gzip_decode(input: Buffer) -> Bytes: ...
def gzip(input: Buffer, quality: int = 9) -> Bytes:
"""Alias for gzip_encode"""
def gunzip(input: Buffer) -> Bytes:
"""Alias for gzip_decode"""
def is_gzipped(input: Buffer) -> bool: ...
ry.ryo3._fnv
"""ryo3-fnv types"""
import typing as t
from ry._types import Buffer
# =============================================================================
# FNV
# =============================================================================
class FnvHasher:
name: t.Literal["fnv1a"]
def __init__(self, input: Buffer | None = None) -> None: ...
def update(self, input: Buffer) -> None: ...
def digest(self) -> int: ...
def hexdigest(self) -> str: ...
def copy(self) -> FnvHasher: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def fnv1a(input: Buffer) -> FnvHasher: ...
ry.ryo3._fspath
"""ryo3-fspath types"""
from __future__ import annotations
import typing as t
from os import PathLike
from pathlib import Path
from ry import Bytes
from ry._types import Buffer, ToPy
# =============================================================================
# FSPATH
# =============================================================================
class FsPath(ToPy[Path]):
def __init__(self, path: PathLike[str] | str | None = None) -> None: ...
def __fspath__(self) -> str: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def __hash__(self) -> int: ...
def __eq__(self, other: object) -> bool: ...
def __ne__(self, other: object) -> bool: ...
def __lt__(self, other: PathLike[str] | str) -> bool: ...
def __le__(self, other: PathLike[str] | str) -> bool: ...
def __gt__(self, other: PathLike[str] | str) -> bool: ...
def __ge__(self, other: PathLike[str] | str) -> bool: ...
def __truediv__(self, other: PathLike[str] | str) -> FsPath: ...
def __rtruediv__(self, other: PathLike[str] | str) -> FsPath: ...
def __bytes__(self) -> bytes: ...
def to_py(self) -> Path: ...
def to_pathlib(self) -> Path: ...
def read(self) -> Bytes: ...
def read_text(self) -> str: ...
def read_bytes(self) -> bytes: ...
def absolute(self) -> FsPath: ...
def resolve(self) -> FsPath: ...
def write(self, data: Buffer | bytes) -> None: ...
def write_bytes(self, data: Buffer | bytes) -> None: ...
def write_text(self, data: str) -> None: ...
def joinpath(self, *paths: str) -> FsPath: ...
def exists(self) -> bool: ...
def with_name(self, name: str) -> FsPath: ...
def with_suffix(self, suffix: str) -> FsPath: ...
def iterdir(self) -> t.Iterator[FsPath]: ...
def relative_to(self, other: PathLike[str] | str | FsPath) -> FsPath: ...
def as_posix(self) -> str: ...
def as_uri(self) -> str: ...
def equiv(self, other: PathLike[str] | str | FsPath) -> bool: ...
def string(self) -> str: ...
def clone(self) -> FsPath: ...
# =========================================================================
# CLASSMETHODS
# =========================================================================
@classmethod
def cwd(cls) -> FsPath: ...
@classmethod
def home(cls) -> FsPath: ...
# =========================================================================
# PROPERTIES
# =========================================================================
@property
def anchor(self) -> str: ...
@property
def drive(self) -> str: ...
@property
def name(self) -> str: ...
@property
def parent(self) -> FsPath: ...
@property
def parents(self) -> t.Sequence[FsPath]: ...
@property
def parts(self) -> tuple[str, ...]: ...
@property
def root(self) -> str: ...
@property
def stem(self) -> str: ...
@property
def suffix(self) -> str: ...
@property
def suffixes(self) -> list[str]: ...
# =========================================================================
# std::path::PathBuf (deref -> std::path::Path)
# =========================================================================
def ancestors(self) -> t.Iterator[FsPath]: ...
def canonicalize(self) -> FsPath: ...
def components(self) -> t.Iterator[FsPath]: ...
def display(self) -> str: ...
def ends_with(self, path: PathLike[str] | str) -> bool: ...
def extension(self) -> str: ...
def file_name(self) -> str: ...
def file_prefix(self) -> FsPath: ...
def file_stem(self) -> str: ...
def has_root(self) -> bool: ...
def is_absolute(self) -> bool: ...
def is_dir(self) -> bool: ...
def is_file(self) -> bool: ...
def is_relative(self) -> bool: ...
def is_symlink(self) -> bool: ...
def starts_with(self, path: PathLike[str] | str) -> bool: ...
def strip_prefix(self, prefix: PathLike[str] | str) -> FsPath: ...
def with_extension(self, ext: str) -> FsPath: ...
def with_file_name(self, name: str) -> FsPath: ...
ry.ryo3._glob
"""ryo3-glob types"""
from __future__ import annotations
import typing as t
from os import PathLike
from pathlib import Path
import typing_extensions as te
T = t.TypeVar("T")
class _MatchOptions(t.TypedDict, total=False):
case_sensitive: bool
require_literal_separator: bool
require_literal_leading_dot: bool
class GlobPaths(t.Generic[T]):
"""glob::Paths iterable wrapper"""
def __next__(self) -> T: ...
def __iter__(self) -> t.Iterator[T]: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def collect(self) -> list[T]: ...
def take(self, n: int) -> list[T]: ...
def glob(
pattern: str,
**kwargs: te.Unpack[_MatchOptions],
) -> GlobPaths[Path]:
"""Return glob iterable for paths matching the pattern."""
class Pattern:
def __init__(self, pattern: str) -> None: ...
def __call__(
self,
ob: str | PathLike[str],
**kwargs: te.Unpack[_MatchOptions],
) -> bool: ...
def matches(self, s: str) -> bool: ...
def matches_path(self, path: PathLike[str]) -> bool: ...
def matches_with(
self,
s: str,
**kwargs: te.Unpack[_MatchOptions],
) -> bool: ...
def matches_path_with(
self,
path: PathLike[str],
**kwargs: te.Unpack[_MatchOptions],
) -> bool: ...
@staticmethod
def escape(pattern: str) -> str: ...
ry.ryo3._globset
"""ryo3-globset types"""
from __future__ import annotations
from os import PathLike
class Glob:
"""globset::Glob wrapper"""
def __init__(
self,
pattern: str,
/,
*,
case_insensitive: bool | None = None,
literal_separator: bool | None = None,
backslash_escape: bool | None = None,
) -> None: ...
def regex(self) -> str: ...
def is_match(self, path: str | PathLike[str]) -> bool: ...
def __call__(self, path: str | PathLike[str]) -> bool: ...
def __invert__(self) -> Glob: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def globset(self) -> GlobSet: ...
def globster(self) -> Globster: ...
class GlobSet:
"""globset::GlobSet wrapper"""
def __init__(
self,
patterns: list[str],
/,
*,
case_insensitive: bool | None = None,
literal_separator: bool | None = None,
backslash_escape: bool | None = None,
) -> None: ...
def is_empty(self) -> bool: ...
def is_match(self, path: str) -> bool: ...
def matches(self, path: str) -> list[int]: ...
def __call__(self, path: str) -> bool: ...
def __invert__(self) -> GlobSet: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def globster(self) -> Globster: ...
class Globster:
"""Globster is a matcher with claws!
Note: The north american `Globster` is similar to the european `Globset`
but allows for negative patterns (prefixed with '!')
"""
def __init__(
self,
patterns: list[str],
/,
*,
case_insensitive: bool | None = None,
literal_separator: bool | None = None,
backslash_escape: bool | None = None,
) -> None: ...
def is_empty(self) -> bool: ...
def is_match(self, path: str | PathLike[str]) -> bool: ...
def __call__(self, path: str | PathLike[str]) -> bool: ...
def __invert__(self) -> GlobSet: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def globster(
patterns: list[str] | tuple[str, ...],
/,
*,
case_insensitive: bool | None = None,
literal_separator: bool | None = None,
backslash_escape: bool | None = None,
) -> Globster: ...
ry.ryo3._heck
"""ryo3-heck types"""
from __future__ import annotations
def camel_case(string: str) -> str: ...
def kebab_case(string: str) -> str: ...
def pascal_case(string: str) -> str: ...
def shouty_kebab_case(string: str) -> str: ...
def shouty_snake_case(string: str) -> str: ...
def snake_case(string: str) -> str: ...
def snek_case(string: str) -> str: ...
def title_case(string: str) -> str: ...
def train_case(string: str) -> str: ...
ry.ryo3._jiff
"""jiff types"""
import datetime as pydt
import typing as t
from typing import Protocol
import typing_extensions as te
from ry._types import (
DateTimeTypedDict,
DateTypedDict,
TimeSpanTypedDict,
TimeTypedDict,
ToPy,
)
from ry.ryo3 import Duration
T = t.TypeVar("T")
# =============================================================================
# JIFF
# =============================================================================
JIFF_UNIT = t.Literal[
"year",
"month",
"week",
"day",
"hour",
"minute",
"second",
"millisecond",
"microsecond",
"nanosecond",
]
JIFF_ROUND_MODE = t.Literal[
"ceil",
"floor",
"expand",
"trunc",
"half_ceil",
"half_floor",
"half_expand",
"half_trunc",
"half_even",
]
WEEKDAY_STR = t.Literal[
"monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"
]
WEEKDAY_INT = t.Literal[
1, # Monday
2, # Tuesday
3, # Wednesday
4, # Thursday
5, # Friday
6, # Saturday
7, # Sunday
]
WEEKDAY: te.TypeAlias = WEEKDAY_STR | WEEKDAY_INT
class ToPyDate(Protocol):
def to_pydate(self) -> pydt.date: ...
class ToPyTime(Protocol):
def to_pytime(self) -> pydt.time: ...
class ToPyDateTime(Protocol):
def to_pydatetime(self) -> pydt.datetime: ...
class ToPyTimeDelta(Protocol):
def to_pytimedelta(self) -> pydt.timedelta: ...
class ToPyTzInfo(Protocol):
def to_pytzinfo(self) -> pydt.tzinfo: ...
class Date(ToPy[pydt.date], ToPyDate):
MIN: Date
MAX: Date
ZERO: Date
def __init__(self, year: int, month: int, day: int) -> None: ...
# =========================================================================
# STRING
# =========================================================================
def string(self) -> str: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
# =========================================================================
# PYTHON_CONVERSIONS
# =========================================================================
def to_py(self) -> pydt.date: ...
def to_pydate(self) -> pydt.date: ...
@classmethod
def from_pydate(cls: type[Date], date: pydt.date) -> Date: ...
# =========================================================================
# PROPERTIES
# =========================================================================
@property
def year(self) -> int: ...
@property
def month(self) -> int: ...
@property
def day(self) -> int: ...
@property
def weekday(self) -> int: ...
# =========================================================================
# CLASSMETHODS
# =========================================================================
@classmethod
def from_iso_week_date(
cls: type[Date], year: int, week: int, weekday: int
) -> Date: ...
@classmethod
def today(cls: type[Date]) -> Date: ...
# =========================================================================
# STRPTIME/STRFTIME
# =========================================================================
@classmethod
def strptime(cls: type[Date], format: str, string: str) -> Date: ...
def strftime(self, format: str) -> str: ...
# =========================================================================
# OPERATORS
# =========================================================================
def __add__(self, other: TimeSpan | SignedDuration | Duration) -> Date: ...
@t.overload
def __sub__(self, other: Date) -> TimeSpan: ...
@t.overload
def __sub__(self, other: TimeSpan | SignedDuration | Duration) -> Date: ...
@t.overload
def __isub__(self, other: Date) -> TimeSpan: ...
@t.overload
def __isub__(self, other: TimeSpan | SignedDuration | Duration) -> Date: ...
# =========================================================================
# INSTANCE METHODS
# =========================================================================
def at(
self, hour: int, minute: int, second: int, nanosecond: int
) -> DateTime: ...
def asdict(self) -> DateTypedDict: ...
def astuple(self) -> tuple[int, int, int]: ...
def checked_add(
self, other: TimeSpan | SignedDuration | Duration
) -> Date: ...
def day_of_year(self) -> int: ...
def day_of_year_no_leap(self) -> int | None: ...
def days_in_month(self) -> int: ...
def days_in_year(self) -> int: ...
def duration_since(self, other: Date) -> Date: ...
def duration_until(self, other: Date) -> Date: ...
def era_year(self) -> tuple[int, t.Literal["BCE", "CE"]]: ...
def first_of_month(self) -> Date: ...
def first_of_year(self) -> Date: ...
def iso_week_date(self) -> ISOWeekDate: ...
def in_leap_year(self) -> bool: ...
def in_tz(self, tz: str) -> ZonedDateTime: ...
def intz(self, tz: str) -> ZonedDateTime: ...
def last_of_month(self) -> Date: ...
def last_of_year(self) -> Date: ...
def nth_weekday(self, nth: int, weekday: WEEKDAY) -> Date: ...
def nth_weekday_of_month(self, nth: int, weekday: WEEKDAY) -> Date: ...
def saturating_add(
self, other: TimeSpan | SignedDuration | Duration
) -> Date: ...
def saturating_sub(
self, other: TimeSpan | SignedDuration | Duration
) -> Date: ...
def series(self, span: TimeSpan) -> JiffSeries[Date]: ...
def sub_date(self, other: Date) -> TimeSpan: ...
def to_datetime(self, time: Time) -> DateTime: ...
def to_zoned(self, tz: TimeZone) -> ZonedDateTime: ...
def tomorrow(self) -> Date: ...
def yesterday(self) -> Date: ...
# =========================================================================
# SINCE/UNTIL
# =========================================================================
def _since(self, other: DateDifference) -> TimeSpan: ...
def _until(self, other: DateDifference) -> TimeSpan: ...
def since(
self,
other: Date | DateTime | ZonedDateTime,
*,
smallest: JIFF_UNIT | None = None,
largest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> TimeSpan: ...
def until(
self,
other: Date | DateTime | ZonedDateTime,
*,
smallest: JIFF_UNIT | None = None,
largest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> TimeSpan: ...
# =========================================================================
# INSTANCE METHODS W/ OVERLOADS
# =========================================================================
@t.overload
def checked_sub(self, other: Date) -> TimeSpan: ...
@t.overload
def checked_sub(
self, other: TimeSpan | SignedDuration | Duration
) -> Date: ...
class DateDifference:
def __init__(
self,
date: Date,
*,
smallest: JIFF_UNIT | None = None,
largest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> None: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def smallest(self, unit: JIFF_UNIT) -> DateDifference: ...
def largest(self, unit: JIFF_UNIT) -> DateDifference: ...
def mode(self, mode: JIFF_ROUND_MODE) -> DateDifference: ...
def increment(self, increment: int) -> DateDifference: ...
class Time(ToPy[pydt.time], ToPyTime):
MIN: Time
MAX: Time
def __init__(
self,
hour: int = 0,
minute: int = 0,
second: int = 0,
nanosecond: int = 0,
) -> None: ...
# =========================================================================
# STRING
# =========================================================================
def string(self) -> str: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
# =========================================================================
# OPERATORS/DUNDERS
# =========================================================================
def __add__(self, other: TimeSpan | SignedDuration | Duration) -> Time: ...
@t.overload
def __sub__(self, other: Time) -> TimeSpan: ...
@t.overload
def __sub__(self, other: TimeSpan | SignedDuration | Duration) -> Time: ...
@t.overload
def __isub__(self, other: Time) -> TimeSpan: ...
@t.overload
def __isub__(self, other: TimeSpan | SignedDuration | Duration) -> Time: ...
# =========================================================================
# STRPTIME/STRFTIME/PARSE
# =========================================================================
@classmethod
def strptime(cls: type[Time], format: str, string: str) -> Time: ...
def strftime(self, format: str) -> str: ...
# =========================================================================
# PYTHON CONVERSIONS
# =========================================================================
def to_py(self) -> pydt.time: ...
def to_pytime(self) -> pydt.time: ...
@classmethod
def from_pytime(cls: type[Time], t: pydt.time) -> Time: ...
# =========================================================================
# CLASS METHODS
# =========================================================================
@classmethod
def midnight(cls: type[Time]) -> Time: ...
@classmethod
def now(cls: type[Time]) -> Time: ...
@classmethod
def parse(cls: type[Time], s: str) -> Time: ...
# =========================================================================
# PROPERTIES
# =========================================================================
@property
def hour(self) -> int: ...
@property
def minute(self) -> int: ...
@property
def second(self) -> int: ...
@property
def millisecond(self) -> int: ...
@property
def microsecond(self) -> int: ...
@property
def nanosecond(self) -> int: ...
@property
def subsec_nanosecond(self) -> None: ...
# =========================================================================
# INSTANCE METHODS
# =========================================================================
def astuple(self) -> tuple[int, int, int, int]: ...
def asdict(self) -> TimeTypedDict: ...
def series(self, span: TimeSpan) -> JiffSeries[Time]: ...
def checked_add(
self, other: TimeSpan | SignedDuration | Duration
) -> Time: ...
@t.overload
def checked_sub(self, other: Time) -> TimeSpan: ...
@t.overload
def checked_sub(
self, other: TimeSpan | SignedDuration | Duration
) -> Time: ...
def saturating_add(
self, other: TimeSpan | SignedDuration | Duration
) -> Time: ...
def saturating_sub(
self, other: TimeSpan | SignedDuration | Duration
) -> Time: ...
def wrapping_add(
self, other: TimeSpan | SignedDuration | Duration
) -> Time: ...
def wrapping_sub(
self, other: TimeSpan | SignedDuration | Duration
) -> Time: ...
def on(self, year: int, month: int, day: int) -> DateTime: ...
def duration_until(self, other: Time) -> SignedDuration: ...
def duration_since(self, other: Time) -> SignedDuration: ...
def round(
self,
smallest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> Time: ...
def to_datetime(self, d: Date) -> DateTime: ...
# =========================================================================
# SINCE/UNTIL
# =========================================================================
def _since(self, other: TimeDifference) -> TimeSpan: ...
def _until(self, other: TimeDifference) -> TimeSpan: ...
def since(
self,
other: Time | DateTime | ZonedDateTime,
*,
smallest: JIFF_UNIT | None = None,
largest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> TimeSpan: ...
def until(
self,
other: Time | DateTime | ZonedDateTime,
*,
smallest: JIFF_UNIT | None = None,
largest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> TimeSpan: ...
class TimeDifference:
def __init__(
self,
date: Time,
*,
smallest: JIFF_UNIT | None = None,
largest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> None: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def smallest(self, unit: JIFF_UNIT) -> TimeDifference: ...
def largest(self, unit: JIFF_UNIT) -> TimeDifference: ...
def mode(self, mode: JIFF_ROUND_MODE) -> TimeDifference: ...
def increment(self, increment: int) -> TimeDifference: ...
class DateTime(ToPy[pydt.datetime], ToPyDate, ToPyTime, ToPyDateTime):
MIN: DateTime
MAX: DateTime
ZERO: DateTime
def __init__(
self,
year: int,
month: int,
day: int,
hour: int = 0,
minute: int = 0,
second: int = 0,
nanosecond: int = 0,
) -> None: ...
def __str__(self) -> str: ...
def string(self) -> str: ...
# =========================================================================
# STRPTIME/STRFTIME/PARSE
# =========================================================================
def strftime(self, format: str) -> str: ...
@classmethod
def strptime(cls: type[DateTime], format: str, string: str) -> DateTime: ...
@classmethod
def parse(cls: type[DateTime], s: str) -> DateTime: ...
# =========================================================================
# PYTHON CONVERSIONS
# =========================================================================
@classmethod
def from_pydatetime(cls: type[DateTime], dt: pydt.datetime) -> DateTime: ...
def to_py(self) -> pydt.datetime: ...
def to_pydate(self) -> pydt.date: ...
def to_pydatetime(self) -> pydt.datetime: ...
def to_pytime(self) -> pydt.time: ...
# =========================================================================
# CLASS METHODS
# =========================================================================
@classmethod
def now(cls: type[DateTime]) -> DateTime: ...
@classmethod
def from_parts(cls: type[DateTime], date: Date, time: Time) -> DateTime: ...
# =========================================================================
# OPERATORS
# =========================================================================
def __repr__(self) -> str: ...
def __add__(
self, other: TimeSpan | SignedDuration | Duration
) -> DateTime: ...
@t.overload
def __sub__(self, other: DateTime) -> TimeSpan: ...
@t.overload
def __sub__(
self, other: TimeSpan | SignedDuration | Duration
) -> DateTime: ...
@t.overload
def __isub__(self, other: DateTime) -> TimeSpan: ...
@t.overload
def __isub__(
self, other: TimeSpan | SignedDuration | Duration
) -> DateTime: ...
# =========================================================================
# INSTANCE METHODS
# =========================================================================
def asdict(self) -> DateTimeTypedDict: ...
def checked_add(
self, other: TimeSpan | SignedDuration | Duration
) -> DateTime: ...
def date(self) -> Date: ...
def day_of_year(self) -> int: ...
def day_of_year_no_leap(self) -> int | None: ...
def days_in_month(self) -> int: ...
def days_in_year(self) -> int: ...
def duration_since(self, other: DateTime) -> SignedDuration: ...
def duration_until(self, other: DateTime) -> SignedDuration: ...
def end_of_day(self) -> DateTime: ...
def era_year(self) -> tuple[int, t.Literal["BCE", "CE"]]: ...
def first_of_month(self) -> DateTime: ...
def first_of_year(self) -> DateTime: ...
def in_leap_year(self) -> bool: ...
def in_tz(self, tz: str) -> ZonedDateTime: ...
def intz(self, tz: str) -> ZonedDateTime: ...
def iso_week_date(self) -> ISOWeekDate: ...
def last_of_month(self) -> DateTime: ...
def last_of_year(self) -> DateTime: ...
def nth_weekday(self, nth: int, weekday: WEEKDAY) -> DateTime: ...
def nth_weekday_of_month(self, nth: int, weekday: WEEKDAY) -> DateTime: ...
def round(
self,
smallest: JIFF_UNIT | None = None,
*,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> DateTime: ...
def _round(self, options: DateTimeRound) -> DateTime: ...
def saturating_add(
self, other: TimeSpan | SignedDuration | Duration
) -> DateTime: ...
def series(self, span: TimeSpan) -> JiffSeries[DateTime]: ...
def start_of_day(self) -> DateTime: ...
def time(self) -> Time: ...
def to_zoned(self, tz: TimeZone) -> ZonedDateTime: ...
def tomorrow(self) -> DateTime: ...
def yesterday(self) -> DateTime: ...
# =========================================================================
# INSTANCE METHODS W/ OVERLOADS
# =========================================================================
@t.overload
def checked_sub(self, other: DateTime) -> TimeSpan: ...
@t.overload
def checked_sub(
self, other: TimeSpan | SignedDuration | Duration
) -> DateTime: ...
@t.overload
def saturating_sub(self, other: DateTime) -> TimeSpan: ...
@t.overload
def saturating_sub(
self, other: TimeSpan | SignedDuration | Duration
) -> DateTime: ...
# =========================================================================
# PROPERTIES
# =========================================================================
@property
def year(self) -> int: ...
@property
def month(self) -> int: ...
@property
def day(self) -> int: ...
@property
def hour(self) -> int: ...
@property
def minute(self) -> int: ...
@property
def second(self) -> int: ...
@property
def millisecond(self) -> int: ...
@property
def microsecond(self) -> int: ...
@property
def nanosecond(self) -> int: ...
@property
def subsec_nanosecond(self) -> int: ...
@property
def weekday(self) -> int: ...
# =========================================================================
# SINCE/UNTIL
# =========================================================================
def _since(self, other: DateTimeDifference) -> TimeSpan: ...
def _until(self, other: DateTimeDifference) -> TimeSpan: ...
def since(
self,
other: Date | Time | DateTime | ZonedDateTime,
*,
smallest: JIFF_UNIT | None = None,
largest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> TimeSpan: ...
def until(
self,
other: Date | Time | DateTime | ZonedDateTime,
*,
smallest: JIFF_UNIT | None = None,
largest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> TimeSpan: ...
class DateTimeDifference:
def __init__(
self,
date: DateTime,
*,
smallest: JIFF_UNIT | None = None,
largest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> None: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def smallest(self, unit: JIFF_UNIT) -> DateTimeDifference: ...
def largest(self, unit: JIFF_UNIT) -> DateTimeDifference: ...
def mode(self, mode: JIFF_ROUND_MODE) -> DateTimeDifference: ...
def increment(self, increment: int) -> DateTimeDifference: ...
class TimeZone(ToPy[pydt.tzinfo], ToPyTzInfo):
def __init__(self, name: str) -> None: ...
def __eq__(self, other: object) -> bool: ...
# =========================================================================
# STRING
# =========================================================================
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
# =========================================================================
# PYTHON CONVERSIONS
# =========================================================================
def to_py(self) -> pydt.tzinfo: ...
def to_pytzinfo(self) -> pydt.tzinfo: ...
@classmethod
def from_pytzinfo(cls: type[TimeZone], tz: pydt.tzinfo) -> TimeZone: ...
# =========================================================================
# PROPERTIES
# =========================================================================
@property
def name(self) -> str: ...
# =========================================================================
# CLASS METHODS
# =========================================================================
@classmethod
def fixed(cls: type[TimeZone], offset: Offset) -> TimeZone: ...
@classmethod
def get(cls: type[TimeZone], name: str) -> TimeZone: ...
@classmethod
def posix(cls: type[TimeZone], name: str) -> TimeZone: ...
@classmethod
def system(cls: type[TimeZone]) -> TimeZone: ...
@classmethod
def try_system(cls: type[TimeZone]) -> TimeZone: ...
@classmethod
def tzif(cls: type[TimeZone], name: str, data: bytes) -> TimeZone: ...
@classmethod
def utc(cls: type[TimeZone]) -> TimeZone: ...
# =========================================================================
# INSTANCE METHODS
# =========================================================================
def iana_name(self) -> str | None: ...
def to_datetime(self, dt: Timestamp) -> DateTime: ...
def to_offset(self, timestamp: Timestamp) -> Offset: ...
def to_timestamp(self, dt: DateTime) -> Timestamp: ...
def to_zoned(self, other: DateTime) -> ZonedDateTime: ...
# =========================================================================
# NOT IMPLEMENTED
# =========================================================================
def to_ambiguous_timestamp(self) -> t.NoReturn: ...
def to_ambiguous_zoned(self) -> t.NoReturn: ...
class SignedDuration(ToPy[pydt.timedelta], ToPyTimeDelta):
MIN: SignedDuration
MAX: SignedDuration
ZERO: SignedDuration
def __init__(self, secs: int = 0, nanos: int = 0) -> None: ...
# =========================================================================
# OPERATORS/DUNDERS
# =========================================================================
def __hash__(self) -> int: ...
def __mul__(self, other: int) -> SignedDuration: ...
def __rmul__(self, other: int) -> SignedDuration: ...
def __eq__(self, other: object) -> bool: ...
def __ne__(self, other: object) -> bool: ...
def __lt__(self, other: object) -> bool: ...
def __le__(self, other: object) -> bool: ...
def __gt__(self, other: object) -> bool: ...
def __ge__(self, other: object) -> bool: ...
def __neg__(self) -> SignedDuration: ...
def __add__(self, other: SignedDuration) -> SignedDuration: ...
def __abs__(self) -> SignedDuration: ...
def __div__(self, other: int) -> SignedDuration: ...
def abs(self) -> SignedDuration: ...
def unsigned_abs(self) -> Duration: ...
def __richcmp__(
self, other: SignedDuration | pydt.timedelta, op: int
) -> bool: ...
# =========================================================================
# STRING
# =========================================================================
def __str__(self) -> str: ...
def string(self, human: bool = False) -> str: ...
# =========================================================================
# PYTHON CONVERSIONS
# =========================================================================
@classmethod
def from_pytimedelta(
cls: type[SignedDuration], td: pydt.timedelta
) -> SignedDuration: ...
def to_py(self) -> pydt.timedelta: ...
def to_pytimedelta(self) -> pydt.timedelta: ...
# =========================================================================
# CLASS METHODS
# =========================================================================
@classmethod
def parse(cls: type[SignedDuration], s: str) -> SignedDuration: ...
@classmethod
def from_hours(cls: type[SignedDuration], n: int) -> SignedDuration: ...
@classmethod
def from_micros(cls: type[SignedDuration], n: int) -> SignedDuration: ...
@classmethod
def from_millis(cls: type[SignedDuration], n: int) -> SignedDuration: ...
@classmethod
def from_mins(cls: type[SignedDuration], n: int) -> SignedDuration: ...
@classmethod
def from_nanos(cls: type[SignedDuration], n: int) -> SignedDuration: ...
@classmethod
def from_secs(cls: type[SignedDuration], n: int) -> SignedDuration: ...
@classmethod
def from_secs_f32(
cls: type[SignedDuration], n: float
) -> SignedDuration: ...
@classmethod
def from_secs_f64(
cls: type[SignedDuration], n: float
) -> SignedDuration: ...
# =========================================================================
# PROPERTIES
# =========================================================================
@property
def is_negative(self) -> bool: ...
@property
def is_zero(self) -> bool: ...
@property
def secs(self) -> int: ...
@property
def nanos(self) -> int: ...
@property
def days(self) -> int: ...
@property
def seconds(self) -> int: ...
@property
def microseconds(self) -> int: ...
# =========================================================================
# INSTANCE METHODS
# =========================================================================
def as_hours(self) -> int: ...
def as_micros(self) -> int: ...
def as_millis(self) -> int: ...
def as_millis_f32(self) -> float: ...
def as_millis_f64(self) -> float: ...
def as_mins(self) -> int: ...
def as_nanos(self) -> int: ...
def as_secs(self) -> int: ...
def as_secs_f32(self) -> float: ...
def as_secs_f64(self) -> float: ...
def checked_add(self, other: SignedDuration) -> SignedDuration | None: ...
def checked_div(self, other: int) -> SignedDuration | None: ...
def checked_mul(self, other: int) -> SignedDuration | None: ...
def checked_neg(self) -> SignedDuration | None: ...
def checked_sub(self, other: SignedDuration) -> SignedDuration | None: ...
def div_duration_f32(self, other: SignedDuration) -> float: ...
def div_duration_f64(self, other: SignedDuration) -> float: ...
def div_f32(self, other: int) -> float: ...
def div_f64(self, other: int) -> float: ...
def is_positive(self) -> bool: ...
def mul_f32(self, other: int) -> SignedDuration: ...
def mul_f64(self, other: int) -> SignedDuration: ...
def saturating_add(self, other: SignedDuration) -> SignedDuration: ...
def saturating_mul(self, other: int) -> SignedDuration: ...
def saturating_sub(self, other: SignedDuration) -> SignedDuration: ...
def signum(self) -> t.Literal[-1, 0, 1]: ...
def subsec_micros(self) -> int: ...
def subsec_millis(self) -> int: ...
def subsec_nanos(self) -> int: ...
def to_timespan(self) -> TimeSpan: ...
# put in quotes to avoid ruff F821 - undefined name
_TimeSpanArithmeticSingle = TimeSpan | Duration | SignedDuration
_TimeSpanArithmeticTuple = tuple[
_TimeSpanArithmeticSingle, ZonedDateTime | Date | DateTime
]
TimeSpanArithmetic = _TimeSpanArithmeticSingle | _TimeSpanArithmeticTuple
class TimeSpan(ToPy[pydt.timedelta], ToPyTimeDelta):
def __init__(
self,
years: int = 0,
months: int = 0,
weeks: int = 0,
days: int = 0,
hours: int = 0,
minutes: int = 0,
seconds: int = 0,
milliseconds: int = 0,
microseconds: int = 0,
nanoseconds: int = 0,
) -> None: ...
# =========================================================================
# STRING
# =========================================================================
def string(self, human: bool = False) -> str: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def repr_full(self) -> str: ...
# =========================================================================
# PYTHON CONVERSIONS
# =========================================================================
@classmethod
def from_pytimedelta(cls, td: pydt.timedelta) -> TimeSpan: ...
def to_pytimedelta(self) -> pydt.timedelta: ...
def to_py(self) -> pydt.timedelta: ...
# =========================================================================
# CLASS METHODS
# =========================================================================
@classmethod
def parse(cls, s: str) -> TimeSpan: ...
# =========================================================================
# PROPERTIES
# =========================================================================
@property
def is_positive(self) -> bool: ...
@property
def is_negative(self) -> bool: ...
@property
def is_zero(self) -> bool: ...
@property
def years(self) -> int: ...
@property
def months(self) -> int: ...
@property
def weeks(self) -> int: ...
@property
def days(self) -> int: ...
@property
def hours(self) -> int: ...
@property
def minutes(self) -> int: ...
@property
def seconds(self) -> int: ...
@property
def milliseconds(self) -> int: ...
@property
def microseconds(self) -> int: ...
@property
def nanoseconds(self) -> int: ...
# =========================================================================
# OPERATORS
# =========================================================================
def __add__(
self,
val: TimeSpanArithmetic,
) -> te.Self: ...
def __sub__(
self,
val: TimeSpanArithmetic,
) -> te.Self: ...
def __mul__(self, other: int) -> te.Self: ...
def __neg__(self) -> te.Self: ...
def __abs__(self) -> te.Self: ...
def __invert__(self) -> te.Self: ...
def __eq__(self, other: object) -> bool: ...
def __ge__(self, other: TimeSpan) -> bool: ...
def __gt__(self, other: TimeSpan) -> bool: ...
def __le__(self, other: TimeSpan) -> bool: ...
def __lt__(self, other: TimeSpan) -> bool: ...
def __ne__(self, other: object) -> bool: ...
def __rmul__(self, other: TimeSpan) -> bool: ...
def __hash__(self) -> int: ...
# =========================================================================
# INSTANCE METHODS
# =========================================================================
def abs(self) -> te.Self: ...
def asdict(self) -> TimeSpanTypedDict: ...
def checked_add(self, val: TimeSpanArithmetic) -> te.Self: ...
def checked_mul(self, other: int) -> te.Self: ...
def checked_sub(self, val: TimeSpanArithmetic) -> te.Self: ...
def compare(
self,
other: TimeSpan,
relative: ZonedDateTime | DateTime | Date | None = None,
days_are_24_hours: bool = False,
) -> int: ...
def negate(self) -> te.Self: ...
def replace(
self,
years: int | None = None,
months: int | None = None,
weeks: int | None = None,
days: int | None = None,
hours: int | None = None,
minutes: int | None = None,
seconds: int | None = None,
milliseconds: int | None = None,
microseconds: int | None = None,
nanoseconds: int | None = None,
) -> te.Self: ...
def round(
self,
smallest: JIFF_UNIT,
increment: int = 1,
*,
relative: ZonedDateTime | Date | DateTime | None = None,
largest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
) -> te.Self: ...
def signum(self) -> t.Literal[-1, 0, 1]: ...
def to_signed_duration(
self, relative: ZonedDateTime | Date | DateTime
) -> SignedDuration: ...
def total(
self,
unit: JIFF_UNIT,
relative: ZonedDateTime | Date | DateTime | None = None,
days_are_24_hours: bool = False,
) -> int: ...
def total_seconds(self) -> int: ...
def try_years(self, years: int) -> te.Self: ...
def try_months(self, months: int) -> te.Self: ...
def try_weeks(self, weeks: int) -> te.Self: ...
def try_days(self, days: int) -> te.Self: ...
def try_hours(self, hours: int) -> te.Self: ...
def try_minutes(self, minutes: int) -> te.Self: ...
def try_seconds(self, seconds: int) -> te.Self: ...
def try_milliseconds(self, milliseconds: int) -> te.Self: ...
def try_microseconds(self, microseconds: int) -> te.Self: ...
def try_nanoseconds(self, nanoseconds: int) -> te.Self: ...
# -------------------------------------------------------------------------
# PANIC-INDUCING METHODS
# -------------------------------------------------------------------------
def _years(self, years: int) -> te.Self: ...
def _months(self, months: int) -> te.Self: ...
def _weeks(self, weeks: int) -> te.Self: ...
def _days(self, days: int) -> te.Self: ...
def _hours(self, hours: int) -> te.Self: ...
def _minutes(self, minutes: int) -> te.Self: ...
def _seconds(self, seconds: int) -> te.Self: ...
def _milliseconds(self, milliseconds: int) -> te.Self: ...
def _microseconds(self, microseconds: int) -> te.Self: ...
def _nanoseconds(self, nanoseconds: int) -> te.Self: ...
class Timestamp(ToPy[pydt.datetime], ToPyDate, ToPyTime, ToPyDateTime):
"""
A representation of a timestamp with second and nanosecond precision.
"""
MIN: Timestamp
MAX: Timestamp
UNIX_EPOCH: Timestamp
def __init__(
self, second: int | None = None, nanosecond: int | None = None
) -> None: ...
# =========================================================================
# CLASS METHODS
# =========================================================================
@classmethod
def now(cls) -> Timestamp: ...
@classmethod
def parse(cls, s: str) -> Timestamp: ...
@classmethod
def from_millisecond(cls, millisecond: int) -> Timestamp: ...
@classmethod
def from_microsecond(cls, microsecond: int) -> Timestamp: ...
@classmethod
def from_nanosecond(cls, nanosecond: int) -> Timestamp: ...
@classmethod
def from_second(cls, second: int) -> Timestamp: ...
# =========================================================================
# STRING
# =========================================================================
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
# =========================================================================
# OPERATORS/DUNDERS
# =========================================================================
def __add__(
self, other: TimeSpan | SignedDuration | Duration
) -> te.Self: ...
def __eq__(self, other: object) -> bool: ...
def __ge__(self, other: Timestamp) -> bool: ...
def __gt__(self, other: Timestamp) -> bool: ...
def __le__(self, other: Timestamp) -> bool: ...
def __lt__(self, other: Timestamp) -> bool: ...
def __ne__(self, other: object) -> bool: ...
def __richcmp__(self, other: Timestamp, op: int) -> bool: ...
# =========================================================================
# OPERATORS/DUNDERS W/ OVERLOADS
# =========================================================================
@t.overload
def __isub__(self, other: Timestamp) -> TimeSpan: ...
@t.overload
def __isub__(
self, other: TimeSpan | SignedDuration | Duration
) -> te.Self: ...
@t.overload
def __sub__(self, other: Timestamp) -> TimeSpan: ...
@t.overload
def __sub__(
self, other: TimeSpan | SignedDuration | Duration
) -> te.Self: ...
# =========================================================================
# PYTHON CONVERSIONS
# =========================================================================
@classmethod
def from_pydatetime(cls, dt: pydt.datetime) -> Timestamp: ...
def to_py(self) -> pydt.datetime: ...
def to_pydate(self) -> pydt.date: ...
def to_pydatetime(self) -> pydt.datetime: ...
def to_pytime(self) -> pydt.time: ...
# =========================================================================
# STRPTIME/STRFTIME
# =========================================================================
def strftime(self, format: str) -> str: ...
@classmethod
def strptime(cls, format: str, input: str) -> Timestamp: ...
# =========================================================================
# INSTANCE METHODS
# =========================================================================
def as_microsecond(self) -> int: ...
def as_millisecond(self) -> int: ...
def as_nanosecond(self) -> int: ...
def as_second(self) -> int: ...
def checked_add(
self, other: TimeSpan | SignedDuration | Duration
) -> Timestamp: ...
@t.overload
def checked_sub(self, other: Timestamp) -> TimeSpan: ...
@t.overload
def checked_sub(
self, other: TimeSpan | SignedDuration | Duration
) -> Timestamp: ...
def display_with_offset(self, offset: Offset) -> str: ...
def in_tz(self, tz: str) -> ZonedDateTime: ...
def intz(self, tz: str) -> ZonedDateTime:
"""Deprecated ~ use `in_tz`"""
def is_zero(self) -> bool: ...
def saturating_add(
self, other: TimeSpan | SignedDuration | Duration
) -> Timestamp: ...
def saturating_sub(
self, other: TimeSpan | SignedDuration | Duration
) -> Timestamp: ...
def series(self, span: TimeSpan) -> JiffSeries[Timestamp]: ...
def signum(self) -> t.Literal[-1, 0, 1]: ...
def string(self) -> str: ...
def subsec_microsecond(self) -> int: ...
def subsec_millisecond(self) -> int: ...
def subsec_nanosecond(self) -> int: ...
def to_zoned(self, time_zone: TimeZone) -> ZonedDateTime: ...
# =========================================================================
# SINCE/UNTIL
# =========================================================================
def _since(self, other: TimestampDifference) -> TimeSpan: ...
def _until(self, other: TimestampDifference) -> TimeSpan: ...
def since(
self,
other: Timestamp | ZonedDateTime,
*,
smallest: JIFF_UNIT | None = None,
largest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> TimeSpan: ...
def until(
self,
other: Timestamp | ZonedDateTime,
*,
smallest: JIFF_UNIT | None = None,
largest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> TimeSpan: ...
def duration_since(self, other: Timestamp) -> SignedDuration: ...
def duration_until(self, other: Timestamp) -> SignedDuration: ...
def round(
self,
unit: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> Timestamp: ...
def _round(self, options: TimestampRound) -> Timestamp: ...
class TimestampDifference:
def __init__(
self,
date: Timestamp,
*,
smallest: JIFF_UNIT | None = None,
largest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> None: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def smallest(self, unit: JIFF_UNIT) -> TimestampDifference: ...
def largest(self, unit: JIFF_UNIT) -> TimestampDifference: ...
def mode(self, mode: JIFF_ROUND_MODE) -> TimestampDifference: ...
def increment(self, increment: int) -> TimestampDifference: ...
class ZonedDateTime(
ToPy[pydt.datetime], ToPyDate, ToPyTime, ToPyDateTime, ToPyTzInfo
):
def __init__(self, timestamp: Timestamp, time_zone: TimeZone) -> None: ...
# =========================================================================
# PYTHON CONVERSIONS
# =========================================================================
@classmethod
def from_pydatetime(
cls: type[ZonedDateTime], dt: pydt.datetime
) -> ZonedDateTime: ...
def to_py(self) -> pydt.datetime: ...
def to_pydate(self) -> pydt.date: ...
def to_pydatetime(self) -> pydt.datetime: ...
def to_pytime(self) -> pydt.time: ...
def to_pytzinfo(self) -> pydt.tzinfo: ...
# =========================================================================
# CLASS METHODS
# =========================================================================
@classmethod
def now(
cls: type[ZonedDateTime], tz: str | None = None
) -> ZonedDateTime: ...
@classmethod
def utcnow(cls: type[ZonedDateTime]) -> ZonedDateTime: ...
@classmethod
def parse(cls: type[ZonedDateTime], s: str) -> ZonedDateTime: ...
@classmethod
def from_rfc2822(cls: type[ZonedDateTime], s: str) -> ZonedDateTime: ...
# =========================================================================
# STRPTIME/STRFTIME
# =========================================================================
@classmethod
def strptime(
cls: type[ZonedDateTime], format: str, input: str
) -> ZonedDateTime: ...
def strftime(self, format: str) -> str: ...
# =========================================================================
# PROPERTIES
# =========================================================================
@property
def year(self) -> int: ...
@property
def month(self) -> int: ...
@property
def day(self) -> int: ...
@property
def hour(self) -> int: ...
@property
def minute(self) -> int: ...
@property
def second(self) -> int: ...
@property
def millisecond(self) -> int: ...
@property
def microsecond(self) -> int: ...
@property
def nanosecond(self) -> int: ...
@property
def subsec_nanosecond(self) -> int: ...
@property
def weekday(self) -> int: ...
# =========================================================================
# STRING
# =========================================================================
def __str__(self) -> str: ...
def string(self) -> str: ...
# =========================================================================
# OPERATORS/DUNDERS
# =========================================================================
def __add__(
self, other: TimeSpan | SignedDuration | Duration
) -> te.Self: ...
def __eq__(self, other: object) -> bool: ...
def __ge__(self, other: ZonedDateTime) -> bool: ...
def __gt__(self, other: ZonedDateTime) -> bool: ...
def __hash__(self) -> int: ...
def __le__(self, other: ZonedDateTime) -> bool: ...
def __lt__(self, other: ZonedDateTime) -> bool: ...
def __ne__(self, other: object) -> bool: ...
def __richcmp__(self, other: ZonedDateTime, op: int) -> bool: ...
# =========================================================================
# OPERATORS/DUNDERS W/ OVERLOADS
# =========================================================================
@t.overload
def __isub__(self, other: ZonedDateTime) -> TimeSpan: ...
@t.overload
def __isub__(
self, other: TimeSpan | SignedDuration | Duration
) -> te.Self: ...
@t.overload
def __sub__(self, other: ZonedDateTime) -> TimeSpan: ...
@t.overload
def __sub__(
self, other: TimeSpan | SignedDuration | Duration
) -> te.Self: ...
# =========================================================================
# INSTANCE METHODS
# =========================================================================
def astimezone(self, tz: str) -> ZonedDateTime: ...
def checked_add(
self, other: TimeSpan | SignedDuration | Duration
) -> te.Self: ...
@t.overload
def checked_sub(self, other: ZonedDateTime) -> TimeSpan: ...
@t.overload
def checked_sub(
self, other: TimeSpan | SignedDuration | Duration
) -> te.Self: ...
def date(self) -> Date: ...
def datetime(self) -> DateTime: ...
def iso_week_date(self) -> ISOWeekDate: ...
def day_of_year(self) -> int: ...
def day_of_year_no_leap(self) -> int | None: ...
def days_in_month(self) -> int: ...
def days_in_year(self) -> int: ...
def duration_since(self, other: ZonedDateTime) -> SignedDuration: ...
def duration_until(self, other: ZonedDateTime) -> SignedDuration: ...
def end_of_day(self) -> ZonedDateTime: ...
def era_year(self) -> tuple[int, t.Literal["CE", "BCE"]]: ...
def first_of_month(self) -> ZonedDateTime: ...
def first_of_year(self) -> ZonedDateTime: ...
def in_leap_year(self) -> bool: ...
def in_tz(self, tz: str) -> te.Self: ...
def intz(self, tz: str) -> te.Self: ...
def inutc(self) -> ZonedDateTime: ...
def last_of_month(self) -> ZonedDateTime: ...
def last_of_year(self) -> ZonedDateTime: ...
def nth_weekday(self, nth: int, weekday: WEEKDAY) -> Date: ...
def nth_weekday_of_month(self, nth: int, weekday: WEEKDAY) -> Date: ...
def offset(self) -> Offset: ...
def round(
self,
smallest: JIFF_UNIT | None = None,
*,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> DateTime: ...
def _round(self, options: ZonedDateTimeRound) -> DateTime: ...
def saturating_add(
self, other: TimeSpan | SignedDuration | Duration
) -> te.Self: ...
@t.overload
def saturating_sub(self, other: ZonedDateTime) -> TimeSpan: ...
@t.overload
def saturating_sub(
self, other: TimeSpan | SignedDuration | Duration
) -> te.Self: ...
def start_of_day(self) -> ZonedDateTime: ...
def time(self) -> Time: ...
def time_zone(self) -> TimeZone: ...
def timestamp(self) -> Timestamp: ...
def timezone(self) -> TimeZone: ...
def to_rfc2822(self) -> str: ...
def tomorrow(self) -> ZonedDateTime: ...
def with_time_zone(self, tz: TimeZone) -> ZonedDateTime: ...
def yesterday(self) -> ZonedDateTime: ...
# =========================================================================
# SINCE/UNTIL
# =========================================================================
def since(
self,
other: ZonedDateTime,
*,
smallest: JIFF_UNIT | None = None,
largest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> TimeSpan: ...
def until(
self,
other: ZonedDateTime,
*,
smallest: JIFF_UNIT | None = None,
largest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> TimeSpan: ...
class ZonedDateTimeDifference:
def __init__(
self,
date: ZonedDateTime,
*,
smallest: JIFF_UNIT | None = None,
largest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int | None = None,
) -> None: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def smallest(self, unit: JIFF_UNIT) -> ZonedDateTimeDifference: ...
def largest(self, unit: JIFF_UNIT) -> ZonedDateTimeDifference: ...
def mode(self, mode: JIFF_ROUND_MODE) -> ZonedDateTimeDifference: ...
def increment(self, increment: int) -> ZonedDateTimeDifference: ...
class ISOWeekDate:
MIN: ISOWeekDate
MAX: ISOWeekDate
ZERO: ISOWeekDate
def __init__(self, year: int, week: int, weekday: WEEKDAY) -> None: ...
# =========================================================================
# OPERATORS/DUNDERS
# =========================================================================
def __eq__(self, other: object) -> bool: ...
def __ne__(self, other: object) -> bool: ...
def __lt__(self, other: ISOWeekDate) -> bool: ...
def __le__(self, other: ISOWeekDate) -> bool: ...
def __gt__(self, other: ISOWeekDate) -> bool: ...
def __ge__(self, other: ISOWeekDate) -> bool: ...
def __hash__(self) -> int: ...
# =========================================================================
# STRING
# =========================================================================
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
# =========================================================================
# CLASS METHODS
# =========================================================================
@classmethod
def from_date(cls: type[ISOWeekDate], date: Date) -> ISOWeekDate: ...
@classmethod
def today(cls: type[ISOWeekDate]) -> ISOWeekDate: ...
# =========================================================================
# PROPERTIES
# =========================================================================
@property
def year(self) -> int: ...
@property
def week(self) -> int: ...
@property
def weekday(self) -> WEEKDAY_INT: ...
# =========================================================================
# INSTANCE METHODS
# =========================================================================
def date(self) -> Date: ...
class TimestampRound:
def __init__(
self,
smallest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int = 1,
) -> None: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def __eq__(self, other: object) -> bool: ...
def mode(self, mode: JIFF_ROUND_MODE) -> TimestampRound: ...
def smallest(self, smallest: JIFF_UNIT) -> TimestampRound: ...
def increment(self, increment: int) -> TimestampRound: ...
def _smallest(self) -> JIFF_UNIT: ...
def _mode(self) -> JIFF_ROUND_MODE: ...
def _increment(self) -> int: ...
def replace(
self,
smallest: JIFF_UNIT | None,
mode: JIFF_ROUND_MODE | None,
increment: int | None,
) -> TimestampRound: ...
class DateTimeRound:
def __init__(
self,
smallest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int = 1,
) -> None: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def __eq__(self, other: object) -> bool: ...
def mode(self, mode: JIFF_ROUND_MODE) -> DateTimeRound: ...
def smallest(self, smallest: JIFF_UNIT) -> DateTimeRound: ...
def increment(self, increment: int) -> DateTimeRound: ...
def _smallest(self) -> JIFF_UNIT: ...
def _mode(self) -> JIFF_ROUND_MODE: ...
def _increment(self) -> int: ...
def replace(
self,
smallest: JIFF_UNIT | None,
mode: JIFF_ROUND_MODE | None,
increment: int | None,
) -> DateTimeRound: ...
class ZonedDateTimeRound:
def __init__(
self,
smallest: JIFF_UNIT | None = None,
mode: JIFF_ROUND_MODE | None = None,
increment: int = 1,
) -> None: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def __eq__(self, other: object) -> bool: ...
def mode(self, mode: JIFF_ROUND_MODE) -> DateTimeRound: ...
def smallest(self, smallest: JIFF_UNIT) -> DateTimeRound: ...
def increment(self, increment: int) -> DateTimeRound: ...
def _smallest(self) -> JIFF_UNIT: ...
def _mode(self) -> JIFF_ROUND_MODE: ...
def _increment(self) -> int: ...
def replace(
self,
smallest: JIFF_UNIT | None,
mode: JIFF_ROUND_MODE | None,
increment: int | None,
) -> DateTimeRound: ...
class Offset(ToPy[pydt.tzinfo], ToPyTzInfo):
MIN: Offset
MAX: Offset
UTC: Offset
ZERO: Offset
def __init__(
self, hours: int | None = None, seconds: int | None = None
) -> None: ...
# =========================================================================
# STRING
# =========================================================================
def string(self) -> str: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
# =========================================================================
# OPERATORS/DUNDERS
# =========================================================================
def __neg__(self) -> Offset: ...
def __eq__(self, other: object) -> bool: ...
def __ne__(self, other: object) -> bool: ...
def __lt__(self, other: Offset) -> bool: ...
def __le__(self, other: Offset) -> bool: ...
def __gt__(self, other: Offset) -> bool: ...
def __ge__(self, other: Offset) -> bool: ...
def __hash__(self) -> int: ...
# =========================================================================
# PYTHON CONVERSIONS
# =========================================================================
# __FROM__
@classmethod
def from_pytzinfo(cls: type[Offset], tz: pydt.tzinfo) -> Offset: ...
# __TO__
def to_py(self) -> pydt.tzinfo: ...
def to_pytzinfo(self) -> pydt.tzinfo: ...
# =========================================================================
# PROPERTIES
# =========================================================================
@property
def seconds(self) -> int: ...
@property
def is_negative(self) -> bool: ...
@property
def is_positive(self) -> bool: ...
# =========================================================================
# FROM
# =========================================================================
@classmethod
def utc(cls: type[Offset]) -> Offset: ...
@classmethod
def from_hours(cls: type[Offset], hours: int) -> Offset: ...
@classmethod
def from_seconds(cls: type[Offset], seconds: int) -> Offset: ...
# =========================================================================
# TO
# =========================================================================
def to_datetime(self, timestamp: Timestamp) -> DateTime: ...
def to_timestamp(self, datetime: DateTime) -> Timestamp: ...
def to_timezone(self) -> TimeZone: ...
# =========================================================================
# INSTANCE METHODS
# =========================================================================
def checked_add(
self, other: Duration | SignedDuration | TimeSpan
) -> Offset: ...
def checked_sub(
self, other: Duration | SignedDuration | TimeSpan
) -> Offset: ...
def duration_since(self, other: Offset) -> SignedDuration: ...
def duration_until(self, other: Offset) -> SignedDuration: ...
def negate(self) -> Offset: ...
def saturating_add(
self, other: Duration | SignedDuration | TimeSpan
) -> Offset: ...
def saturating_sub(
self, other: Duration | SignedDuration | TimeSpan
) -> Offset: ...
def since(self, other: Offset) -> TimeSpan: ...
def until(self, other: Offset) -> TimeSpan: ...
class JiffSeries(
t.Generic[T],
):
def __iter__(self) -> t.Iterator[T]: ...
def __next__(self) -> T: ...
def take(self, n: int) -> list[T]: ...
def date(year: int, month: int, day: int) -> Date: ...
def time(
hour: int = 0, minute: int = 0, second: int = 0, nanosecond: int = 0
) -> Time: ...
def datetime(
year: int,
month: int,
day: int,
hour: int = 0,
minute: int = 0,
second: int = 0,
nanosecond: int = 0,
) -> DateTime: ...
def timespan(
*,
years: int = 0,
months: int = 0,
weeks: int = 0,
days: int = 0,
hours: int = 0,
minutes: int = 0,
seconds: int = 0,
milliseconds: int = 0,
microseconds: int = 0,
nanoseconds: int = 0,
unchecked: bool = False,
) -> TimeSpan: ...
def offset(hours: int) -> Offset: ...
# =============================================================================
# TIMEZONE-DATABASE
# =============================================================================
class TimeZoneDatabase:
def __init__(self) -> None:
"""Defaults to using the `self.from_env`"""
@t.overload
def get(self, name: str, err: t.Literal[False]) -> TimeZone | None:
"""Returns TimeZone or None if the timezone is not found"""
@t.overload
def get(self, name: str, err: t.Literal[True] = True) -> TimeZone:
"""Returns TimeZone, if not found raises a ValueError"""
def available(self) -> list[str]: ...
def __getitem__(self, name: str) -> TimeZone: ...
def __len__(self) -> int: ...
def is_definitively_empty(self) -> bool: ...
@classmethod
def from_env(cls) -> TimeZoneDatabase: ...
@classmethod
def from_dir(cls, path: str) -> TimeZoneDatabase: ...
@classmethod
def from_concatenated_path(cls, path: str) -> TimeZoneDatabase: ...
ry.ryo3._jiter
from __future__ import annotations
import typing as t
import typing_extensions as te
from ry._types import Buffer
# =============================================================================
# JSON
# =============================================================================
JsonPrimitive = None | bool | int | float | str
JsonValue = (
JsonPrimitive
| dict[str, JsonPrimitive | JsonValue]
| list[JsonPrimitive | JsonValue]
)
class JsonParseKwargs(t.TypedDict, total=False):
allow_inf_nan: bool
"""Allow parsing of `Infinity`, `-Infinity`, `NaN` ~ default: True"""
cache_mode: t.Literal[True, False, "all", "keys", "none"]
"""Cache mode for JSON parsing ~ default: `all` """
partial_mode: t.Literal[True, False, "off", "on", "trailing-strings"]
"""Partial mode for JSON parsing ~ default: False"""
catch_duplicate_keys: bool
"""Catch duplicate keys in JSON objects ~ default: False"""
float_mode: t.Literal["float", "decimal", "lossless-float"] | bool
"""Mode for parsing JSON floats ~ default: False"""
def parse_json(
data: Buffer | bytes | str,
/,
**kwargs: te.Unpack[JsonParseKwargs],
) -> JsonValue: ...
def parse_json_bytes(
data: bytes,
/,
**kwargs: te.Unpack[JsonParseKwargs],
) -> JsonValue: ...
def json_cache_clear() -> None: ...
def json_cache_usage() -> int: ...
ry.ryo3._quick_maths
"""ryo3-quick-maths types"""
from __future__ import annotations
import typing as t
def quick_maths() -> t.Literal[3]:
"""Performs quick-maths
Implements the algorithm for performing "quick-maths" as described by
Big Shaq in his PHD thesis, 2017, in which he states:
> "2 plus 2 is 4, minus one that's 3, quick maths." (Big Shaq et al., 2017)
Reference:
https://youtu.be/3M_5oYU-IsU?t=60
Example:
>>> import ry
>>> result = ry.quick_maths()
>>> assert result == 3
NOTE: THIS IS FROM MY TEMPLATE RY03-MODULE
"""
ry.ryo3._regex
"""ryo3-regex types"""
from __future__ import annotations
# =============================================================================
# Regex
# =============================================================================
class Regex:
def __init__(
self,
pattern: str,
*,
case_insensitive: bool = False,
crlf: bool = False,
dot_matches_new_line: bool = False,
ignore_whitespace: bool = False,
line_terminator: str | None = None,
multi_line: bool = False,
octal: bool = False,
size_limit: int | None = None,
swap_greed: bool = False,
unicode: bool = False,
) -> None: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def is_match(self, string: str) -> bool: ...
ry.ryo3._reqwest
import typing as t
from http import HTTPStatus
import ry
if t.TYPE_CHECKING:
from ry.http import Headers
from ry.ryo3 import URL, Duration
class HttpClient:
def __init__(
self,
*,
headers: dict[str, str] | None = None,
user_agent: str | None = None, # default ~ 'ry-reqwest/<VERSION> ...'
timeout: Duration | None = None,
connect_timeout: Duration | None = None,
read_timeout: Duration | None = None,
gzip: bool = True,
brotli: bool = True,
deflate: bool = True,
) -> None: ...
async def get(
self, url: str | URL, *, headers: dict[str, str] | None = None
) -> Response: ...
async def post(
self,
url: str | URL,
*,
body: bytes | None = None,
headers: dict[str, str] | None = None,
) -> Response: ...
async def put(
self,
url: str | URL,
*,
body: bytes | None = None,
headers: dict[str, str] | None = None,
) -> Response: ...
async def delete(
self, url: str | URL, *, headers: dict[str, str] | None = None
) -> Response: ...
async def patch(
self,
url: str | URL,
*,
body: bytes | None = None,
headers: dict[str, str] | None = None,
) -> Response: ...
async def head(
self, url: str | URL, *, headers: dict[str, str] | None = None
) -> Response: ...
async def fetch(
self,
url: str | URL,
*,
method: str = "GET",
body: bytes | None = None,
headers: dict[str, str] | None = None,
) -> Response: ...
class ReqwestError(Exception):
def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def __dbg__(self) -> str: ...
def is_body(self) -> bool: ...
def is_builder(self) -> bool: ...
def is_connect(self) -> bool: ...
def is_decode(self) -> bool: ...
def is_redirect(self) -> bool: ...
def is_request(self) -> bool: ...
def is_status(self) -> bool: ...
def is_timeout(self) -> bool: ...
def status(self) -> HTTPStatus | None: ...
def url(self) -> URL | None: ...
class Response:
status_code: int
@property
def headers(self) -> Headers: ...
async def text(self) -> str: ...
async def json(self) -> t.Any: ...
async def bytes(self) -> ry.Bytes: ...
def bytes_stream(self) -> ResponseStream: ...
class ResponseStream:
def __aiter__(self) -> ResponseStream: ...
async def __anext__(self) -> ry.Bytes: ...
async def fetch(
url: str | URL,
*,
client: HttpClient | None = None,
method: str = "GET",
body: bytes | None = None,
headers: dict[str, str] | None = None,
) -> Response: ...
ry.ryo3._same_file
"""ryo3-same-file types"""
from __future__ import annotations
from os import PathLike
def is_same_file(a: PathLike[str], b: PathLike[str]) -> bool: ...
ry.ryo3._shlex
"""ryo3-shlex types"""
from __future__ import annotations
def shplit(s: str) -> list[str]:
"""shlex::split wrapper much like python's stdlib shlex.split but faster"""
...
ry.ryo3._size
from __future__ import annotations
from typing import Literal
FORMAT_SIZE_BASE = Literal[2, 10] # default=2
FORMAT_SIZE_STYLE = Literal[ # default="default"
"default",
"abbreviated",
"abbreviated_lowercase",
"abbreviated-lowercase",
"full",
"full-lowercase",
"full_lowercase",
]
def fmt_size(
n: int,
*,
base: FORMAT_SIZE_BASE | None = 2,
style: FORMAT_SIZE_STYLE | None = "default",
) -> str:
"""Return human-readable string representation of bytes-size."""
def parse_size(s: str) -> int:
"""Return integer representation of human-readable bytes-size string.
Raises:
ValueError: If string is not a valid human-readable bytes-size string.
"""
class SizeFormatter:
"""Human-readable bytes-size formatter."""
def __init__(
self,
base: FORMAT_SIZE_BASE | None = 2,
style: FORMAT_SIZE_STYLE | None = "default",
) -> None:
"""Initialize human-readable bytes-size formatter."""
def format(self, n: int) -> str:
"""Return human-readable string representation of bytes-size."""
def __call__(self, n: int) -> str:
"""Return human-readable string representation of bytes-size."""
def __repr__(self) -> str: ...
def __str__(self) -> str: ...
class Size:
"""Bytes-size object."""
def __init__(self, size: int) -> None: ...
def __int__(self) -> int: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def __hash__(self) -> int: ...
def __abs__(self) -> Size: ...
def __neg__(self) -> Size: ...
def __eq__(self, other: object) -> bool: ...
def __ne__(self, other: object) -> bool: ...
def __lt__(self, other: Size | int | float) -> bool: ...
def __le__(self, other: Size | int | float) -> bool: ...
def __gt__(self, other: Size | int | float) -> bool: ...
def __ge__(self, other: Size | int | float) -> bool: ...
def __bool__(self) -> bool: ...
def __pos__(self) -> Size: ...
def __invert__(self) -> Size: ...
def __add__(self, other: Size | int | float) -> Size: ...
def __sub__(self, other: Size | int | float) -> Size: ...
def __mul__(self, other: Size | int | float) -> Size: ...
def __rmul__(self, other: Size | int | float) -> Size: ...
@property
def bytes(self) -> int: ...
def format(
self,
base: FORMAT_SIZE_BASE | None = 2,
style: FORMAT_SIZE_STYLE | None = "default",
) -> str: ...
# =========================================================================
# CLASS-METHODS
# =========================================================================
# -------------------------------------------------------------------------
# PARSING
# -------------------------------------------------------------------------
@classmethod
def parse(cls: type[Size], size: str) -> Size: ...
@classmethod
def from_str(cls: type[Size], size: str) -> Size: ...
# -------------------------------------------------------------------------
# BYTES
# -------------------------------------------------------------------------
@classmethod
def from_bytes(cls: type[Size], size: int | float) -> Size: ...
# -------------------------------------------------------------------------
# KILOBYTES
# -------------------------------------------------------------------------
@classmethod
def from_kb(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_kib(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_kibibytes(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_kilobytes(cls: type[Size], size: int | float) -> Size: ...
# -------------------------------------------------------------------------
# MEGABYTES
# -------------------------------------------------------------------------
@classmethod
def from_mb(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_mebibytes(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_megabytes(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_mib(cls: type[Size], size: int | float) -> Size: ...
# -------------------------------------------------------------------------
# GIGABYTES
# -------------------------------------------------------------------------
@classmethod
def from_gb(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_gib(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_gibibytes(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_gigabytes(cls: type[Size], size: int | float) -> Size: ...
# -------------------------------------------------------------------------
# TERABYTES
# -------------------------------------------------------------------------
@classmethod
def from_tb(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_tebibytes(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_terabytes(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_tib(cls: type[Size], size: int | float) -> Size: ...
# -------------------------------------------------------------------------
# PETABYTES
# -------------------------------------------------------------------------
@classmethod
def from_pb(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_pebibytes(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_petabytes(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_pib(cls: type[Size], size: int | float) -> Size: ...
# -------------------------------------------------------------------------
# EXABYTES
# -------------------------------------------------------------------------
@classmethod
def from_eb(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_eib(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_exabytes(cls: type[Size], size: int | float) -> Size: ...
@classmethod
def from_exbibytes(cls: type[Size], size: int | float) -> Size: ...
ry.ryo3._sqlformat
from __future__ import annotations
import typing as t
# =============================================================================
# SQLFORMAT
# =============================================================================
SqlfmtParamValue = str | int | float | bool
TSqlfmtParamValue_co = t.TypeVar(
"TSqlfmtParamValue_co", bound=SqlfmtParamValue, covariant=True
)
SqlfmtParamsLike = (
dict[str, TSqlfmtParamValue_co]
| t.Sequence[tuple[str, TSqlfmtParamValue_co]]
| t.Sequence[TSqlfmtParamValue_co]
)
class SqlfmtQueryParams:
def __init__(
self, params: SqlfmtParamsLike[TSqlfmtParamValue_co]
) -> None: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def sqlfmt_params(
params: SqlfmtParamsLike[TSqlfmtParamValue_co] | SqlfmtQueryParams,
) -> SqlfmtQueryParams: ...
def sqlfmt(
sql: str,
params: SqlfmtParamsLike[TSqlfmtParamValue_co]
| SqlfmtQueryParams
| None = None,
*,
indent: int = 2, # -1 or any negative value will use tabs
uppercase: bool | None = True,
lines_between_statements: int = 1,
) -> str: ...
ry.ryo3._std
"""ryo3-std types"""
from __future__ import annotations
import datetime as pydt
import typing as t
from ry import Bytes, FsPath
from ry._types import Buffer, FsPathLike
# =============================================================================
# STD::TIME
# =============================================================================
class Duration:
ZERO: Duration
MIN: Duration
MAX: Duration
NANOSECOND: Duration
MICROSECOND: Duration
MILLISECOND: Duration
SECOND: Duration
def __init__(self, secs: int = 0, nanos: int = 0) -> None: ...
def __eq__(self, other: object) -> bool: ...
def __ne__(self, other: object) -> bool: ...
def __lt__(self, other: Duration) -> bool: ...
def __le__(self, other: Duration) -> bool: ...
def __gt__(self, other: Duration) -> bool: ...
def __ge__(self, other: Duration) -> bool: ...
def __hash__(self) -> int: ...
def __richcmp__(
self, other: Duration | pydt.timedelta, op: int
) -> bool: ...
def __str__(self) -> str: ...
def abs_diff(self, other: Duration) -> Duration: ...
def sleep(self) -> None: ...
# =========================================================================
# PYTHON_CONVERSIONS
# =========================================================================
@classmethod
def from_pytimedelta(
cls: type[Duration], td: pydt.timedelta
) -> Duration: ...
def to_pytimedelta(self) -> pydt.timedelta: ...
# =========================================================================
# PROPERTIES
# =========================================================================
@property
def is_zero(self) -> bool: ...
@property
def nanos(self) -> int: ...
@property
def secs(self) -> int: ...
@property
def days(self) -> int: ...
@property
def seconds(self) -> int: ...
@property
def microseconds(self) -> int: ...
@property
def subsec_micros(self) -> int: ...
@property
def subsec_millis(self) -> int: ...
@property
def subsec_nanos(self) -> int: ...
# =========================================================================
# CLASSMETHODS
# =========================================================================
@classmethod
def from_hours(cls, hours: int) -> Duration: ...
@classmethod
def from_micros(cls, micros: int) -> Duration: ...
@classmethod
def from_millis(cls, millis: int) -> Duration: ...
@classmethod
def from_mins(cls, mins: int) -> Duration: ...
@classmethod
def from_nanos(cls, nanos: int) -> Duration: ...
@classmethod
def from_secs(cls, secs: int) -> Duration: ...
@classmethod
def from_secs_f32(cls, secs: float) -> Duration: ...
@classmethod
def from_secs_f64(cls, secs: float) -> Duration: ...
@classmethod
def from_days(cls, days: int) -> Duration: ...
@classmethod
def from_weeks(cls, weeks: int) -> Duration: ...
def as_micros(self) -> int: ...
def as_millis(self) -> int: ...
def as_nanos(self) -> int: ...
def as_secs(self) -> int: ...
def as_secs_f32(self) -> float: ...
def as_secs_f64(self) -> float: ...
# =========================================================================
# NOT IMPLEMENTED
# =========================================================================
def checked_add(self, other: Duration) -> Duration | None: ...
def checked_div(self, other: Duration) -> Duration | None: ...
def checked_mul(self, other: Duration) -> Duration | None: ...
def checked_sub(self, other: Duration) -> Duration | None: ...
def div_duration_f32(self, other: Duration) -> float: ...
def div_duration_f64(self, other: Duration) -> float: ...
def div_f32(self, other: float) -> Duration: ...
def div_f64(self, other: float) -> Duration: ...
def mul_f32(self, other: float) -> Duration: ...
def mul_f64(self, other: float) -> Duration: ...
def saturating_add(self, other: Duration) -> Duration: ...
def saturating_mul(self, other: Duration) -> Duration: ...
def saturating_sub(self, other: Duration) -> Duration: ...
class Instant:
def __init__(self) -> None: ...
@classmethod
def now(cls) -> Instant: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def __eq__(self, other: object) -> bool: ...
def __ne__(self, other: object) -> bool: ...
def __lt__(self, other: Instant) -> bool: ...
def __le__(self, other: Instant) -> bool: ...
def __gt__(self, other: Instant) -> bool: ...
def __ge__(self, other: Instant) -> bool: ...
def __hash__(self) -> int: ...
def __add__(self, other: Duration) -> Instant: ...
@t.overload
def __sub__(self, other: Duration) -> Instant: ...
@t.overload
def __sub__(self, other: Instant) -> Duration: ...
# =========================================================================
# INSTANCE METHODS
# =========================================================================
def checked_add(self, other: Duration) -> Instant | None: ...
def checked_duration_since(self, earlier: Instant) -> Duration | None: ...
def checked_sub(self, other: Duration) -> Instant | None: ...
def duration_since(self, earlier: Instant) -> Duration: ...
def elapsed(self) -> Duration: ...
def saturating_duration_since(self, earlier: Instant) -> Duration: ...
def instant() -> Instant: ...
def sleep(seconds: float) -> float: ...
# =============================================================================
# STD::FS
# =============================================================================
class FileType:
def __repr__(self) -> str: ...
@property
def is_dir(self) -> bool: ...
@property
def is_file(self) -> bool: ...
@property
def is_symlink(self) -> bool: ...
class Metadata:
def __repr__(self) -> str: ...
@property
def file_type(self) -> FileType: ...
@property
def len(self) -> int: ...
@property
def is_empty(self) -> bool: ...
@property
def modified(self) -> pydt.datetime: ...
@property
def accessed(self) -> pydt.datetime: ...
@property
def created(self) -> pydt.datetime: ...
@property
def is_dir(self) -> bool: ...
@property
def is_file(self) -> bool: ...
@property
def is_symlink(self) -> bool: ...
# =============================================================================
# STD::FS ~ functions
# =============================================================================
def read(path: FsPathLike) -> Bytes: ...
def read_bytes(path: FsPathLike) -> bytes: ...
def read_text(path: FsPathLike) -> str: ...
def read_stream(
path: FsPathLike,
chunk_size: int = 65536,
*,
offset: int = 0,
) -> t.Iterator[Bytes]: ...
def write(path: FsPathLike, data: Buffer | str) -> int: ...
def write_bytes(path: FsPathLike, data: bytes) -> int: ...
def write_text(path: FsPathLike, data: str) -> int: ...
def canonicalize(path: FsPathLike) -> FsPath: ...
def copy(from_path: FsPathLike, to_path: FsPathLike) -> int: ...
def create_dir(path: FsPathLike) -> None: ...
def create_dir_all(path: FsPathLike) -> None: ...
def exists(path: FsPathLike) -> bool: ...
def is_dir(path: FsPathLike) -> bool: ...
def is_file(path: FsPathLike) -> bool: ...
def is_symlink(path: FsPathLike) -> bool: ...
def metadata(path: FsPathLike) -> Metadata: ...
def remove_dir(path: FsPathLike) -> None: ...
def remove_dir_all(path: FsPathLike) -> None: ...
def remove_file(path: FsPathLike) -> None: ...
def rename(from_path: FsPathLike, to_path: FsPathLike) -> None: ...
ry.ryo3._tokio
"""ryo3-tokio types"""
from __future__ import annotations
from typing import NoReturn
from ry import Bytes
from ry._types import Buffer, FsPathLike
# =============================================================================
# FS
# =============================================================================
async def copy_async(src: FsPathLike, dst: FsPathLike) -> None: ...
async def create_dir_async(path: FsPathLike) -> None: ...
async def metadata_async(path: FsPathLike) -> None: ...
async def read_async(path: FsPathLike) -> Bytes: ...
async def read_dir_async(path: FsPathLike) -> NoReturn: ...
async def remove_dir_async(path: FsPathLike) -> None: ...
async def remove_file_async(path: FsPathLike) -> None: ...
async def rename_async(src: FsPathLike, dst: FsPathLike) -> None: ...
async def write_async(path: FsPathLike, data: Buffer) -> None: ...
# =============================================================================
# SLEEP
# =============================================================================
async def sleep_async(seconds: float) -> float: ...
async def asleep(seconds: float) -> float:
"""Alias for sleep_async"""
...
ry.ryo3._unindent
"""ryo3-unindent types"""
from __future__ import annotations
def unindent(string: str) -> str: ...
def unindent_bytes(string: bytes) -> bytes: ...
ry.ryo3._url
from __future__ import annotations
from ipaddress import IPv4Address
class URL:
def __init__(
self, url: str | URL, *, params: dict[str, str] | None = None
) -> None: ...
# =========================================================================
# CLASSMETHODS
# =========================================================================
@classmethod
def parse(cls, url: str) -> URL: ...
@classmethod
def parse_with_params(cls, url: str, params: dict[str, str]) -> URL: ...
@classmethod
def from_directory_path(cls, path: str) -> URL: ...
# =========================================================================
# STRING
# =========================================================================
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def __fspath__(self) -> str: ...
# =========================================================================
# OPERATORS/DUNDER
# =========================================================================
def __eq__(self, other: object) -> bool: ...
def __ge__(self, other: URL) -> bool: ...
def __gt__(self, other: URL) -> bool: ...
def __hash__(self) -> int: ...
def __le__(self, other: URL) -> bool: ...
def __lt__(self, other: URL) -> bool: ...
def __ne__(self, other: object) -> bool: ...
def __rtruediv__(self, relative: str) -> URL: ...
def __truediv__(self, relative: str) -> URL: ...
# =========================================================================
# PROPERTIES
# =========================================================================
@property
def authority(self) -> str: ...
@property
def fragment(self) -> str | None: ...
@property
def host(self) -> str | None: ...
@property
def host_str(self) -> str | None: ...
@property
def netloc(self) -> str: ...
@property
def password(self) -> str | None: ...
@property
def path(self) -> str: ...
@property
def path_segments(self) -> tuple[str, ...]: ...
@property
def port(self) -> int | None: ...
@property
def port_or_known_default(self) -> int | None: ...
@property
def query(self) -> str | None: ...
@property
def query_pairs(self) -> list[tuple[str, str]]: ...
@property
def scheme(self) -> str: ...
@property
def username(self) -> str: ...
@property
def origin(self) -> str: ...
# =========================================================================
# INSTANCE METHODS
# =========================================================================
def has_authority(self) -> bool: ...
def has_host(self) -> bool: ...
def is_special(self) -> bool: ...
def join(self, *parts: str) -> URL: ...
def to_filepath(self) -> str: ...
def replace_fragment(self, fragment: str | None = None) -> URL: ...
def replace_host(self, host: str | None = None) -> URL: ...
def replace_ip_host(self, host: IPv4Address | IPv4Address) -> URL: ...
def replace_password(self, password: str | None = None) -> URL: ...
def replace_path(self, path: str) -> URL: ...
def replace_port(self, port: int | None = None) -> URL: ...
def replace_query(self, query: str | None = None) -> URL: ...
def replace_scheme(self, scheme: str) -> URL: ...
def replace_username(self, username: str) -> URL: ...
def socket_addrs(self) -> None: ...
def replace(
self,
*,
fragment: str | None = None,
host: str | None = None,
ip_host: IPv4Address | None = None,
password: str | None = None,
path: str | None = None,
port: int | None = None,
query: str | None = None,
scheme: str | None = None,
username: str | None = None,
) -> URL: ...
ry.ryo3._walkdir
"""ryo3-walkdir types"""
from __future__ import annotations
import typing as t
from os import PathLike
from ry import FileType, FsPath, Glob, GlobSet, Globster
class WalkDirEntry:
def __fspath__(self) -> str: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
@property
def path(self) -> FsPath: ...
@property
def file_name(self) -> str: ...
@property
def depth(self) -> int: ...
@property
def path_is_symlink(self) -> bool: ...
@property
def file_type(self) -> FileType: ...
@property
def is_dir(self) -> bool: ...
@property
def is_file(self) -> bool: ...
@property
def is_symlink(self) -> bool: ...
@property
def len(self) -> int: ...
class WalkdirGen:
"""walkdir::Walkdir iterable wrapper"""
def __next__(self) -> str: ...
def __iter__(self) -> t.Iterator[str]: ...
def collect(self) -> list[str]: ...
def take(self, n: int) -> list[str]: ...
def __str__(self) -> str: ...
def walkdir(
path: str | PathLike[str] | None = None,
*,
files: bool = True,
dirs: bool = True,
contents_first: bool = False,
min_depth: int = 0,
max_depth: int | None = None,
follow_links: bool = False,
same_file_system: bool = False,
glob: Glob | GlobSet | Globster | t.Sequence[str] | str | None = None,
) -> WalkdirGen: ...
ry.ryo3._which
"""ryo3-which types"""
from __future__ import annotations
from pathlib import Path
from ry.ryo3._regex import Regex
def which(cmd: str, path: None | str = None) -> Path | None: ...
def which_all(cmd: str, path: None | str = None) -> list[Path]: ...
def which_re(regex: str | Regex, path: None | str = None) -> list[Path]: ...
ry.dirs
def audio() -> str | None: ...
def audio_dir() -> str | None: ...
def cache() -> str | None: ...
def cache_dir() -> str | None: ...
def config() -> str | None: ...
def config_dir() -> str | None: ...
def config_local() -> str | None: ...
def config_local_dir() -> str | None: ...
def data() -> str | None: ...
def data_dir() -> str | None: ...
def data_local() -> str | None: ...
def data_local_dir() -> str | None: ...
def desktop() -> str | None: ...
def desktop_dir() -> str | None: ...
def document() -> str | None: ...
def document_dir() -> str | None: ...
def download() -> str | None: ...
def download_dir() -> str | None: ...
def executable() -> str | None: ...
def executable_dir() -> str | None: ...
def font() -> str | None: ...
def font_dir() -> str | None: ...
def home() -> str | None: ...
def home_dir() -> str | None: ...
def picture() -> str | None: ...
def picture_dir() -> str | None: ...
def preference() -> str | None: ...
def preference_dir() -> str | None: ...
def public() -> str | None: ...
def public_dir() -> str | None: ...
def runtime() -> str | None: ...
def runtime_dir() -> str | None: ...
def state() -> str | None: ...
def state_dir() -> str | None: ...
def template() -> str | None: ...
def template_dir() -> str | None: ...
def video() -> str | None: ...
def video_dir() -> str | None: ...
ry.http
from __future__ import annotations
import typing as t
class Headers:
"""python-ryo3-http `http::HeadersMap` wrapper"""
def __init__(self, headers: dict[str, str | t.Sequence[str]]) -> None: ...
# =========================================================================
# STRING
# =========================================================================
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def __dbg__(self) -> str: ...
# =========================================================================
# MAGIC METHODS
# =========================================================================
def __len__(self) -> int: ...
def __getitem__(self, key: str) -> str: ...
def __setitem__(self, key: str, value: str) -> None: ...
def __delitem__(self, key: str) -> None: ...
def __contains__(self, key: str) -> bool: ...
def __or__(self, other: Headers | dict[str, str]) -> Headers: ...
def asdict(self) -> dict[str, str | t.Sequence[str]]: ...
# =========================================================================
# INSTANCE METHODS
# =========================================================================
def append(self, key: str, value: str) -> None: ...
def get(self, key: str) -> str | None: ...
def get_all(self, key: str) -> list[str]: ...
def keys_len(self) -> int: ...
def len(self) -> int: ...
def remove(self, key: str) -> None: ...
def clear(self) -> None: ...
def pop(self, key: str) -> str: ...
def keys(self) -> list[str]: ...
def update(self, headers: Headers | dict[str, str]) -> None: ...
class HttpStatus:
def __init__(self, code: int) -> None: ...
def __int__(self) -> int: ...
def __bool__(self) -> bool: ...
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
def __hash__(self) -> int: ...
def __eq__(self, other: object) -> bool: ...
def __ne__(self, other: object) -> bool: ...
def __lt__(self, other: HttpStatus | int) -> bool: ...
def __le__(self, other: HttpStatus | int) -> bool: ...
def __gt__(self, other: HttpStatus | int) -> bool: ...
def __ge__(self, other: HttpStatus | int) -> bool: ...
def reason(self) -> str: ...
def is_informational(self) -> bool: ...
def is_success(self) -> bool: ...
def is_redirect(self) -> bool: ...
def is_client_error(self) -> bool: ...
def is_server_error(self) -> bool: ...
def is_ok(self) -> bool: ...
@property
def ok(self) -> bool: ...
# =========================================================================
# CONST STATUS CODES
# =========================================================================
CONTINUE: HttpStatus # 100 ~ Continue
SWITCHING_PROTOCOLS: HttpStatus # 101 ~ Switching Protocols
PROCESSING: HttpStatus # 102 ~ Processing
OK: HttpStatus # 200 ~ OK
CREATED: HttpStatus # 201 ~ Created
ACCEPTED: HttpStatus # 202 ~ Accepted
NON_AUTHORITATIVE_INFORMATION: (
HttpStatus # 203 ~ Non Authoritative Information
)
NO_CONTENT: HttpStatus # 204 ~ No Content
RESET_CONTENT: HttpStatus # 205 ~ Reset Content
PARTIAL_CONTENT: HttpStatus # 206 ~ Partial Content
MULTI_STATUS: HttpStatus # 207 ~ Multi-Status
ALREADY_REPORTED: HttpStatus # 208 ~ Already Reported
IM_USED: HttpStatus # 226 ~ IM Used
MULTIPLE_CHOICES: HttpStatus # 300 ~ Multiple Choices
MOVED_PERMANENTLY: HttpStatus # 301 ~ Moved Permanently
FOUND: HttpStatus # 302 ~ Found
SEE_OTHER: HttpStatus # 303 ~ See Other
NOT_MODIFIED: HttpStatus # 304 ~ Not Modified
USE_PROXY: HttpStatus # 305 ~ Use Proxy
TEMPORARY_REDIRECT: HttpStatus # 307 ~ Temporary Redirect
PERMANENT_REDIRECT: HttpStatus # 308 ~ Permanent Redirect
BAD_REQUEST: HttpStatus # 400 ~ Bad Request
UNAUTHORIZED: HttpStatus # 401 ~ Unauthorized
PAYMENT_REQUIRED: HttpStatus # 402 ~ Payment Required
FORBIDDEN: HttpStatus # 403 ~ Forbidden
NOT_FOUND: HttpStatus # 404 ~ Not Found
METHOD_NOT_ALLOWED: HttpStatus # 405 ~ Method Not Allowed
NOT_ACCEPTABLE: HttpStatus # 406 ~ Not Acceptable
PROXY_AUTHENTICATION_REQUIRED: (
HttpStatus # 407 ~ Proxy Authentication Required
)
REQUEST_TIMEOUT: HttpStatus # 408 ~ Request Timeout
CONFLICT: HttpStatus # 409 ~ Conflict
GONE: HttpStatus # 410 ~ Gone
LENGTH_REQUIRED: HttpStatus # 411 ~ Length Required
PRECONDITION_FAILED: HttpStatus # 412 ~ Precondition Failed
PAYLOAD_TOO_LARGE: HttpStatus # 413 ~ Payload Too Large
URI_TOO_LONG: HttpStatus # 414 ~ URI Too Long
UNSUPPORTED_MEDIA_TYPE: HttpStatus # 415 ~ Unsupported Media Type
RANGE_NOT_SATISFIABLE: HttpStatus # 416 ~ Range Not Satisfiable
EXPECTATION_FAILED: HttpStatus # 417 ~ Expectation Failed
IM_A_TEAPOT: HttpStatus # 418 ~ I'm a teapot
MISDIRECTED_REQUEST: HttpStatus # 421 ~ Misdirected Request
UNPROCESSABLE_ENTITY: HttpStatus # 422 ~ Unprocessable Entity
LOCKED: HttpStatus # 423 ~ Locked
FAILED_DEPENDENCY: HttpStatus # 424 ~ Failed Dependency
TOO_EARLY: HttpStatus # 425 ~ Too Early
UPGRADE_REQUIRED: HttpStatus # 426 ~ Upgrade Required
PRECONDITION_REQUIRED: HttpStatus # 428 ~ Precondition Required
TOO_MANY_REQUESTS: HttpStatus # 429 ~ Too Many Requests
REQUEST_HEADER_FIELDS_TOO_LARGE: (
HttpStatus # 431 ~ Request Header Fields Too Large
)
UNAVAILABLE_FOR_LEGAL_REASONS: (
HttpStatus # 451 ~ Unavailable For Legal Reasons
)
INTERNAL_SERVER_ERROR: HttpStatus # 500 ~ Internal Server Error
NOT_IMPLEMENTED: HttpStatus # 501 ~ Not Implemented
BAD_GATEWAY: HttpStatus # 502 ~ Bad Gateway
SERVICE_UNAVAILABLE: HttpStatus # 503 ~ Service Unavailable
GATEWAY_TIMEOUT: HttpStatus # 504 ~ Gateway Timeout
HTTP_VERSION_NOT_SUPPORTED: HttpStatus # 505 ~ HTTP Version Not Supported
VARIANT_ALSO_NEGOTIATES: HttpStatus # 506 ~ Variant Also Negotiates
INSUFFICIENT_STORAGE: HttpStatus # 507 ~ Insufficient Storage
LOOP_DETECTED: HttpStatus # 508 ~ Loop Detected
NOT_EXTENDED: HttpStatus # 510 ~ Not Extended
NETWORK_AUTHENTICATION_REQUIRED: (
HttpStatus # 511 ~ Network Authentication Required
)
ry.xxhash
from __future__ import annotations
import typing as t
from ry._types import Buffer
@t.final
class Xxh32:
name: t.Literal["xxh32"]
def __init__(self, input: Buffer = ..., seed: int | None = ...) -> None: ...
def update(self, input: Buffer) -> None: ...
def digest(self) -> bytes: ...
def hexdigest(self) -> str: ...
def intdigest(self) -> int: ...
def copy(self) -> Xxh32: ...
def reset(self, seed: int | None = ...) -> None: ...
@property
def seed(self) -> int: ...
@t.final
class Xxh64:
name: t.Literal["xxh64"]
def __init__(
self, input: Buffer | None = None, seed: int | None = ...
) -> None: ...
def update(self, input: Buffer) -> None: ...
def digest(self) -> bytes: ...
def hexdigest(self) -> str: ...
def intdigest(self) -> int: ...
def copy(self) -> Xxh32: ...
def reset(self, seed: int | None = ...) -> None: ...
@property
def seed(self) -> int: ...
@t.final
class Xxh3:
name: t.Literal["xxh3"]
def __init__(
self,
input: Buffer = ...,
seed: int | None = ...,
secret: bytes | None = ...,
) -> None: ...
def update(self, input: Buffer) -> None: ...
def digest(self) -> bytes: ...
def hexdigest(self) -> str: ...
def intdigest(self) -> int: ...
@property
def seed(self) -> int: ...
def digest128(self) -> bytes: ...
def hexdigest128(self) -> str: ...
def intdigest128(self) -> int: ...
def copy(self) -> Xxh3: ...
def reset(self) -> None: ...
def xxh32(input: Buffer | None = None, seed: int | None = None) -> Xxh32: ...
def xxh64(input: Buffer | None = None, seed: int | None = None) -> Xxh64: ...
def xxh3(
input: Buffer | None = None,
seed: int | None = None,
secret: bytes | None = None,
) -> Xxh3: ...
# xxh32
def xxh32_digest(input: Buffer, seed: int | None = None) -> bytes: ...
def xxh32_hexdigest(input: Buffer, seed: int | None = None) -> str: ...
def xxh32_intdigest(input: Buffer, seed: int | None = None) -> int: ...
# xxh64
def xxh64_digest(input: Buffer, seed: int | None = None) -> bytes: ...
def xxh64_hexdigest(input: Buffer, seed: int | None = None) -> str: ...
def xxh64_intdigest(input: Buffer, seed: int | None = None) -> int: ...
# xxh128
def xxh128_digest(input: Buffer, seed: int | None = None) -> bytes: ...
def xxh128_hexdigest(input: Buffer, seed: int | None = None) -> str: ...
def xxh128_intdigest(input: Buffer, seed: int | None = None) -> int: ...
# xxh3
def xxh3_64_digest(input: Buffer, seed: int | None = None) -> bytes: ...
def xxh3_64_intdigest(input: Buffer, seed: int | None = None) -> int: ...
def xxh3_64_hexdigest(input: Buffer, seed: int | None = None) -> str: ...
def xxh3_digest(input: Buffer, seed: int | None = None) -> bytes: ...
def xxh3_intdigest(input: Buffer, seed: int | None = None) -> int: ...
def xxh3_hexdigest(input: Buffer, seed: int | None = None) -> str: ...
# xxh128
def xxh3_128_digest(input: Buffer, seed: int | None = None) -> bytes: ...
def xxh3_128_intdigest(input: Buffer, seed: int | None = None) -> int: ...
def xxh3_128_hexdigest(input: Buffer, seed: int | None = None) -> str: ...
ry.zstd
from ry import Bytes
from ry._types import Buffer
__zstd_version__: str # zstd version string ("1.5.7" as of 2025-03-14)
BLOCKSIZELOG_MAX: int
BLOCKSIZE_MAX: int
CLEVEL_DEFAULT: int # default=3 (as of 2025-03-14)
CONTENTSIZE_ERROR: int
CONTENTSIZE_UNKNOWN: int
MAGICNUMBER: int
MAGIC_DICTIONARY: int
MAGIC_SKIPPABLE_MASK: int
MAGIC_SKIPPABLE_START: int
VERSION_MAJOR: int
VERSION_MINOR: int
VERSION_NUMBER: int
VERSION_RELEASE: int
# =============================================================================
# PYFUNCTIONS
# =============================================================================
# __COMPRESSION__
def compress(data: Buffer, level: int = CLEVEL_DEFAULT) -> Bytes: ...
def encode(data: Buffer, level: int = CLEVEL_DEFAULT) -> Bytes: ...
def zstd(data: Buffer, level: int = CLEVEL_DEFAULT) -> Bytes: ...
def zstd_compress(data: Buffer, level: int = CLEVEL_DEFAULT) -> Bytes: ...
def zstd_encode(data: Buffer, level: int = CLEVEL_DEFAULT) -> Bytes: ...
# __DECOMPRESSION__
def decode(data: Buffer) -> Bytes: ...
def decompress(data: Buffer) -> Bytes: ...
def unzstd(data: Buffer) -> Bytes: ...
def zstd_decode(data: Buffer) -> Bytes: ...
def zstd_decompress(data: Buffer) -> Bytes: ...
# __MAGIC__
def is_zstd(data: Buffer) -> bool: ...
food-4-thought
thinking out loud…
ry.dev
For people who find ry.dev
it is a module that exports all the things in ry as
well as can be used as a repl; python -m ry.dev
will start a repl (with
ipython if installed else python-repl) with all of ry already imported. I
(jesse) use this super often for testing things out.
string-bridge?
The jiter
crate uses a string-cache to store python-strings to avoid the
overhead of converting strings to python strings. A global string bridge and/or
caching setup for other types of structs that often convert to strings might be
worth considering?
Naming
Coming up with names is hard… I (jesse) want to strike a balance between being clear but also close to the wrapped libraries…
- Should jiff’s
Zoned
beZoned
in python? orZonedDateTime
? (currentlyZonedDateTime
) - Should jiff’s
Span
beSpan
in python? orTimeSpan
? (currentlyTimeSpan
) - Should reqwest’s
Client
beClient
in python? orHttpClient
? (currentlyHttpClient
)
Flat? Nested submodules?
I like flat more, but nesting submodules might be preferable for some people and would allow for more flexibility in naming…
pros & cons:
- flat:
- pros:
- easier to import
- easier to work on
- no need to remember where things are
- type annotations are easier to setup/dist
- cons:
- name conflicts
- type annotations are harder to read bc of huge file
- harder to remember where things are
- pros:
- nested:
- pros:
- no name conflicts
- easier to remember where things are
- type annotations are easier to read
- importing
ry.jiff
(orry.ryo3.jiff
tbd) is more explicitly thejiff
wrapper(s)
- cons:
- Don’t know how type annotations should be laid out… if there is a
submodule called
ry.ryo3.reqwest
, do you import fromry.ryo3.reqwest
or do we reexport fromry.reqwest
? Then were doe the type-annotations live and how are they laid out without having to duplicate/shim them?
- Don’t know how type annotations should be laid out… if there is a
submodule called
- pros:
pypi size limit
The pypi project size limit of 10gb was reached. I (jesse) won’t request a limit
raise until the package is more stable and hits some sort of v0.1.x
, SOOOOOO
for now I will be:
- deleting older versions of ry from pypi as needed
- update the release gh-action to push the built wheels to the releases page so they are not lost into the ether…
jiff
docs.rs: https://docs.rs/jiff
crates: https://crates.io/crates/jiff
The jiff
crate has a super excellent API that is very ergonomic to use and
ry
provides a nearly complete wrapper around it.
A good amount of time, and a greater amount of thought has gone into balancing
the jiff
python api to be both ergonomic and performant.
python-conversions
The structs under ryo3-jiff
are convertable to/from python’s datetime.*
types and the conversions are pretty well tested (ty hypothesis).
pyo3-v0.24.0
& jiff-02
The conversions to/from python datetime.*
types were originally hand rolled (
by me (jesse)) using the ‘new-type’ pattern, HOWEVER pyo3-v0.24.0
provides
conversions via the jiff-02
feature flag, which is what is used now.
ry-v0.0.37
will be the last version with the mostly hand rolled conversions.
ry-v0.0.38
will be the first version with the jiff-02
feature flag.
As of 2025-03-12 pyo3
does not seem to support converting Span
->
datetime.timedelta
, so that is still hand rolled.
ry
vs whenever
There is another library called
whenever
that provides a similar
datetime library to that of ryo3-jiff
(both jiff
and whenever
are based on
the temporal API).
No formal benchmarks between ry
and whenever
have been done, but I have
copy-pasta-ed some of the benchmarks from the whenever
repo and translated
them to ry
and the results were pretty similar; whenever
is faster for some
things, ry
is faster for others, but both are wildly more performant than
python’s built in datetime
module and pendulum
– differences in performance
are almost all measured in nanoseconds.
Big shoutout to “Mr. Dutch Airlines” guy
(@ariebovenberg) who wrote whenever
! Love
the name of the library too!