pyproject.toml
Rama main · réplica de lectura del repositorio original.
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "saleor"
version = "3.24.0-a.0"
description = "A modular, high performance, headless e-commerce platform built with Python, GraphQL, Django, and React."
authors = [{ name = "Saleor Commerce", email = "hello@saleor.io" }]
requires-python = ">=3.12,<3.13"
readme = "README.md"
license = "BSD-3-Clause"
dependencies = [
"asgiref>=3.11.1,<4",
"authlib>=1.9.2,<2",
"azure-common>=1.1.28,<2",
"azure-storage-blob>=12.29.0,<13",
"azure-storage-common>=2.1.0,<3",
"babel>=2.18.0,<2.19",
"boto3~=1.43",
"botocore~=1.43",
"cryptography>=50.0.2",
"dj-database-url>=3.1.2,<4",
"dj-email-url>=1,<2",
"django[bcrypt]~=5.2.19",
"django-cache-url>=3.4.6,<4",
"django-celery-beat>=2.8.1,<3",
"django-countries~=7.2",
"django-filter~=26.1",
"django-measurement~=3.0",
"django-mptt>=0,<1",
"django-phonenumber-field>=8.4.0,<9",
"django-stubs-ext>=5.1.3,<6",
"faker>=40.32.0,<41.0",
"google-cloud-pubsub>=2.39.0,<3.0",
"google-cloud-storage>=2.0.0,<3",
"google-i18n-address>=3.1.0,<4",
"graphene<3.0",
"graphql-core>=2.3.2,<3",
"graphql-relay>=2.0.1,<3",
"lxml>=6.1.1,<7",
"measurement>=3.2.2,<4",
"micawber>=0.6.2,<0.7",
"oauthlib~=4.0",
"petl==1.7.20",
"phonenumberslite>=9.0.36,<10",
"pillow>=13.0.0,<14",
"prices~=1.0",
"promise~=2.3",
"pybars3>=0.9.7,<0.10",
"pyjwt>=2.15.0,<3",
"python-dateutil>=2.8.2,<3",
"python-json-logger>=0.1.11,<3.3.0",
"pytimeparse>=1.1.8,<2",
"redis>=5.0.1,<6",
"requests>=2.33.0,<3",
"requests-hardened>=1.3.0,<2.0.0",
"Rx>=1.6.3,<2",
"semantic-version>=2.10.0,<3",
"sentry-sdk~=2.58",
"stripe>=3.0.0,<4",
"text-unidecode~=1.2",
"urllib3>=2.8.0,<3",
"uvicorn[standard]==0.52.1",
"psycopg[binary]>=3.3.4,<4",
"pydantic>=2.13.4,<3",
"pydantic-core>=2.33.0,<3",
"opentelemetry-api>=1.37.0,<2",
"opentelemetry-sdk>=1.37.0,<2",
"opentelemetry-semantic-conventions>=0.58b0,<0.59",
"opentelemetry-distro[otlp]>=0.58b0,<0.59",
"opentelemetry-instrumentation-botocore>=0.58b0,<0.59",
"opentelemetry-instrumentation-celery>=0.58b0,<0.59",
"opentelemetry-instrumentation-psycopg>=0.58b0,<0.59",
"opentelemetry-instrumentation-redis>=0.58b0,<0.59",
"opentelemetry-instrumentation-threading>=0.58b0,<0.59",
"celery[redis, sqs]>=5.6.3,<6.0.0",
"kombu[sqs]>=4.6.11,<6.0.0",
"django-storages[google]~=1.14",
"python-magic>=0.4.27,<0.5 ; sys_platform != 'win32'",
"python-magic-bin>=0.4.14,<0.5 ; sys_platform == 'win32'",
"nh3>=0.2.20",
"idna>=3.18",
"orjson>=3.11.9",
]
[project.urls]
Homepage = "https://saleor.io/"
Repository = "https://github.com/saleor/saleor"
Documentation = "https://docs.saleor.io/"
[dependency-groups]
dev = [
"coverage~=7.14",
"deptry>=0.23.0,<0.24",
"django-extensions~=4.1",
# TODO: once on django-stubs >= 6.0.2, revert the PublishedQuerySet TypeVar
# workaround in saleor/core/models.py back to bound="PublishableModel".
# The fix landed in https://github.com/typeddjango/django-stubs/commit/461fb9ba8d26667cb43cfb55827acdc6d4ed42ed
"django-stubs[compatible-mypy]>=5.1.3,<6",
"fakeredis~=2.26",
"freezegun>=1,<2",
"mypy-extensions>=1.1.0,<2",
"openpyxl>=3.1.5,<4",
"pre-commit~=4.6",
"pytest>=9.0.3,<10",
"pytest-asyncio>=1.4.0,<2",
"pytest-celery>=1.0.1,<2",
"pytest-cov>=7.1.0,<8",
"pytest-django==4.12.0",
"pytest-django-queries>=1.2,<1.3",
"pytest-memray>=1.9.0,<2", # Used via @pytest.mark.limit_memory
"pytest-mock>=3.6.1,<4",
"pytest-recording>=0.13.0,<0.14",
"pytest-socket>=0.8.0,<1",
"pytest-xdist>=3.0.2,<4",
"pywatchman>=3.0.0,<4",
"ruff>=0.12.2,<0.13",
"types-certifi>=2021.10.8,<2022",
"types-freezegun>=1.1.7,<2",
"types-mock>=5.2.0.20260508,<6",
"types-python-dateutil>=2.9.0.20260518,<3",
"types-redis>=4.6.0,<5",
"types-requests>=2.33.0.20260712,<3",
"types-six>=1.17.0.20260518,<2",
"vcrpy>=8.2.1,<9",
"poethepoet>=0.45.0,<0.46",
"ipdb>=0.13.13,<0.14",
]
[tool.poe]
envfile = ".env"
[tool.uv]
# 0.13.5 fixes bundled `pip` version containing a compromised certificate
# (https://github.com/astral-sh/uv/releases/tag/0.13.5)
required-version = ">=0.13.5"
environments = [
"platform_python_implementation != 'PyPy'"
]
package = false
# Applies the 21 days cooldown (3 weeks) recommendation from Snyk
# (https://snyk.io/articles/npm-security-best-practices-shai-hulud-attack/#2-2-snyk-cooldown-in-automatic-p-rs)
exclude-newer = "3 weeks"
[tool.uv.exclude-newer-package]
# To customize on a per-package basis, for example you can do this:
# setuptools = "2026-04-07T14:30:00Z"
# Note: the timestamp should correspond to the package's upload time on PyPI.
# It doesn't need to match exactly, it can be set slightly after the actual
# publication time (add a few more seconds, but no more than a few minutes).
# Setting the timestamp too far after the publication time increases the risk
# of a race condition (e.g., a malicious version being uploaded within that
# window).
# Note: if you remove a package from this list and 'uv lock' does not update the
# lockfile, run 'uv lock --refresh' to force a refresh.
certifi = "2026-10-20T02:24:16" # https://pypi.org/pypi/certifi/2026.10.19/json
cryptography = "2026-09-30T15:31:00Z" # https://pypi.org/pypi/cryptography/50.0.2/json
pillow = "2026-10-16T22:20:00Z" # https://pypi.org/pypi/pillow/13.0.0/json
virtualenv = "2026-10-22T20:11:00Z" # https://pypi.org/pypi/virtualenv/21.14.13/json
pyasn1 = "2026-10-27T06:33:00Z" # https://pypi.org/pypi/pyasn1/0.6.5/json
authlib = "2026-11-01T20:40:00Z" # https://pypi.org/pypi/authlib/1.9.2/json
joserfc = "2026-10-19T00:31:00Z" # https://pypi.org/pypi/joserfc/1.7.7/json
oauthlib = "2026-09-28T06:02:00Z" # https://pypi.org/pypi/oauthlib/4.0.0/json
vcrpy = "2026-06-16T13:21:00Z" # https://pypi.org/pypi/vcrpy/8.2.1/json
django = "2026-11-03T15:25:00Z" # https://pypi.org/pypi/django/5.2.19/json
[tool.pytest]
addopts = [
"-n=auto",
"--record-mode=none",
"--ds=saleor.tests.settings",
"--disable-socket",
"--allow-hosts=127.0.0.1,::1,cache,host.docker.internal,host.containers.internal",
"--allow-unix-socket",
"--pdbcls=IPython.terminal.debugger:TerminalPdb",
"--dist=loadgroup",
]
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "function"
testpaths = ["saleor"]
filterwarnings = [
"ignore::DeprecationWarning",
"ignore::PendingDeprecationWarning",
]
markers = [
"integration",
"e2e",
"slow",
]
[tool.poe.tasks]
start.help = "Start development server with hot reload"
start.cmd = "uvicorn saleor.asgi:application --reload"
worker.help = "Start Celery worker"
worker.cmd = "celery --app saleor.celeryconf:app worker -E"
scheduler.help = "Start Celery Beat scheduler"
scheduler.cmd = "celery --app saleor.celeryconf:app beat --scheduler saleor.schedulers.schedulers.DatabaseScheduler"
build-schema.cmd = "python manage.py get_graphql_schema"
build-schema.capture_stdout = "saleor/graphql/schema.graphql"
build-schema.help = "Build GraphQL schema to saleor/graphql/schema.graphql file"
migrate.cmd = "python manage.py migrate"
migrate.help = "Run database migrations"
make-migrations.cmd = "python manage.py makemigrations"
make-migrations.help = "Create new migrations based on changes in models"
release.shell = "npm run release"
release.help = """
Release new Saleor verison
Prerequisities:
- Node installed on machine
- Run npm install to install dependencies
"""
shell.cmd = "python manage.py shell"
shell.help = "Start Django shell in interactive mode"
populatedb.cmd = "python manage.py populatedb --createsuperuser"
populatedb.help = """
Populates database with sample data and creates admin user with credentials:
- email: admin@example.com
- password: admin
"""
test.cmd="pytest --reuse-db"
test.help = "Run tests with db reuse to speed up testing time"
[tool.deptry]
extend_exclude = ["conftest\\.py", ".*/conftest\\.py", ".*/tests/.*"]
[tool.deptry.package_module_name_map]
graphql-core = "graphql"
pillow = "PIL"
python-magic-bin = "magic"
[tool.deptry.per_rule_ignores]
DEP002 = ["azure-common", "azure-storage-blob", "azure-storage-common", "django-redis", "psycopg", "pyxb", "opentelemetry-instrumentation-botocore", "opentelemetry-instrumentation-celery", "opentelemetry-instrumentation-psycopg", "opentelemetry-instrumentation-redis", "opentelemetry-instrumentation-threading"]
[tool.django-stubs]
django_settings_module = "saleor.settings"
[tool.mypy]
allow_untyped_globals = true
allow_redefinition = true
check_untyped_defs = true
ignore_missing_imports = true
pretty = true
show_column_numbers = true
show_error_codes = true
show_error_context = true
show_traceback = true
warn_redundant_casts = true
warn_unused_ignores = true
plugins = [
"mypy_django_plugin.main",
"pydantic.mypy"
]
exclude = [
"tests/"
]
[[tool.mypy.overrides]]
module = ["saleor.*.migrations.*"]
ignore_errors = true
[tool.pydantic-mypy]
init_forbid_extra = true
init_typed = true
warn_required_dynamic_aliases = true
[tool.ruff]
target-version = "py312"
[tool.ruff.lint]
select = [
"ASYNC",
"B",
"C4",
"D",
"DTZ",
"E",
"F",
"FURB",
"G",
"I",
"ISC001",
"ISC002",
"LOG",
"PGH",
"PIE",
"PT",
"PYI",
"RET",
"T20",
"UP",
"W"
]
ignore = [
"B009", # Do not call getattr with a constant value
"B010", # Do not call setattr with a constant value
"B023", # Function definition does not bind loop variable
"D100", # Missing docstring in public module
"D101", # Missing docstring in public class
"D102", # Missing docstring in public method
"D103", # Missing docstring in public function
"D104", # Missing docstring in public package
"D105", # Missing docstring in magic method
"D106", # Missing docstring in public nested class
"D107", # Missing docstring in __init__
"D202", # No blank lines allowed after function docstring
"D203", # 1 blank line required before class docstring
"D206", # Docstring should be indented with spaces, not tabs
"D213", # Multi-line docstring summary should start at the second line
"D407", # Missing dashed underline after section
"E501", # Line too long
"PT019", # Fixture without value is injected as parameter, use @pytest.mark.usefixtures instead
"PYI041", # Use `float` instead of `int | float`
"RET504", # Unnecessary assignment before return statement
"UP046" # Parameter syntax for generic classes; not supported by mypy: https://github.com/python/mypy/issues/18507
]
[tool.ruff.lint.flake8-pytest-style]
fixture-parentheses = false
mark-parentheses = false
[tool.ruff.lint.isort]
known-first-party = ["saleor"]