From 2fd12f6b37bc767c5b59aa1775095f3fdf238bdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Dupr=C3=A9?= Date: Mon, 3 Feb 2025 10:43:04 +0100 Subject: [PATCH] ci: check that stubs are up to date --- .github/workflows/checks.yml | 25 ++++++ .gitignore | 2 +- Cargo.lock | 8 +- Cargo.toml | 8 +- compact-calendar/Cargo.toml | 2 +- opening-hours-py/Cargo.toml | 6 +- opening-hours-py/src/bin/stub_gen.rs | 54 +++++++++++++ opening-hours-py/src/types/timezone.rs | 18 +++++ opening-hours-syntax/Cargo.toml | 2 +- .../opening_hours.pyi => opening_hours.pyi | 80 +++++++++++-------- poetry.lock | 63 ++++++++++----- pyproject.toml | 3 +- 12 files changed, 206 insertions(+), 65 deletions(-) create mode 100644 opening-hours-py/src/bin/stub_gen.rs create mode 100644 opening-hours-py/src/types/timezone.rs rename opening-hours-py/opening_hours.pyi => opening_hours.pyi (79%) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 174c0638..d9fa0a1f 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -70,6 +70,31 @@ jobs: - name: Check version consistency run: poetry run ./check-version.py + # --- + # --- Check that python stubs are up to date + # --- + + check-stubs: + runs-on: ubuntu-latest + defaults: + run: + working-directory: ${{ matrix.crate }}/opening-hours-py + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + with: + toolchain: stable + components: rustfmt, clippy + - uses: actions/setup-python@v4 + with: + python-version: 3.12 + - name: Install poetry + run: | + python -m pip install --upgrade pip + pip install poetry + - name: Check that Python stubs are up to date + run: cargo run --bin stub_gen -- check + # --- # --- Calculate coverage using tarpaulin # --- diff --git a/.gitignore b/.gitignore index 11078082..246405d4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ -opening-hours/data/osm_examples.txt docs fuzz/artifacts +opening-hours/data/osm_examples.txt __pycache__ **/target diff --git a/Cargo.lock b/Cargo.lock index eb0665bd..ff79c7a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -216,7 +216,7 @@ checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "compact-calendar" -version = "1.0.0" +version = "1.0.1" dependencies = [ "chrono", ] @@ -715,7 +715,7 @@ checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" [[package]] name = "opening-hours" -version = "1.0.0" +version = "1.0.1" dependencies = [ "chrono", "chrono-tz", @@ -732,7 +732,7 @@ dependencies = [ [[package]] name = "opening-hours-py" -version = "1.0.0" +version = "1.0.1" dependencies = [ "chrono", "chrono-tz", @@ -745,7 +745,7 @@ dependencies = [ [[package]] name = "opening-hours-syntax" -version = "1.0.0" +version = "1.0.1" dependencies = [ "chrono", "log", diff --git a/Cargo.toml b/Cargo.toml index c884679b..b38a1291 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "opening-hours" -version = "1.0.0" +version = "1.0.1" authors = ["Rémi Dupré "] license = "MIT OR Apache-2.0" readme = "README.md" @@ -34,9 +34,9 @@ disable-test-timeouts = [] [dependencies] chrono = "0.4" -compact-calendar = { path = "compact-calendar", version = "1.0.0" } +compact-calendar = { path = "compact-calendar", version = "1.0.1" } flate2 = "1.0" -opening-hours-syntax = { path = "opening-hours-syntax", version = "1.0.0" } +opening-hours-syntax = { path = "opening-hours-syntax", version = "1.0.1" } sunrise-next = "1.2" # Feature: log (default) @@ -51,7 +51,7 @@ tzf-rs = { version = "0.4", default-features = false, optional = true } [build-dependencies] chrono = "0.4" -compact-calendar = { path = "compact-calendar", version = "1.0.0" } +compact-calendar = { path = "compact-calendar", version = "1.0.1" } country-boundaries = { version = "1.2", optional = true } flate2 = "1.0" rustc_version = "0.4.0" diff --git a/compact-calendar/Cargo.toml b/compact-calendar/Cargo.toml index 0c96d178..d2bf540c 100644 --- a/compact-calendar/Cargo.toml +++ b/compact-calendar/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "compact-calendar" -version = "1.0.0" +version = "1.0.1" authors = ["Rémi Dupré "] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/opening-hours-py/Cargo.toml b/opening-hours-py/Cargo.toml index 7c1e4619..daa1777f 100644 --- a/opening-hours-py/Cargo.toml +++ b/opening-hours-py/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "opening-hours-py" -version = "1.0.0" +version = "1.0.1" authors = ["Rémi Dupré "] license = "MIT OR Apache-2.0" readme = "README.md" @@ -23,12 +23,12 @@ pyo3-stub-gen = "0.7" [dependencies.opening-hours-rs] package = "opening-hours" path = ".." -version = "1.0.0" +version = "1.0.1" features = ["log", "auto-country", "auto-timezone"] [dependencies.opening-hours-syntax] path = "../opening-hours-syntax" -version = "1.0.0" +version = "1.0.1" features = ["log"] [dependencies.pyo3] diff --git a/opening-hours-py/src/bin/stub_gen.rs b/opening-hours-py/src/bin/stub_gen.rs new file mode 100644 index 00000000..692aa477 --- /dev/null +++ b/opening-hours-py/src/bin/stub_gen.rs @@ -0,0 +1,54 @@ +//! Run stub generation. +//! See https://github.com/Jij-Inc/pyo3-stub-gen + +use std::fs::File; +use std::io::Read; + +const STUB_SOURCE_PATH: &str = "opening_hours.pyi"; +const STUB_TARGET_PATH: &str = "../opening_hours.pyi"; + +// ⚠️ Do not copy this code as it is optimized for concision and not performance. +fn load_file(path: &str) -> Vec { + let mut file = File::open(path).unwrap_or_else(|err| panic!("could not load {path:?}: {err}")); + let mut res = Vec::new(); + + file.read_to_end(&mut res) + .unwrap_or_else(|err| panic!("could not read content from {path:?}: {err}")); + + res +} + +fn main() -> pyo3_stub_gen::Result<()> { + let is_subcommand_check = match std::env::args().nth(1).as_deref() { + None => false, + Some("check") => true, + Some(x) => panic!("Unknown subcommand {x:?}"), + }; + + let stub = opening_hours::stub_info()?; + stub.generate()?; + + std::process::Command::new("poetry") + .args(["run", "ruff", "format", STUB_SOURCE_PATH]) + .output() + .expect("failed to format stubs with ruff"); + + let changed = load_file(STUB_SOURCE_PATH) != load_file(STUB_TARGET_PATH); + + if changed { + if is_subcommand_check { + std::fs::remove_file(STUB_SOURCE_PATH).expect("could not remove stub file"); + panic!("File changed!"); + } else { + println!("Installing new stubs."); + + std::fs::rename(STUB_SOURCE_PATH, STUB_TARGET_PATH) + .expect("could not move stub to project's root"); + } + } else { + println!("No change detected."); + std::fs::remove_file(STUB_SOURCE_PATH).expect("could not remove stub file"); + } + + Ok(()) +} diff --git a/opening-hours-py/src/types/timezone.rs b/opening-hours-py/src/types/timezone.rs new file mode 100644 index 00000000..d23ded52 --- /dev/null +++ b/opening-hours-py/src/types/timezone.rs @@ -0,0 +1,18 @@ +use pyo3::prelude::*; +use pyo3_stub_gen::{PyStubType, TypeInfo}; + +/// Tiny wrapper that is here to extend type with stub generation. +#[derive(FromPyObject, IntoPyObject)] +pub(crate) struct TimeZoneWrapper(chrono_tz::Tz); + +impl From for chrono_tz::Tz { + fn from(val: TimeZoneWrapper) -> Self { + val.0 + } +} + +impl PyStubType for TimeZoneWrapper { + fn type_output() -> TypeInfo { + TypeInfo::with_module("zoneinfo.ZoneInfo", "zoneinfo".into()) + } +} diff --git a/opening-hours-syntax/Cargo.toml b/opening-hours-syntax/Cargo.toml index 634c0d9b..5656d9a8 100644 --- a/opening-hours-syntax/Cargo.toml +++ b/opening-hours-syntax/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "opening-hours-syntax" -version = "1.0.0" +version = "1.0.1" authors = ["Rémi Dupré "] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/opening-hours-py/opening_hours.pyi b/opening_hours.pyi similarity index 79% rename from opening-hours-py/opening_hours.pyi rename to opening_hours.pyi index 533ebb4c..526c1935 100644 --- a/opening-hours-py/opening_hours.pyi +++ b/opening_hours.pyi @@ -10,7 +10,7 @@ from enum import Enum, auto class OpeningHours: r""" Parse input opening hours description. - + Parameters ---------- oh : str @@ -35,35 +35,43 @@ class OpeningHours: auto_timezone : bool (default: `True`) If set to `True`, the timezone will automatically be inferred from coordinates when they are specified. - + Raises ------ SyntaxError Given string is not in valid opening hours format. - + Examples -------- >>> oh = OpeningHours("24/7") >>> oh.is_open() True - + >>> dt = datetime.fromisoformat("2024-07-14 15:00") >>> oh = OpeningHours("sunrise-sunset ; PH off", country="FR", coords=(48.8535, 2.34839)) >>> assert oh.is_closed(dt) >>> assert oh.next_change(dt).replace(tzinfo=None) == datetime.fromisoformat("2024-07-15 06:03") """ - def __new__(cls,oh:builtins.str, timezone:typing.Optional[zoneinfo.ZoneInfo]=None, country:typing.Optional[builtins.str]=None, coords:typing.Optional[tuple[builtins.float, builtins.float]]=None, auto_country:typing.Optional[builtins.bool]=True, auto_timezone:typing.Optional[builtins.bool]=True): ... - def state(self, time:typing.Optional[datetime.datetime]=None) -> State: + def __new__( + cls, + oh: builtins.str, + timezone: typing.Optional[zoneinfo.ZoneInfo] = None, + country: typing.Optional[builtins.str] = None, + coords: typing.Optional[tuple[builtins.float, builtins.float]] = None, + auto_country: typing.Optional[builtins.bool] = True, + auto_timezone: typing.Optional[builtins.bool] = True, + ): ... + def state(self, time: typing.Optional[datetime.datetime] = None) -> State: r""" Get current state of the time domain, the state can be either "open", "closed" or "unknown". - + Parameters ---------- time : Optional[datetime] Base time for the evaluation, current time will be used if it is not specified. - + Examples -------- >>> OpeningHours("24/7 off").state() @@ -71,16 +79,16 @@ class OpeningHours: """ ... - def is_open(self, time:typing.Optional[datetime.datetime]=None) -> builtins.bool: + def is_open(self, time: typing.Optional[datetime.datetime] = None) -> builtins.bool: r""" Check if current state is open. - + Parameters ---------- time : Optional[datetime] Base time for the evaluation, current time will be used if it is not specified. - + Examples -------- >>> OpeningHours("24/7").is_open() @@ -88,16 +96,18 @@ class OpeningHours: """ ... - def is_closed(self, time:typing.Optional[datetime.datetime]=None) -> builtins.bool: + def is_closed( + self, time: typing.Optional[datetime.datetime] = None + ) -> builtins.bool: r""" Check if current state is closed. - + Parameters ---------- time : Optional[datetime] Base time for the evaluation, current time will be used if it is not specified. - + Examples -------- >>> OpeningHours("24/7 off").is_closed() @@ -105,16 +115,18 @@ class OpeningHours: """ ... - def is_unknown(self, time:typing.Optional[datetime.datetime]=None) -> builtins.bool: + def is_unknown( + self, time: typing.Optional[datetime.datetime] = None + ) -> builtins.bool: r""" Check if current state is unknown. - + Parameters ---------- time : Optional[datetime] Base time for the evaluation, current time will be used if it is not specified. - + Examples -------- >>> OpeningHours("24/7 unknown").is_unknown() @@ -122,17 +134,19 @@ class OpeningHours: """ ... - def next_change(self, time:typing.Optional[datetime.datetime]=None) -> typing.Optional[datetime.datetime]: + def next_change( + self, time: typing.Optional[datetime.datetime] = None + ) -> typing.Optional[datetime.datetime]: r""" Get the date for next change of state. If the date exceed the limit date, returns None. - + Parameters ---------- time : Optional[datetime] Base time for the evaluation, current time will be used if it is not specified. - + Examples -------- >>> OpeningHours("24/7").next_change() # None @@ -141,11 +155,17 @@ class OpeningHours: """ ... - def intervals(self, start:typing.Optional[datetime.datetime]=None, end:typing.Optional[datetime.datetime]=None) -> typing.Iterator[builtins.tuple[datetime.datetime, datetime.datetime, State, builtins.str]]: + def intervals( + self, + start: typing.Optional[datetime.datetime] = None, + end: typing.Optional[datetime.datetime] = None, + ) -> typing.Iterator[ + builtins.tuple[datetime.datetime, datetime.datetime, State, builtins.str] + ]: r""" Give an iterator that yields successive time intervals of consistent state. - + Parameters ---------- start: Optional[datetime] @@ -154,7 +174,7 @@ class OpeningHours: end : Optional[datetime] Maximal time for the iterator, the iterator will continue until year 9999 if it no max is specified. - + Examples -------- >>> intervals = OpeningHours("2099Mo-Su 12:30-17:00").intervals() @@ -165,25 +185,22 @@ class OpeningHours: """ ... - def __str__(self) -> builtins.str: - ... - - def __repr__(self) -> builtins.str: - ... - + def __str__(self) -> builtins.str: ... + def __repr__(self) -> builtins.str: ... class State(Enum): r""" Specify the state of an opening hours interval. """ + Open = auto() Closed = auto() Unknown = auto() -def validate(oh:builtins.str) -> builtins.bool: +def validate(oh: builtins.str) -> builtins.bool: r""" Validate that input string is a correct opening hours description. - + Examples -------- >>> opening_hours.validate("24/7") @@ -192,4 +209,3 @@ def validate(oh:builtins.str) -> builtins.bool: False """ ... - diff --git a/poetry.lock b/poetry.lock index ff614e5c..baabf033 100644 --- a/poetry.lock +++ b/poetry.lock @@ -89,24 +89,24 @@ files = [ [[package]] name = "maturin" -version = "1.8.0" +version = "1.8.1" description = "Build and publish crates with pyo3, cffi and uniffi bindings as well as rust binaries as python packages" optional = false python-versions = ">=3.7" files = [ - {file = "maturin-1.8.0-py3-none-linux_armv6l.whl", hash = "sha256:04f90b4cc03f78a616cc7054034f0184b61756d1497e1b87e011a70ce420ebe2"}, - {file = "maturin-1.8.0-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:e02add08490f8246381ee3d66d35aab5d002435e2c1c0e14e45849bda5c42e39"}, - {file = "maturin-1.8.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:16d2ccd0476cf81022f01c45a77bf20fb4db06c04bfbbc77a1c85b27f9973e2d"}, - {file = "maturin-1.8.0-py3-none-manylinux_2_12_i686.manylinux2010_i686.musllinux_1_1_i686.whl", hash = "sha256:935892c4cfa9483eda22034413db0a6cd71069b4539ee5107d137c428a0026b6"}, - {file = "maturin-1.8.0-py3-none-manylinux_2_12_x86_64.manylinux2010_x86_64.musllinux_1_1_x86_64.whl", hash = "sha256:721f5f75e3645fa25576af549e62673c45f247e4567eb3a21fbb714b16d3e741"}, - {file = "maturin-1.8.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:4f55a717aebff0a16abb9f207a3c25edc350f0ef12b7f98ffb53f2287f221f58"}, - {file = "maturin-1.8.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:90e1a022b5c735170f50867b1fa46338acc695b94fbf230376dc69ff9830606b"}, - {file = "maturin-1.8.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.musllinux_1_1_ppc64le.whl", hash = "sha256:11fbd89f07053c71904ae4afdf48ee18d41740d2f2939b91c838ccc5afd02e1a"}, - {file = "maturin-1.8.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:acae3cfa51a68e512653103efa29e3321aa1ffb73b26cdcf3450f4a9806f8e00"}, - {file = "maturin-1.8.0-py3-none-win32.whl", hash = "sha256:cca59e78121c90d26e80af8e0be624362d14816ce28e082d876208f2d29ea8b5"}, - {file = "maturin-1.8.0-py3-none-win_amd64.whl", hash = "sha256:422355ec4bab3ce025f826b25e2bb77e31a879c6cc06bb7a6fd3c1dd16a7e4fe"}, - {file = "maturin-1.8.0-py3-none-win_arm64.whl", hash = "sha256:2a62793262eea8f85218accd2f877040e4b74af356a958bb769858ee23a275fd"}, - {file = "maturin-1.8.0.tar.gz", hash = "sha256:2f4abdf33e87ccb0d035a838e832945c6f7374222eacde508fafc752dda8ba6e"}, + {file = "maturin-1.8.1-py3-none-linux_armv6l.whl", hash = "sha256:7e590a23d9076b8a994f2e67bc63dc9a2d1c9a41b1e7b45ac354ba8275254e89"}, + {file = "maturin-1.8.1-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8d8251a95682c83ea60988c804b620c181911cd824aa107b4a49ac5333c92968"}, + {file = "maturin-1.8.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b9fc1a4354cac5e32c190410208039812ea88c4a36bd2b6499268ec49ef5de00"}, + {file = "maturin-1.8.1-py3-none-manylinux_2_12_i686.manylinux2010_i686.musllinux_1_1_i686.whl", hash = "sha256:621e171c6b39f95f1d0df69a118416034fbd59c0f89dcaea8c2ea62019deecba"}, + {file = "maturin-1.8.1-py3-none-manylinux_2_12_x86_64.manylinux2010_x86_64.musllinux_1_1_x86_64.whl", hash = "sha256:98f638739a5132962347871b85c91f525c9246ef4d99796ae98a2031e3df029f"}, + {file = "maturin-1.8.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:f9f5c47521924b6e515cbc652a042fe5f17f8747445be9d931048e5d8ddb50a4"}, + {file = "maturin-1.8.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:0f4407c7353c31bfbb8cdeb82bc2170e474cbfb97b5ba27568f440c9d6c1fdd4"}, + {file = "maturin-1.8.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.musllinux_1_1_ppc64le.whl", hash = "sha256:ec49cd70cad3c389946c6e2bc0bd50772a7fcb463040dd800720345897eec9bf"}, + {file = "maturin-1.8.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c08767d794de8f8a11c5c8b1b47a4ff9fb6ae2d2d97679e27030f2f509c8c2a0"}, + {file = "maturin-1.8.1-py3-none-win32.whl", hash = "sha256:d678407713f3e10df33c5b3d7a343ec0551eb7f14d8ad9ba6febeb96f4e4c75c"}, + {file = "maturin-1.8.1-py3-none-win_amd64.whl", hash = "sha256:a526f90fe0e5cb59ffb81f4ff547ddc42e823bbdeae4a31012c0893ca6dcaf46"}, + {file = "maturin-1.8.1-py3-none-win_arm64.whl", hash = "sha256:e95f077fd2ddd2f048182880eed458c308571a534be3eb2add4d3dac55bf57f4"}, + {file = "maturin-1.8.1.tar.gz", hash = "sha256:49cd964aabf59f8b0a6969f9860d2cdf194ac331529caae14c884f5659568857"}, ] [package.extras] @@ -131,19 +131,46 @@ pygments = ">=2.12.0" [[package]] name = "pygments" -version = "2.18.0" +version = "2.19.1" description = "Pygments is a syntax highlighting package written in Python." optional = false python-versions = ">=3.8" files = [ - {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, - {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, + {file = "pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c"}, + {file = "pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f"}, ] [package.extras] windows-terminal = ["colorama (>=0.4.6)"] +[[package]] +name = "ruff" +version = "0.9.4" +description = "An extremely fast Python linter and code formatter, written in Rust." +optional = false +python-versions = ">=3.7" +files = [ + {file = "ruff-0.9.4-py3-none-linux_armv6l.whl", hash = "sha256:64e73d25b954f71ff100bb70f39f1ee09e880728efb4250c632ceed4e4cdf706"}, + {file = "ruff-0.9.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6ce6743ed64d9afab4fafeaea70d3631b4d4b28b592db21a5c2d1f0ef52934bf"}, + {file = "ruff-0.9.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:54499fb08408e32b57360f6f9de7157a5fec24ad79cb3f42ef2c3f3f728dfe2b"}, + {file = "ruff-0.9.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37c892540108314a6f01f105040b5106aeb829fa5fb0561d2dcaf71485021137"}, + {file = "ruff-0.9.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:de9edf2ce4b9ddf43fd93e20ef635a900e25f622f87ed6e3047a664d0e8f810e"}, + {file = "ruff-0.9.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:87c90c32357c74f11deb7fbb065126d91771b207bf9bfaaee01277ca59b574ec"}, + {file = "ruff-0.9.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:56acd6c694da3695a7461cc55775f3a409c3815ac467279dfa126061d84b314b"}, + {file = "ruff-0.9.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e0c93e7d47ed951b9394cf352d6695b31498e68fd5782d6cbc282425655f687a"}, + {file = "ruff-0.9.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1d4c8772670aecf037d1bf7a07c39106574d143b26cfe5ed1787d2f31e800214"}, + {file = "ruff-0.9.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfc5f1d7afeda8d5d37660eeca6d389b142d7f2b5a1ab659d9214ebd0e025231"}, + {file = "ruff-0.9.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:faa935fc00ae854d8b638c16a5f1ce881bc3f67446957dd6f2af440a5fc8526b"}, + {file = "ruff-0.9.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a6c634fc6f5a0ceae1ab3e13c58183978185d131a29c425e4eaa9f40afe1e6d6"}, + {file = "ruff-0.9.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:433dedf6ddfdec7f1ac7575ec1eb9844fa60c4c8c2f8887a070672b8d353d34c"}, + {file = "ruff-0.9.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d612dbd0f3a919a8cc1d12037168bfa536862066808960e0cc901404b77968f0"}, + {file = "ruff-0.9.4-py3-none-win32.whl", hash = "sha256:db1192ddda2200671f9ef61d9597fcef89d934f5d1705e571a93a67fb13a4402"}, + {file = "ruff-0.9.4-py3-none-win_amd64.whl", hash = "sha256:05bebf4cdbe3ef75430d26c375773978950bbf4ee3c95ccb5448940dc092408e"}, + {file = "ruff-0.9.4-py3-none-win_arm64.whl", hash = "sha256:585792f1e81509e38ac5123492f8875fbc36f3ede8185af0a26df348e5154f41"}, + {file = "ruff-0.9.4.tar.gz", hash = "sha256:6907ee3529244bb0ed066683e075f09285b38dd5b4039370df6ff06041ca19e7"}, +] + [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "9d9ee940489180ed0d9d982f7245de762ebac6c15e29fb2f4fbfc7450d596bf1" +content-hash = "6822fe5c2659b2beb028cbf61b38d2633f5a843037adca65d6b52115dc0a6f88" diff --git a/pyproject.toml b/pyproject.toml index 261e9a7f..d3e04bf5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ dynamic = ["version"] [tool.poetry] name = "opening_hours" -version = "1.0.0" +version = "1.0.1" description = "A parser for the opening_hours fields from OpenStreetMap." authors = ["Rémi Dupré "] package-mode = false @@ -15,6 +15,7 @@ python = "^3.11" [tool.poetry.dev-dependencies] maturin = ">=1" pdoc = "^15" +ruff = "^0.9" [build-system] requires = ["poetry>=0.12", "maturin>=1,<2"]