tina4-python 3.11.11__tar.gz → 3.11.12__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. {tina4_python-3.11.11 → tina4_python-3.11.12}/PKG-INFO +1 -1
  2. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/__init__.py +1 -1
  3. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/core/server.py +11 -3
  4. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/database/connection.py +55 -15
  5. {tina4_python-3.11.11 → tina4_python-3.11.12}/.gitignore +0 -0
  6. {tina4_python-3.11.11 → tina4_python-3.11.12}/README.md +0 -0
  7. {tina4_python-3.11.11 → tina4_python-3.11.12}/pyproject.toml +0 -0
  8. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/CLAUDE.md +0 -0
  9. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/HtmlElement.py +0 -0
  10. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/Testing.py +0 -0
  11. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/ai/__init__.py +0 -0
  12. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/api/__init__.py +0 -0
  13. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/auth/__init__.py +0 -0
  14. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/cache/__init__.py +0 -0
  15. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/cli/__init__.py +0 -0
  16. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/container/__init__.py +0 -0
  17. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/core/__init__.py +0 -0
  18. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/core/cache.py +0 -0
  19. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/core/constants.py +0 -0
  20. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/core/events.py +0 -0
  21. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/core/middleware.py +0 -0
  22. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/core/rate_limiter.py +0 -0
  23. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/core/request.py +0 -0
  24. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/core/response.py +0 -0
  25. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/core/router.py +0 -0
  26. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/crud/__init__.py +0 -0
  27. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/database/__init__.py +0 -0
  28. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/database/adapter.py +0 -0
  29. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/database/firebird.py +0 -0
  30. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/database/mongodb.py +0 -0
  31. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/database/mssql.py +0 -0
  32. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/database/mysql.py +0 -0
  33. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/database/odbc.py +0 -0
  34. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/database/postgres.py +0 -0
  35. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/database/sqlite.py +0 -0
  36. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/debug/__init__.py +0 -0
  37. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/debug/error_overlay.py +0 -0
  38. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/dev_admin/__init__.py +0 -0
  39. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/dev_admin/metrics.py +0 -0
  40. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/dotenv/__init__.py +0 -0
  41. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/frond/FROND.md +0 -0
  42. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/frond/__init__.py +0 -0
  43. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/frond/engine.py +0 -0
  44. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/gallery/auth/meta.json +0 -0
  45. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/gallery/auth/src/routes/api/gallery_auth.py +0 -0
  46. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/gallery/database/meta.json +0 -0
  47. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/gallery/database/src/routes/api/gallery_db.py +0 -0
  48. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/gallery/error-overlay/meta.json +0 -0
  49. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/gallery/error-overlay/src/routes/api/gallery_crash.py +0 -0
  50. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/gallery/orm/meta.json +0 -0
  51. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/gallery/orm/src/orm/Product.py +0 -0
  52. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/gallery/orm/src/routes/api/gallery_products.py +0 -0
  53. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/gallery/queue/meta.json +0 -0
  54. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/gallery/queue/src/routes/api/gallery_queue.py +0 -0
  55. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/gallery/rest-api/meta.json +0 -0
  56. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/gallery/rest-api/src/routes/api/gallery_hello.py +0 -0
  57. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/gallery/templates/meta.json +0 -0
  58. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/gallery/templates/src/routes/gallery_page.py +0 -0
  59. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/gallery/templates/src/templates/gallery_page.twig +0 -0
  60. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/graphql/__init__.py +0 -0
  61. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/i18n/__init__.py +0 -0
  62. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/mcp/__init__.py +0 -0
  63. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/mcp/protocol.py +0 -0
  64. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/mcp/tools.py +0 -0
  65. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/messenger/__init__.py +0 -0
  66. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/migration/__init__.py +0 -0
  67. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/migration/runner.py +0 -0
  68. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/orm/__init__.py +0 -0
  69. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/orm/fields.py +0 -0
  70. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/orm/model.py +0 -0
  71. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/public/css/tina4.css +0 -0
  72. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/public/css/tina4.min.css +0 -0
  73. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/public/favicon.ico +0 -0
  74. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/public/images/logo.svg +0 -0
  75. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/public/images/tina4-logo-icon.webp +0 -0
  76. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/public/js/frond.min.js +0 -0
  77. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/public/js/tina4-dev-admin.js +0 -0
  78. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/public/js/tina4-dev-admin.min.js +0 -0
  79. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/public/js/tina4.min.js +0 -0
  80. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/public/js/tina4js.min.js +0 -0
  81. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/public/swagger/index.html +0 -0
  82. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/public/swagger/oauth2-redirect.html +0 -0
  83. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/query_builder/__init__.py +0 -0
  84. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/queue/__init__.py +0 -0
  85. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/queue/job.py +0 -0
  86. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/queue/kafka_backend.py +0 -0
  87. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/queue/lite_backend.py +0 -0
  88. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/queue/mongo_backend.py +0 -0
  89. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/queue/rabbitmq_backend.py +0 -0
  90. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/queue_backends/__init__.py +0 -0
  91. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/queue_backends/kafka_backend.py +0 -0
  92. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/queue_backends/mongo_backend.py +0 -0
  93. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/queue_backends/rabbitmq_backend.py +0 -0
  94. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/scss/__init__.py +0 -0
  95. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/scss/tina4css/_alerts.scss +0 -0
  96. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/scss/tina4css/_badges.scss +0 -0
  97. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/scss/tina4css/_buttons.scss +0 -0
  98. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/scss/tina4css/_cards.scss +0 -0
  99. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/scss/tina4css/_forms.scss +0 -0
  100. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/scss/tina4css/_grid.scss +0 -0
  101. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/scss/tina4css/_modals.scss +0 -0
  102. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/scss/tina4css/_nav.scss +0 -0
  103. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/scss/tina4css/_reset.scss +0 -0
  104. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/scss/tina4css/_tables.scss +0 -0
  105. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/scss/tina4css/_typography.scss +0 -0
  106. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/scss/tina4css/_utilities.scss +0 -0
  107. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/scss/tina4css/_variables.scss +0 -0
  108. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/scss/tina4css/base.scss +0 -0
  109. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/scss/tina4css/colors.scss +0 -0
  110. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/scss/tina4css/tina4.scss +0 -0
  111. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/seeder/__init__.py +0 -0
  112. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/service/__init__.py +0 -0
  113. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/session/__init__.py +0 -0
  114. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/session_handlers/__init__.py +0 -0
  115. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/session_handlers/mongodb_handler.py +0 -0
  116. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/session_handlers/redis_handler.py +0 -0
  117. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/session_handlers/valkey_handler.py +0 -0
  118. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/swagger/__init__.py +0 -0
  119. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/templates/components/crud.twig +0 -0
  120. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/templates/docker/distroless/Dockerfile +0 -0
  121. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/templates/docker/poetry/Dockerfile +0 -0
  122. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/templates/docker/python/Dockerfile +0 -0
  123. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/templates/docker/uv/Dockerfile +0 -0
  124. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/templates/errors/302.twig +0 -0
  125. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/templates/errors/401.twig +0 -0
  126. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/templates/errors/403.twig +0 -0
  127. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/templates/errors/404.twig +0 -0
  128. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/templates/errors/500.twig +0 -0
  129. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/templates/errors/502.twig +0 -0
  130. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/templates/errors/503.twig +0 -0
  131. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/templates/errors/base.twig +0 -0
  132. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/templates/frontend/README.md +0 -0
  133. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/templates/readme.md +0 -0
  134. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/test_client/__init__.py +0 -0
  135. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/translations/af/LC_MESSAGES/messages.mo +0 -0
  136. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/translations/af/LC_MESSAGES/messages.po +0 -0
  137. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/translations/en/LC_MESSAGES/messages.mo +0 -0
  138. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/translations/en/LC_MESSAGES/messages.po +0 -0
  139. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/translations/es/LC_MESSAGES/messages.mo +0 -0
  140. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/translations/es/LC_MESSAGES/messages.po +0 -0
  141. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/translations/fr/LC_MESSAGES/messages.mo +0 -0
  142. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/translations/fr/LC_MESSAGES/messages.po +0 -0
  143. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/translations/ja/LC_MESSAGES/messages.mo +0 -0
  144. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/translations/ja/LC_MESSAGES/messages.po +0 -0
  145. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/translations/zh/LC_MESSAGES/messages.mo +0 -0
  146. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/translations/zh/LC_MESSAGES/messages.po +0 -0
  147. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/validator/__init__.py +0 -0
  148. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/websocket/__init__.py +0 -0
  149. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/websocket/backplane.py +0 -0
  150. {tina4_python-3.11.11 → tina4_python-3.11.12}/tina4_python/wsdl/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tina4-python
