Skip to content

Commit

Permalink
migrate from poetry to uv
Browse files Browse the repository at this point in the history
  • Loading branch information
oriontvv committed Dec 28, 2024
1 parent 8b291ba commit cbed426
Show file tree
Hide file tree
Showing 9 changed files with 487 additions and 1,100 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ jobs:

steps:
- uses: actions/checkout@v3
- name: Install uv
uses: astral-sh/setup-uv@v5
with:
version: "0.5.13"
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
Expand Down
22 changes: 9 additions & 13 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,26 @@ TESTS =\
ALL = $(CODE)\
$(TESTS)

VENV ?= .venv
JOBS ?= 4


init:
test -d $(VENV) || python3 -m venv $(VENV)
$(VENV)/bin/python -m pip install -U pip
$(VENV)/bin/python -m pip install poetry
$(VENV)/bin/poetry install
uv sync

lint: ruff mypy

ruff:
$(VENV)/bin/ruff .
uv run ruff check $(CODE)

mypy:
$(VENV)/bin/mypy --install-types --non-interactive \
uv run mypy --install-types --non-interactive \
--explicit-package-bases --namespace-packages --check-untyped-defs $(CODE)

pytest-lint:
$(VENV)/bin/pytest --dead-fixtures --dup-fixtures $(CODE)
uv run pytest --dead-fixtures --dup-fixtures $(CODE)

pretty:
$(VENV)/bin/ruff --silent --exit-zero --fix .
uv run ruff format $(CODE)

plint: pretty lint

Expand All @@ -40,10 +36,10 @@ precommit_install:
chmod +x .git/hooks/pre-commit

test:
$(VENV)/bin/python -m pytest tests --cov=src --ignore=.DS_Store
uv run pytest $(TESTS) --cov=src --ignore=.DS_Store

coverage-report:
$(VENV)/bin/coverage report -m
uv run coverage report -m

clean:
rm -rf `find . -name __pycache__`
Expand All @@ -60,10 +56,10 @@ clean:
rm -rf cover

build:
$(VENV)/bin/poetry build
uv build

publish:
$(VENV)/bin/poetry publish
uv publish

doc:
make -C docs html
Expand Down
1,008 changes: 0 additions & 1,008 deletions poetry.lock

This file was deleted.

