pyproject.toml 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. #[build-system] #remove for python2
  2. #requires = ["setuptools>=64.0", "wheel", "setuptools_scm"]
  3. #build-backend = "setuptools.build_meta"
  4. #[tool.setuptools_scm]
  5. #local_scheme = "no-local-version"
  6. [project]
  7. name = "ddns"
  8. dynamic = ["version"]
  9. description = "Dynamic DNS client for multiple providers, supporting IPv4 and IPv6."
  10. authors = [{ name = "NewFuture", email = "[email protected]" }]
  11. readme = "README.md"
  12. license = "MIT"
  13. requires-python = ">=2.7"
  14. classifiers = [
  15. "Development Status :: 5 - Production/Stable",
  16. "Intended Audience :: Developers",
  17. "Intended Audience :: End Users/Desktop",
  18. "Intended Audience :: Information Technology",
  19. "Intended Audience :: System Administrators",
  20. "Topic :: Internet",
  21. "Topic :: Internet :: Name Service (DNS)",
  22. "Topic :: System :: Networking",
  23. "Topic :: Software Development",
  24. 'Programming Language :: Python :: 2.7',
  25. "Programming Language :: Python :: 3",
  26. "Programming Language :: Python :: 3.6",
  27. "Programming Language :: Python :: 3.7",
  28. "Programming Language :: Python :: 3.8",
  29. "Programming Language :: Python :: 3.9",
  30. "Programming Language :: Python :: 3.10",
  31. "Programming Language :: Python :: 3.11",
  32. "Programming Language :: Python :: 3.12",
  33. "Programming Language :: Python :: 3.13",
  34. ]
  35. keywords = ["ddns", "ipv6", "ipv4", "dns", "dnspod", "alidns", "cloudflare"]
  36. dependencies = []
  37. [project.urls]
  38. Homepage = "https://ddns.newfuture.cc"
  39. Documentation = "https://ddns.newfuture.cc"
  40. Repository = "https://github.com/NewFuture/DDNS"
  41. "Bug Tracker" = "https://github.com/NewFuture/DDNS/issues"
  42. Source = "https://github.com/NewFuture/DDNS"
  43. [project.scripts]
  44. ddns = "ddns.__main__:main"
  45. # Optional dependencies
  46. [project.optional-dependencies]
  47. dev = [
  48. "ruff",
  49. "mock;python_version<'3.3'", # For Python 2.7 compatibility
  50. ]
  51. # 可选的 pytest 支持(不是默认测试框架)
  52. pytest = [
  53. "pytest>=6.0",
  54. "pytest-cov",
  55. "mock;python_version<'3.3'",
  56. ]
  57. # Setuptools configuration
  58. [tool.setuptools]
  59. platforms = ["any"]
  60. packages = ["ddns", "ddns.config", "ddns.provider", "ddns.scheduler", "ddns.util"]
  61. package-dir= {"ddns" = "ddns"}
  62. #[tool.setuptools.packages.find]
  63. #where = ["."]
  64. [tool.setuptools.dynamic]
  65. version = { attr = "ddns.__version__" }
  66. # description = { attr = "ddns.__description__" }
  67. # 测试配置 - 使用 unittest 作为默认测试框架
  68. [tool.unittest]
  69. start-directory = "tests"
  70. pattern = "test_*.py"
  71. # unittest 不需要额外配置,使用内置的 test discovery
  72. # pytest 兼容配置(保持与 pytest 的兼容性)
  73. [tool.pytest.ini_options]
  74. testpaths = ["tests"]
  75. python_files = ["test_*.py"]
  76. python_classes = ["Test*"]
  77. python_functions = ["test_*"]
  78. addopts = ["-v", "--tb=short"]
  79. # 确保 pytest 可以找到 test_base 模块
  80. pythonpath = [".", "tests"]
  81. # Ruff configuration - unified formatting and linting
  82. [tool.ruff]
  83. # Same line length as black was using
  84. line-length = 120
  85. # Ruff minimum supported version is py37, but project supports py27+
  86. target-version = "py37"
  87. exclude = [
  88. ".eggs",
  89. ".git",
  90. ".hg",
  91. ".mypy_cache",
  92. ".tox",
  93. ".venv",
  94. "build",
  95. "dist",
  96. "__pycache__",
  97. "*.egg-info",
  98. ]
  99. [tool.ruff.lint]
  100. # Enable pycodestyle (E, W), pyflakes (F), and mccabe (C) - same as flake8 defaults
  101. # Deliberately exclude pyupgrade (UP) rules to maintain Python 2 compatibility
  102. # (UP rules would convert u"" strings to "" which breaks py2 compatibility)
  103. select = ["E", "W", "F", "C"]
  104. # Same ignores as flake8 configuration, but using ruff rule codes
  105. ignore = [
  106. # "E203", # whitespace before ':' - not needed in ruff, formatter handles this
  107. "E501", # line too long (handled by formatter)
  108. "UP025", # unicode-kind-prefix (keep u"..." for Py2 compatibility)
  109. ]
  110. # Same max complexity as flake8
  111. mccabe = { max-complexity = 12 }
  112. [tool.ruff.lint.per-file-ignores]
  113. # Allow unused imports and redefined names in tests (same as flake8)
  114. "tests/*" = ["F401", "F811"]
  115. [tool.ruff.format]
  116. line-ending = "auto"
  117. indent-style = "space"
  118. quote-style = "double"
  119. skip-magic-trailing-comma = true # py2
  120. docstring-code-format = true
  121. docstring-code-line-length = "dynamic"
  122. # 类型检查配置
  123. [tool.pyright]
  124. typeCheckingMode = "standard"
  125. autoImportCompletions = true
  126. autoFormatStrings = true
  127. completeFunctionParens = true
  128. supportAllPythonDocuments = true
  129. importFormat = "relative"
  130. generateWithTypeAnnotation = true
  131. diagnosticMode = "workspace"
  132. indexing = true
  133. useLibraryCodeForTypes = true
  134. # Coverage configuration (可选,仅在使用 pytest-cov 时需要)
  135. # 要使用覆盖率报告,需要安装: pip install pytest pytest-cov
  136. # 然后运行: pytest tests/ --cov=ddns --cov-report=term-missing
  137. [tool.coverage.run]
  138. source = ["ddns"]
  139. omit = [
  140. "*/tests/*",
  141. "*/test_*",
  142. "*/__pycache__/*",
  143. "*/.*",
  144. ]
  145. [tool.coverage.report]
  146. exclude_lines = [
  147. "pragma: no cover",
  148. "def __repr__",
  149. "if self.debug:",
  150. "if settings.DEBUG",
  151. "raise AssertionError",
  152. "raise NotImplementedError",
  153. "if 0:",
  154. "if __name__ == .__main__.:",
  155. "class .*\\bProtocol\\):",
  156. "@(abc\\.)?abstractmethod",
  157. ]
  158. show_missing = true
  159. precision = 2