3
- Version: 3.11.11
3
+ Version: 3.11.12
4
4
  Summary: Tina4 for Python — 54 built-in features, zero dependencies
5
5
  Author-email: Andre van Zuydam <andrevanzuydam@gmail.com>
6
6
  License: MIT
@@ -8,7 +8,7 @@ Tina4 Python v3.0 — Zero-dependency, lightweight web framework.
8
8
 
9
9
  One import, everything works.
10
10
  """
11
- __version__ = "3.11.11"
11
+ __version__ = "3.11.12"
12
12
 
13
13
  # ── Route decorators ──
14
14
  from tina4_python.core.router import ( # noqa: E402, F401
@@ -73,12 +73,20 @@ def _auto_discover(root_dir: str = "src"):
73
73
 
74
74
 
75
75
  def _ensure_folders():
76
- """Create project folders if missing (auto-repair)."""
76
+ """Create project folders if missing (auto-repair).
77
+
78
+ Note: ``migrations/`` lives at the project root (matches the CLI's
79
+ ``migrations`` default and the documented project structure), never
80
+ under ``src/``. Don't add ``src/migrations`` here — it creates an
81
+ empty directory that the migration runner ignores and confuses users.
82
+ """
77
83
  folders = [
78
- "src/routes", "src/orm", "src/migrations", "src/seeds",
84
+ "src/routes", "src/orm", "src/seeds",
79
85
  "src/templates", "src/templates/errors",
80
86
  "src/public", "src/public/js", "src/public/css", "src/public/icons",
81
- "src/locales", "data", "data/.broken", "logs", "secrets", "tests",
87
+ "src/locales",
88
+ "migrations",
89
+ "data", "data/.broken", "logs", "secrets", "tests",
82
90
  ]
83
91
  for folder in folders:
84
92
  Path(folder).mkdir(parents=True, exist_ok=True)
@@ -195,27 +195,67 @@ class Database:
195
195
  return _DRIVERS[scheme]()
196
196
 
197
197
  def _connection_path(self) -> str:
198
- """Extract connection-specific path/params from the URL."""
198
+ """Extract connection-specific path/params from the URL.
199
+
200
+ SQLite URL convention (matches PHP and the Python CLAUDE.md docs):
201
+
202
+ sqlite::memory: → in-memory database
203
+ sqlite:///:memory: → in-memory database (URL form)
204
+ sqlite:///app.db → ./app.db (relative to cwd)
205
+ sqlite:///data/app.db → ./data/app.db (relative)
206
+ sqlite:///./data/app.db → ./data/app.db (relative, explicit)
207
+ sqlite:////absolute/path.db → /absolute/path.db (absolute)
208
+ sqlite:///C:/Users/app.db → C:/Users/app.db (Windows absolute)
209
+
210
+ Directories are auto-created ONLY when the resolved path is
211
+ inside the current working directory (the project root). We
212
+ never try to ``os.makedirs`` at root (``/data``, ``C:\\data``)
213
+ — that's both hostile on read-only filesystems and not what
214
+ any project actually wants.
215
+ """
199
216
  parsed = urlparse(self.url)
200
217
 
201
- if parsed.scheme.startswith("sqlite"):
202
- # urlparse("sqlite:///path").path = "/path"
203
- # Strip the leading / only when it precedes a Windows drive
204
- # letter (e.g. /C:/Users/app.db → C:/Users/app.db). On Linux
205
- # the leading / is the root directory and must be kept.
206
- path = parsed.path
207
- if len(path) >= 3 and path[0] == "/" and path[1].isalpha() and path[2] == ":":
208
- path = path[1:] # Windows: /C:/... → C:/...
218
+ if not parsed.scheme.startswith("sqlite"):
219
+ # For other drivers, return the full URL (adapter parses it)
220
+ return self.url
221
+
222
+ # In-memory forms passthrough
223
+ raw_path = parsed.path
224
+ if raw_path in (":memory:", "/:memory:"):
225
+ return ":memory:"
209
226
 
210
- # Ensure directory exists
227
+ # Strip exactly one leading "/" — the URL "/"-delimiter between the
228
+ # empty netloc and the start of the path.
229
+ if raw_path.startswith("/"):
230
+ stripped = raw_path[1:]
231
+ else:
232
+ stripped = raw_path
233
+
234
+ # Windows absolute path (drive-letter form): C:/... or C:\...
235
+ is_windows_abs = (
236
+ len(stripped) >= 3
237
+ and stripped[0].isalpha()
238
+ and stripped[1] == ":"
239
+ and stripped[2] in ("/", "\\")
240
+ )
241
+ # Unix absolute path: urlparse("sqlite:////abs/app.db").path == "//abs/app.db"
242
+ # After one strip it's still "/abs/app.db" → still starts with "/".
243
+ is_unix_abs = stripped.startswith("/")
244
+
245
+ if is_windows_abs or is_unix_abs:
246
+ path = stripped
247
+ # Don't auto-create directories outside cwd. If the user gave
248
+ # an absolute path, they're responsible for it existing.
249
+ else:
250
+ # Relative — resolve under the project root (cwd).
251
+ cwd = os.getcwd()
252
+ path = os.path.join(cwd, stripped)
253
+ # Only auto-create subdirectories *inside* cwd.
211
254
  directory = os.path.dirname(path)
212
- if directory:
255
+ if directory and os.path.commonpath([os.path.abspath(directory), cwd]) == cwd:
213
256
  os.makedirs(directory, exist_ok=True)
214
257
 
215
- return path
216
-
217
- # For other drivers, return the full URL (adapter parses it)
218
- return self.url
258
+ return path
219
259
 
220
260
  # ── Query Cache ──────────────────────────────────────────────
221
261
 
File without changes