Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .github/CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@ Setting things up

$ git remote add upstream https://github.com/python-telegram-bot/python-telegram-bot

4. Install dependencies:
4. Install the package in development mode as well as optional dependencies and development dependencies.
Note that the `--group` argument requires `pip` 25.1 or later.

.. code-block:: bash

$ pip install .[all] --group all
$ pip install -e .[all] --group all

Installing the package itself is necessary because python-telegram-bot uses a src-based layout where the package code is located in the ``src/`` directory.

5. Install pre-commit hooks:

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/docs-admonitions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Test Admonitions Generation
on:
pull_request:
paths:
- telegram/**
- src/telegram/**
- docs/**
- .github/workflows/docs-admonitions.yml
push:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test_official.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Bot API Tests
on:
pull_request:
paths:
- telegram/**
- src/telegram/**
- tests/**
push:
branches:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/type_completeness.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Check Type Completeness
on:
pull_request:
paths:
- telegram/**
- src/telegram/**
- pyproject.toml
- .github/workflows/type_completeness.yml
push:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/unit_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Unit Tests
on:
pull_request:
paths:
- telegram/**
- src/telegram/**
- tests/**
- .github/workflows/unit_tests.yml
- pyproject.toml
Expand Down
5 changes: 5 additions & 0 deletions changes/unreleased/4798.g7G3jRf2ns4ath9LRFEcit.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
internal = "Rework Repository to `src` Layout"
[[pull_requests]]
uid = "4798"
author_uid = "Bibo-Joshi"
closes_threads = ["4797"]
24 changes: 15 additions & 9 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,15 @@ all = ["pre-commit", { include-group = "tests" }, { include-group = "docs" }]
[tool.hatch.version]
# dynamically evaluates the `__version__` variable in that file
source = "code"
path = "telegram/_version.py"
search-paths = ["telegram"]
path = "src/telegram/_version.py"

[tool.hatch.build]
packages = ["telegram"]
# See also https://github.com/pypa/hatch/issues/1230 for discussion
# the source distribution will include most of the files in the root directory
[tool.hatch.build.targets.sdist]
exclude = [".venv*", "venv*", ".github"]
# the wheel will only include the src/telegram package
[tool.hatch.build.targets.wheel]
packages = ["src/telegram"]

# CHANGO
[tool.chango]
Expand Down Expand Up @@ -167,9 +171,9 @@ select = ["E", "F", "I", "PL", "UP", "RUF", "PTH", "C4", "B", "PIE", "SIM", "RET
[tool.ruff.lint.per-file-ignores]
"tests/*.py" = ["B018"]
"tests/**.py" = ["RUF012", "ASYNC230", "DTZ", "ARG", "T201", "ASYNC109", "D", "S", "TRY"]
"telegram/**.py" = ["TRY003"]
"telegram/ext/_applicationbuilder.py" = ["TRY004"]
"telegram/ext/filters.py" = ["D102"]
"src/telegram/**.py" = ["TRY003"]
"src/telegram/ext/_applicationbuilder.py" = ["TRY004"]
"src/telegram/ext/filters.py" = ["D102"]
"docs/**.py" = ["INP001", "ARG", "D", "TRY003", "S"]
"examples/**.py" = ["ARG", "D", "S105", "TRY003"]

Expand Down Expand Up @@ -197,6 +201,7 @@ exclude-protected = ["_unfrozen"]
# PYTEST:
[tool.pytest.ini_options]
testpaths = ["tests"]
pythonpath = ["src"]
addopts = "--no-success-flaky-report -rX"
filterwarnings = [
"error",
Expand All @@ -219,6 +224,7 @@ log_cli_format = "%(funcName)s - Line %(lineno)d - %(message)s"

# MYPY:
[tool.mypy]
mypy_path = "src"
warn_unused_ignores = true
warn_unused_configs = true
disallow_untyped_defs = true
Expand Down Expand Up @@ -261,12 +267,12 @@ ignore_missing_imports = true
# COVERAGE:
[tool.coverage.run]
branch = true
source = ["telegram"]
source = ["src/telegram"]
parallel = true
concurrency = ["thread", "multiprocessing"]
omit = [
"tests/",
"telegram/__main__.py"
"src/telegram/__main__.py"
]

[tool.coverage.report]
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
6 changes: 6 additions & 0 deletions tests/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ PTB uses `pytest`_ for testing. To run the tests, you need to
have pytest installed along with a few other dependencies. You can find the list of dependencies
in the ``pyproject.toml`` file in the root of the repository.

Since PTB uses a src-based layout, make sure you have installed the package in development mode before running the tests:

.. code-block:: bash

$ pip install -e .

Running tests
=============

Expand Down
1 change: 1 addition & 0 deletions tests/auxil/files.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from pathlib import Path

PROJECT_ROOT_PATH = Path(__file__).parent.parent.parent.resolve()
SOURCE_ROOT_PATH = PROJECT_ROOT_PATH / "src" / "telegram"
TEST_DATA_PATH = PROJECT_ROOT_PATH / "tests" / "data"


Expand Down
6 changes: 3 additions & 3 deletions tests/ext/test_application.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
from telegram.warnings import PTBDeprecationWarning, PTBUserWarning
from tests.auxil.asyncio_helpers import call_after
from tests.auxil.build_messages import make_message_update
from tests.auxil.files import PROJECT_ROOT_PATH
from tests.auxil.files import SOURCE_ROOT_PATH
from tests.auxil.monkeypatch import empty_get_updates, return_true
from tests.auxil.networking import send_webhook_message
from tests.auxil.pytest_classes import PytestApplication, PytestUpdater, make_bot
Expand Down Expand Up @@ -1006,7 +1006,7 @@ async def callback(update, context):
== "ApplicationHandlerStop is not supported with handlers running non-blocking."
)
assert (
Path(recwarn[0].filename) == PROJECT_ROOT_PATH / "telegram" / "ext" / "_application.py"
Path(recwarn[0].filename) == SOURCE_ROOT_PATH / "ext" / "_application.py"
), "incorrect stacklevel!"

async def test_non_blocking_no_error_handler(self, app, caplog):
Expand Down Expand Up @@ -1079,7 +1079,7 @@ async def error_handler(update, context):
== "ApplicationHandlerStop is not supported with handlers running non-blocking."
)
assert (
Path(recwarn[0].filename) == PROJECT_ROOT_PATH / "telegram" / "ext" / "_application.py"
Path(recwarn[0].filename) == SOURCE_ROOT_PATH / "ext" / "_application.py"
), "incorrect stacklevel!"

@pytest.mark.parametrize(("block", "expected_output"), [(False, 0), (True, 5)])
Expand Down
13 changes: 4 additions & 9 deletions tests/ext/test_conversationhandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
)
from telegram.warnings import PTBUserWarning
from tests.auxil.build_messages import make_command_message
from tests.auxil.files import PROJECT_ROOT_PATH
from tests.auxil.files import SOURCE_ROOT_PATH
from tests.auxil.pytest_classes import PytestBot, make_bot
from tests.auxil.slots import mro_slots

Expand Down Expand Up @@ -725,7 +725,7 @@ async def callback(_, __):
assert recwarn[0].category is PTBUserWarning
assert (
Path(recwarn[0].filename)
== PROJECT_ROOT_PATH / "telegram" / "ext" / "_handlers" / "conversationhandler.py"
== SOURCE_ROOT_PATH / "ext" / "_handlers" / "conversationhandler.py"
), "wrong stacklevel!"
assert (
str(recwarn[0].message)
Expand Down Expand Up @@ -1105,11 +1105,7 @@ async def test_no_running_job_queue_warning(self, app, bot, user1, recwarn, jq):
assert warning.category is PTBUserWarning
assert (
Path(warning.filename)
== PROJECT_ROOT_PATH
/ "telegram"
/ "ext"
/ "_handlers"
/ "conversationhandler.py"
== SOURCE_ROOT_PATH / "ext" / "_handlers" / "conversationhandler.py"
), "wrong stacklevel!"
# now set app.job_queue back to it's original value

Expand Down Expand Up @@ -1428,8 +1424,7 @@ def timeout(*args, **kwargs):
assert str(recwarn[0].message).startswith("ApplicationHandlerStop in TIMEOUT")
assert recwarn[0].category is PTBUserWarning
assert (
Path(recwarn[0].filename)
== PROJECT_ROOT_PATH / "telegram" / "ext" / "_jobqueue.py"
Path(recwarn[0].filename) == SOURCE_ROOT_PATH / "ext" / "_jobqueue.py"
), "wrong stacklevel!"

await app.stop()
Expand Down
5 changes: 2 additions & 3 deletions tests/ext/test_picklepersistence.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
from telegram import Chat, Message, TelegramObject, Update, User
from telegram.ext import ContextTypes, PersistenceInput, PicklePersistence
from telegram.warnings import PTBUserWarning
from tests.auxil.files import PROJECT_ROOT_PATH
from tests.auxil.files import SOURCE_ROOT_PATH
from tests.auxil.pytest_classes import make_bot
from tests.auxil.slots import mro_slots

Expand Down Expand Up @@ -899,8 +899,7 @@ async def test_custom_pickler_unpickler_simple(
assert recwarn[-1].category is PTBUserWarning
assert str(recwarn[-1].message).startswith("Unknown bot instance found.")
assert (
Path(recwarn[-1].filename)
== PROJECT_ROOT_PATH / "telegram" / "ext" / "_picklepersistence.py"
Path(recwarn[-1].filename) == SOURCE_ROOT_PATH / "ext" / "_picklepersistence.py"
), "wrong stacklevel!"
pp = PicklePersistence("pickletest", single_file=False, on_flush=False)
pp.set_bot(bot)
Expand Down
5 changes: 4 additions & 1 deletion tests/test_modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@
import os
from pathlib import Path

from tests.auxil.files import SOURCE_ROOT_PATH


def test_public_submodules_dunder_all():
modules_to_search = list(Path("telegram").rglob("*.py"))
modules_to_search = list(SOURCE_ROOT_PATH.rglob("*.py"))

if not modules_to_search:
raise AssertionError("No modules found to search through, please modify this test.")
Expand All @@ -52,6 +54,7 @@ def test_public_submodules_dunder_all():


def load_module(path: Path):
path = path.relative_to(SOURCE_ROOT_PATH.parent)
if path.name == "__init__.py":
mod_name = str(path.parent).replace(os.sep, ".") # telegram(.ext) format
else:
Expand Down
4 changes: 2 additions & 2 deletions tests/test_warnings.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

from telegram._utils.warnings import warn
from telegram.warnings import PTBDeprecationWarning, PTBRuntimeWarning, PTBUserWarning
from tests.auxil.files import PROJECT_ROOT_PATH
from tests.auxil.files import SOURCE_ROOT_PATH
from tests.auxil.slots import mro_slots


Expand Down Expand Up @@ -66,7 +66,7 @@ def make_assertion(cls):
make_assertion(PTBUserWarning)

def test_warn(self, recwarn):
expected_file = PROJECT_ROOT_PATH / "telegram" / "_utils" / "warnings.py"
expected_file = SOURCE_ROOT_PATH / "_utils" / "warnings.py"

warn("test message")
assert len(recwarn) == 1
Expand Down
Loading