75 changes: 27 additions & 48 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,68 +1,49 @@
[tool.poetry]
[project]
name = "wordle-solver"
description = "script for solving wordle puzzle"
version = "0.1.0"
description = "script for solving wordle puzzle"
authors = [
"Vassiliy Taranov <[email protected]>",
{ name = "oriontvv", email = "[email protected]" }
]
license = "LGPL"
license = "LGPL-3.0+"
readme = "README.md"
requires-python = ">=3.12"
homepage = "https://github.com/oriontvv/wordle-solver"
repository = "https://github.com/oriontvv/wordle-solver"
documentation = "https://github.com/oriontvv/wordle-solver"
keywords = [
"wordle",
"puzzle",
"solver",
]
classifiers = [
"Development Status :: 5 - Production/Stable",
"License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)",
"Operating System :: OS Independent",
"Intended Audience :: End Users/Desktop",
"Programming Language :: Python :: 3",
"Topic :: Games/Entertainment",
"Topic :: Games/Entertainment :: Puzzle Games",
"Topic :: Utilities",
dependencies = [
"expiring-dict>=1.1.1",
"python-dotenv>=1.0.1",
"python-telegram-bot==13.0",
]
packages = [
{ include = "src" }
]

[tool.poetry.dependencies]
python = ">=3.7,<4.0"
python-telegram-bot = "13.0,<20.0"
python-dotenv = "^0.21"
expiring-dict = "^1.1.0"

[tool.poetry.dev-dependencies]
coveralls = { version = "^3.3.1", extras = [ "toml" ]}
mypy = "^1.4"
pytest = "^7.4.0"
pytest-cov = "^4.1.0"
pytest-deadfixtures = "^2.2.1"


[tool.poetry.group.dev.dependencies]
black = {version = "^23.3", allow-prereleases = true}
ruff = "^0.0.281"
[project.scripts]
wordle-solver = "wordle_solver:main"

[build-system]
requires = ["poetry>=0.12"]
build-backend = "poetry.masonry.api"
requires = ["hatchling"]
build-backend = "hatchling.build"

[dependency-groups]
dev = [
"mypy>=1.14.0",
"pytest>=8.3.4",
"pytest-cov>=6.0.0",
"pytest-deadfixtures>=2.2.1",
"ruff>=0.8.4",
]

[tool.ruff]
line-length = 120
ignore = ["T201", "I001", "B905"]
select = ["A", "B", "C", "E", "F", "N", "T", "UP", "I"]
target-version = "py310"
target-version = "py311"

[tool.ruff.lint]
ignore = ["T201", "I001"]

[tool.ruff.mccabe]
# Unlike Flake8, default to a complexity level of 10.
[tool.ruff.lint.mccabe]
max-complexity = 10

[tool.ruff.flake8-quotes]
[tool.ruff.lint.flake8-quotes]
docstring-quotes = "double"

[tool.mypy]
Expand All @@ -71,7 +52,6 @@ ignore_missing_imports = true
[tool.pytest]
addopts = "--ignore=py3 --ignore=build"


[tool.coverage.run]
relative_files = true
omit = [
Expand All @@ -80,7 +60,6 @@ omit = [
"src/cli_app.py",
]


[tool.coverage.report]
exclude_lines = [
"pragma: no cover",
Expand Down
16 changes: 4 additions & 12 deletions src/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@
logging.basicConfig(format=log_format, level=logging.INFO)
logger = logging.getLogger(__name__)

file_handler = RotatingFileHandler(
cur_dir.parent / "history.log", maxBytes=10**6, backupCount=5
)
file_handler = RotatingFileHandler(cur_dir.parent / "history.log", maxBytes=10**6, backupCount=5)
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(logging.Formatter(log_format))
logger.addHandler(file_handler)
Expand Down Expand Up @@ -65,9 +63,7 @@ def __init__(
):
self.lang = lang
self.length = length
self.sessions = RefreshExpiringDict(
ttl=expire_session_ttl, interval=expire_session_interval
)
self.sessions = RefreshExpiringDict(ttl=expire_session_ttl, interval=expire_session_interval)

def __getitem__(self, key: str) -> Session:
try:
Expand Down Expand Up @@ -172,19 +168,15 @@ def run_bot(lang: str, length: int):
expire_session_interval = int(os.getenv("EXPIRE_SESSION_INTERVAL", 10 * 60))

global sessions
sessions = ExpiredSessionsStorage(
lang, length, expire_session_ttl, expire_session_interval
)
sessions = ExpiredSessionsStorage(lang, length, expire_session_ttl, expire_session_interval)

assert tg_token, "TELEGRAM_TOKEN env var not found"
updater = Updater(token=tg_token, use_context=True)
dispatcher = updater.dispatcher

dispatcher.add_handler(CommandHandler("help", help_command))
dispatcher.add_handler(CommandHandler("new", new_command))
dispatcher.add_handler(
MessageHandler(Filters.text & ~Filters.command, guess_word_command)
)
dispatcher.add_handler(MessageHandler(Filters.text & ~Filters.command, guess_word_command))

updater.start_polling()
logger.info("started")
Expand Down
4 changes: 1 addition & 3 deletions src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ def parse_args():
parser = ArgumentParser()
parser.add_argument("--lang", help="language", default="ru")
parser.add_argument("--length", help="length of words", default=5)
parser.add_argument(
"--bot", help="run telegram bot", default=False, action="store_true"
)
parser.add_argument("--bot", help="run telegram bot", default=False, action="store_true")
return parser.parse_args()


Expand Down
23 changes: 7 additions & 16 deletions src/solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ def __init__(self, words: set[str], length: int) -> None:
self.length = length
self.letters: list[Letter] = []
self.reset(words)
self.found_chars: set[
str
] = set() # letters that must be in the word, not in their places
self.found_chars: set[str] = set() # letters that must be in the word, not in their places

def reset(self, words: set[str]):
if not words:
Expand All @@ -29,11 +27,9 @@ def reset(self, words: set[str]):
def add_guess_result(self, guess: str):
chars = guess.strip().lower().split()
if len(chars) != len(self.letters):
raise ValueError(
f"Invalid format: {chars}, expected {len(self.letters)} chars"
)
raise ValueError(f"Invalid format: {chars}, expected {len(self.letters)} chars")

for ch, letter in zip(chars, self.letters):
for ch, letter in zip(chars, self.letters, strict=True):
if ch.endswith(("?", "+")):
ch = ch[0]
self.found_chars.add(ch)
Expand All @@ -56,8 +52,7 @@ def get_next_guess(self) -> list[str]:
self.possible_words = {
word
for word in self.possible_words
if re.match(pattern, word)
and all(variant in word for variant in self.found_chars)
if re.match(pattern, word) and all(variant in word for variant in self.found_chars)
}
variants = self.find_most_frequent_variants()
total_found = len([letter for letter in self.letters if letter.is_done()])
Expand All @@ -71,9 +66,7 @@ def get_next_guess(self) -> list[str]:
def total_variants(self) -> int:
return len(self.possible_words)

def find_most_frequent_variants(
self, count: int = 30, additional_weight: set | None = None
) -> list[str]:
def find_most_frequent_variants(self, count: int = 30, additional_weight: set | None = None) -> list[str]:
_additional_weight = additional_weight or set()

def max_freq(word):
Expand Down Expand Up @@ -103,14 +96,12 @@ def find_optimized_word(self, variants: list[str]) -> str:
solver = Solver(self.original_words, self.length)
unchecked_letters = set()
for variant in variants:
for variant_letter, letter in zip(variant, self.letters):
for variant_letter, letter in zip(variant, self.letters, strict=True):
if letter.is_done():
continue
unchecked_letters.add(variant_letter)

optimized_variants = solver.find_most_frequent_variants(
count=1, additional_weight=unchecked_letters
)
optimized_variants = solver.find_most_frequent_variants(count=1, additional_weight=unchecked_letters)
return optimized_variants[0]

def __str__(self) -> str:
Expand Down
Empty file added src/wordle_solver/__init__.py
Empty file.
Loading

0 comments on commit cbed426

Please sign in to comment.