Codebase list django-environ / fresh-releases/main
New upstream release. Debian Janitor 8 months ago
35 changed file(s) with 714 addition(s) and 264 deletion(s). Raw diff Collapse all Expand all
44 - package-ecosystem: pip
55 # setup.py stored in repository root.
66 directory: '/'
7 # Raise pull requests for version updates
8 # to pip against the `develop` branch
9 target-branch: develop
710 schedule:
8 interval: daily
11 # Check for updates managed by pip once a week
12 interval: weekly
13 # Specify labels for npm pull requests
14 labels:
15 - pip
16 - dependencies
917 assignees:
1018 - sergeyklay
1119
1321 # Workflow files stored in the
1422 # default location of `.github/workflows`
1523 directory: '/'
24 # Raise pull requests for version updates
25 # to pip against the `develop` branch
26 target-branch: develop
1627 schedule:
17 interval: daily
28 # Check for updates for GitHub actions once a week
29 interval: weekly
30 # Specify labels for npm pull requests
31 labels:
32 - github_actions
33 - dependencies
1834 assignees:
1935 - sergeyklay
11
22 on:
33 push:
4 branches:
5 - develop
6 - main
7 - 'feature/**'
8 - 'release/**'
9 - 'fix/**'
4 branches-ignore:
5 # These should always correspond to pull requests, so ignore them for
6 # the push trigger and let them be triggered by the pull_request
7 # trigger, avoiding running the workflow twice. This is a minor
8 # optimization so there's no need to ensure this is comprehensive.
9 - 'dependabot/**'
1010 tags:
1111 - 'v[0-9]+.[0-9]+.[0-9]+'
1212
13 # The branches below must be a subset of the branches above
1314 pull_request:
1415 branches:
1516 - develop
1819 jobs:
1920 build:
2021 name: Build and test package distribution
21 runs-on: ${{ matrix.os }}
22
23 strategy:
24 matrix:
25 os: [ ubuntu-latest, macos-latest, windows-latest ]
22 runs-on: ubuntu-latest
2623
2724 steps:
2825 - name: Checkout code
29 uses: actions/checkout@v3.0.2
26 uses: actions/checkout@v3.3.0
3027
3128 - name: Set up Python 3.10
32 uses: actions/setup-python@v4.0.0
29 uses: actions/setup-python@v4.5.0
3330 with:
3431 python-version: '3.10'
3532
6663
6764 steps:
6865 - name: Checkout code
69 uses: actions/checkout@v3.0.2
66 uses: actions/checkout@v3.3.0
7067
7168 - name: Set up Python 3.10
72 uses: actions/setup-python@v4.0.0
69 uses: actions/setup-python@v4.5.0
7370 with:
7471 python-version: '3.10'
7572
0 name: Make sure new PRs are sent to develop
1
2 on:
3 pull_request_target:
4 types: [opened, edited]
5
6 jobs:
7 check-branch:
8 runs-on: ubuntu-latest
9 steps:
10 - uses: Vankka/pr-target-branch-action@v2
11 env:
12 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
13 with:
14 target: main
15 exclude: develop # Don't prevent going from develop -> main
16 change-to: develop
17 comment: |
18 Your PR was set to target `main`, PRs should be target `develop`
19 The base branch of this PR has been automatically changed to `develop`, please check that there are no merge conflicts.
11
22 on:
33 push:
4 branches:
5 - develop
6 - main
7 - 'feature/**'
8 - 'release/**'
9 - 'fix/**'
4 branches-ignore:
5 # These should always correspond to pull requests, so ignore them for
6 # the push trigger and let them be triggered by the pull_request
7 # trigger, avoiding running the workflow twice. This is a minor
8 # optimization so there's no need to ensure this is comprehensive.
9 - 'dependabot/**'
1010
11 # The branches below must be a subset of the branches above
1112 pull_request:
1213 branches:
1314 - develop
4546
4647 matrix:
4748 python:
48 - '3.5'
49 - '3.6'
50 - '3.7'
5149 - '3.8'
5250 - '3.9'
5351 - '3.10'
52 - '3.11'
5453 - 'pypy-3.7'
5554 os: [ ubuntu-latest, macos-latest, windows-latest ]
5655
56 # These versions are no longer supported by Python team, and may
57 # eventually be dropped from GitHub Actions. The support of these
58 # versions by django-environ will continue for as long as possible,
59 # and may be discontinued at any time.
60 include:
61 - python: '3.5'
62 os: ubuntu-20.04
63 - python: '3.6'
64 os: ubuntu-20.04
65 - python: '3.7'
66 os: ubuntu-20.04
67
5768 steps:
5869 - name: Checkout code
59 uses: actions/checkout@v3.0.2
70 uses: actions/checkout@v3.3.0
6071 with:
6172 fetch-depth: 5
6273
6374 - name: Set up Python ${{ matrix.python }}
64 uses: actions/setup-python@v4.0.0
75 uses: actions/setup-python@v4.5.0
6576 with:
6677 python-version: ${{ matrix.python }}
6778
0 name: CodeQL
1
2 on:
3 push:
4 branches:
5 - develop
6 - main
7
8 # The branches below must be a subset of the branches above
9 pull_request:
10 branches:
11 - develop
12 - main
13
14 schedule:
15 - cron: '40 22 * * 5'
16 # | | | | |
17 # | | | | |____ day of the week (0 - 6 or SUN-SAT)
18 # | | | |____ month (1 - 12 or JAN-DEC)
19 # | | |____ day of the month (1 - 31)
20 # | |____ hour (0 - 23)
21 # |____ minute (0 - 59)
22
23 jobs:
24 analyze:
25 name: Analyze
26 runs-on: ubuntu-latest
27 permissions:
28 actions: read
29 contents: read
30 security-events: write
31
32 # The maximum number of minutes to let a workflow run
33 # before GitHub automatically cancels it. Default: 360
34 timeout-minutes: 30
35
36 strategy:
37 # When set to true, GitHub cancels
38 # all in-progress jobs if any matrix job fails.
39 fail-fast: false
40
41 matrix:
42 language:
43 - python
44
45 steps:
46 - name: Checkout repository
47 uses: actions/checkout@v3.3.0
48
49 # Initializes the CodeQL tools for scanning.
50 - name: Initialize CodeQL
51 uses: github/codeql-action/init@v2
52 with:
53 languages: ${{ matrix.language }}
54
55 - name: Autobuild
56 uses: github/codeql-action/autobuild@v2
57
58 - name: Perform CodeQL Analysis
59 uses: github/codeql-action/analyze@v2
11
22 on:
33 push:
4 branches:
5 - develop
6 - main
7 - 'feature/**'
8 - 'release/**'
9 - 'fix/**'
4 branches-ignore:
5 # These should always correspond to pull requests, so ignore them for
6 # the push trigger and let them be triggered by the pull_request
7 # trigger, avoiding running the workflow twice. This is a minor
8 # optimization so there's no need to ensure this is comprehensive.
9 - 'dependabot/**'
1010
1111 pull_request:
1212 branches:
1818 runs-on: ubuntu-latest
1919 name: Code linting
2020
21 # The maximum number of minutes to let a workflow run
22 # before GitHub automatically cancels it. Default: 360
23 timeout-minutes: 30
24
2125 steps:
2226 - name: Checkout code
23 uses: actions/checkout@v3.0.2
27 uses: actions/checkout@v3.3.0
2428
2529 - name: Set up Python 3.10
26 uses: actions/setup-python@v4.0.0
30 uses: actions/setup-python@v4.5.0
2731 with:
2832 python-version: '3.10'
2933
11
22 on:
33 push:
4 branches:
5 - develop
6 - main
7 - 'feature/**'
8 - 'release/**'
9 - 'fix/**'
4 branches-ignore:
5 # These should always correspond to pull requests, so ignore them for
6 # the push trigger and let them be triggered by the pull_request
7 # trigger, avoiding running the workflow twice. This is a minor
8 # optimization so there's no need to ensure this is comprehensive.
9 - 'dependabot/**'
1010
11 # The branches below must be a subset of the branches above
1112 pull_request:
1213 branches:
1314 - develop
1819 runs-on: ubuntu-latest
1920 name: Build and test package documentation
2021
22 # The maximum number of minutes to let a workflow run
23 # before GitHub automatically cancels it. Default: 360
24 timeout-minutes: 30
25
2126 steps:
2227 - name: Checkout code
23 uses: actions/checkout@v3.0.2
28 uses: actions/checkout@v3.3.0
2429
2530 - name: Set up Python 3.10
26 uses: actions/setup-python@v4.0.0
31 uses: actions/setup-python@v4.5.0
2732 with:
2833 python-version: '3.10'
2934
44 The format is inspired by `Keep a Changelog <https://keepachangelog.com/en/1.0.0/>`_
55 and this project adheres to `Semantic Versioning <https://semver.org/spec/v2.0.0.html>`_.
66
7 `v0.10.0`_ - 2-March-2023
8 -------------------------------
9 Added
10 +++++
11 - Use the core redis library by default if running Django >= 4.0
12 `#356 <https://github.com/joke2k/django-environ/issues/356>`_.
13 - Value of dict can now contain an equal sign
14 `#241 <https://github.com/joke2k/django-environ/pull/241>`_.
15 - Added support for Python 3.11.
16 - Added ``CONN_HEALTH_CHECKS`` to database base options
17 `#413 <https://github.com/joke2k/django-environ/issues/413>`_.
18 - Added ``encoding`` parameter to ``read_env`` with default value 'utf8'
19 `#442 <https://github.com/joke2k/django-environ/pull/442>`_.
20 - Added support for Django 4.1
21 `#416 <https://github.com/joke2k/django-environ/issues/416>`_.
22
23 Deprecated
24 ++++++++++
25 - Support of Python < 3.6 is deprecated and will be removed
26 in next major version.
27
28 Changed
29 +++++++
30 - Used UTF-8 as a encoding when open ``.env`` file.
31 - Provided access to ```DB_SCHEMES`` through ``cls`` rather than
32 ``Env`` in ``db_url_config``
33 `#414 <https://github.com/joke2k/django-environ/pull/414>`_.
34 - Correct CI workflow to use supported Python versions/OS matrix
35 `#441 <https://github.com/joke2k/django-environ/pull/441>`_.
36 - Reworked trigger CI workflows strategy
37 `#440 <https://github.com/joke2k/django-environ/pull/440>`_.
38
39 Fixed
40 +++++
41 - Fixed logic of ``Env.get_value()`` to skip parsing only when
42 ``default=None``, not for all default values that coerce to ``False``
43 `#404 <https://github.com/joke2k/django-environ/issues/404>`_.
44 - Deleted duplicated include in docs/quickstart.rst
45 `#439 <https://github.com/joke2k/django-environ/pull/439>`_.
46
47 Removed
48 +++++++
49 - Removed deprecated ``Env.unicode()``.
50 - Removed ``environ.register_schemes`` calls and do not modify global
51 ``urllib.parse.urlparse``'s ``uses_*`` variables as this no longer needed
52 `#246 <https://github.com/joke2k/django-environ/pull/246>`_.
53
54
755 `v0.9.0`_ - 15-June-2022
8 ------------------------------
56 ------------------------
957 Added
1058 +++++
1159 - Added support for Postgresql cluster URI
1664 `#362 <https://github.com/joke2k/django-environ/issues/362>`_.
1765 - Amended documentation.
1866
19
2067 Deprecated
2168 ++++++++++
2269 - ``Env.unicode()`` is deprecated and will be removed in the next
2370 major release. Use ``Env.str()`` instead.
2471
25
2672 Changed
2773 +++++++
2874 - Attach cause to ``ImproperlyConfigured`` exception
2975 `#360 <https://github.com/joke2k/django-environ/issues/360>`_.
30
3176
3277 Fixed
3378 +++++
5499 ---------------------------
55100 Added
56101 +++++
57 - Log invalid lines when parse .env file
102 - Log invalid lines when parse ``.env`` file
58103 `#283 <https://github.com/joke2k/django-environ/pull/283>`_.
59104 - Added docker-style file variable support
60105 `#189 <https://github.com/joke2k/django-environ/issues/189>`_.
66111 - Added ``pymemcache`` cache backend for Django 3.2+
67112 `#335 <https://github.com/joke2k/django-environ/pull/335>`_.
68113
69
70114 Fixed
71115 +++++
72116 - Keep newline/tab escapes in quoted strings
190234 +++++
191235 - Fix Path subtracting.
192236
193
194237 `v0.4.3`_ - 21-August-2017
195238 --------------------------
196239 Changed
197240 +++++++
198241 - Rollback the default Environ to ``os.environ``.
242
199243
200244 `v0.4.2`_ - 13-April-2017
201245 -------------------------
210254 `#55 <https://github.com/joke2k/django-environ/issues/55>`_.
211255 - Update support for ``django-redis`` urls
212256 `#109 <https://github.com/joke2k/django-environ/pull/109>`_.
257
213258
214259 `v0.4.1`_ - 13-November-2016
215260 ----------------------------
225270 - Fixed support for Oracle urls.
226271 - Fixed support for ``django-redis``.
227272
273
228274 `v0.4`_ - 23-September-2015
229275 ---------------------------
230276 Added
268314 +++++++
269315 - Rewriting README.rst.
270316
317
271318 v0.2.1 - 19-April-2013
272319 ----------------------
273320 Changed
274321 +++++++
275322 - ``Env.__call__`` now uses ``Env.get_value`` instance method.
276323
324
277325 v0.2 - 16-April-2013
278326 --------------------
279327 Added
284332 +++++
285333 - Fixed typos in the documentation.
286334
335
287336 v0.1 - 2-April-2013
288337 -------------------
289338 Added
291340 - Initial release.
292341
293342
343 .. _v0.10.0: https://github.com/joke2k/django-environ/compare/v0.9.0...develop
294344 .. _v0.9.0: https://github.com/joke2k/django-environ/compare/v0.8.1...v0.9.0
295345 .. _v0.8.1: https://github.com/joke2k/django-environ/compare/v0.8.0...v0.8.1
296346 .. _v0.8.0: https://github.com/joke2k/django-environ/compare/v0.7.0...v0.8.0
44 `current issues <https://github.com/joke2k/django-environ/issues>`_. If there is
55 a bug or feature that you want but it isn't listed, make an issue and work on it.
66
7 How to Contribute
8 -----------------
7 Bug reports
8 -----------
9
10 *Before raising an issue, please ensure that you are using the latest version
11 of django-environ.*
12
13 Please provide the following information with your issue to enable us to
14 respond as quickly as possible.
15
16 * The relevant versions of the packages you are using.
17 * The steps to recreate your issue.
18 * The full stacktrace if there is an exception.
19 * An executable code example where possible
20
21 Guidelines for bug reports:
22
23 * **Use the GitHub issue search** — check if the issue has already been
24 reported.
25 * **Check if the issue has been fixed** — try to reproduce it using the latest
26 ``main`` or ``develop`` branch in the repository.
27 * Isolate the problem — create a reduced test case and a live example.
28
29 A good bug report shouldn't leave others needing to chase you up for more
30 information. Please try to be as detailed as possible in your report. What is
31 your environment? What steps will reproduce the issue? What OS experience the
32 problem? What would you expect to be the outcome? All these details will help
33 people to fix any potential bugs.
34
35 Feature requests
36 ----------------
37
38 Feature requests are welcome. But take a moment to find out whether your idea
39 fits with the scope and aims of the project. It's up to *you* to make a strong
40 case to convince the project's developers of the merits of this feature. Please
41 provide as much detail and context as possible.
42
43 Pull requests
44 -------------
45
46 Good pull requests - patches, improvements, new features - are a fantastic
47 help. They should remain focused in scope and avoid containing unrelated
48 commits.
49
50 Follow this process if you'd like your work considered for inclusion in the
51 project:
952
1053 1. Check for open issues or open a fresh issue to start a discussion around a
1154 feature idea or a bug.
12 2. Fork `the repository <https://github.com/joke2k/django-environ>`_ on GitHub
13 to start making your changes to the **develop** branch (or branch off of it).
55 2. Fork `the repository <https://github.com/joke2k/django-environ>`_
56 on GitHub to start making your changes to the ``develop`` branch
57 (or branch off of it).
1458 3. Write a test which shows that the bug was fixed or that the feature works as
1559 expected.
1660 4. Send a pull request and bug the maintainer until it gets merged and published.
61
62 If you are intending to implement a fairly large feature we'd appreciate if you
63 open an issue with GitHub detailing your use case and intended solution to
64 discuss how it might impact other work that is in flight.
65
66 We also appreciate it if you take the time to update and write tests for any
67 changes you submit.
68
69 **By submitting a patch, you agree to allow the project owner to license your
70 work under the same license as that used by the project.**
71
72 Resources
73 ---------
74
75 * `How to Contribute to Open Source <https://opensource.guide/how-to-contribute/>`_
76 * `Using Pull Requests <https://help.github.com/articles/about-pull-requests/>`_
77 * `Writing good commit messages <http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html>`_
00 Metadata-Version: 2.1
11 Name: django-environ
2 Version: 0.9.0
2 Version: 0.10.0
33 Summary: A package that allows you to utilize 12factor inspired environment variables to configure your Django application.
44 Home-page: https://django-environ.readthedocs.org
55 Author: Daniele Faraglia
2525 Classifier: Framework :: Django :: 3.1
2626 Classifier: Framework :: Django :: 3.2
2727 Classifier: Framework :: Django :: 4.0
28 Classifier: Framework :: Django :: 4.1
2829 Classifier: Operating System :: OS Independent
2930 Classifier: Intended Audience :: Developers
3031 Classifier: Natural Language :: English
3132 Classifier: Programming Language :: Python
3233 Classifier: Programming Language :: Python :: 3
33 Classifier: Programming Language :: Python :: 3.4
3434 Classifier: Programming Language :: Python :: 3.5
3535 Classifier: Programming Language :: Python :: 3.6
3636 Classifier: Programming Language :: Python :: 3.7
3737 Classifier: Programming Language :: Python :: 3.8
3838 Classifier: Programming Language :: Python :: 3.9
3939 Classifier: Programming Language :: Python :: 3.10
40 Classifier: Programming Language :: Python :: 3.11
4041 Classifier: Programming Language :: Python :: Implementation :: CPython
4142 Classifier: Programming Language :: Python :: Implementation :: PyPy
4243 Classifier: Topic :: Software Development :: Libraries :: Python Modules
4344 Classifier: Topic :: Utilities
4445 Classifier: License :: OSI Approved :: MIT License
45 Requires-Python: >=3.4,<4
46 Requires-Python: >=3.5,<4
4647 Description-Content-Type: text/x-rst
4748 Provides-Extra: testing
4849 Provides-Extra: docs
155156 and the latest release on `PyPI <https://pypi.org/project/django-environ/>`_.
156157
157158 It’s rigorously tested on Python 3.5+, and officially supports
158 Django 1.11, 2.2, 3.0, 3.1, 3.2 and 4.0.
159 Django 1.11, 2.2, 3., 3.1, 3.2, 4.0 and 4.1.
159160
160161 If you'd like to contribute to ``django-environ`` you're most welcome!
161162
176177 `current issues <https://github.com/joke2k/django-environ/issues>`_. If there is
177178 a bug or feature that you want but it isn't listed, make an issue and work on it.
178179
179 How to Contribute
180 -----------------
180 Bug reports
181 -----------
182
183 *Before raising an issue, please ensure that you are using the latest version
184 of django-environ.*
185
186 Please provide the following information with your issue to enable us to
187 respond as quickly as possible.
188
189 * The relevant versions of the packages you are using.
190 * The steps to recreate your issue.
191 * The full stacktrace if there is an exception.
192 * An executable code example where possible
193
194 Guidelines for bug reports:
195
196 * **Use the GitHub issue search** — check if the issue has already been
197 reported.
198 * **Check if the issue has been fixed** — try to reproduce it using the latest
199 ``main`` or ``develop`` branch in the repository.
200 * Isolate the problem — create a reduced test case and a live example.
201
202 A good bug report shouldn't leave others needing to chase you up for more
203 information. Please try to be as detailed as possible in your report. What is
204 your environment? What steps will reproduce the issue? What OS experience the
205 problem? What would you expect to be the outcome? All these details will help
206 people to fix any potential bugs.
207
208 Feature requests
209 ----------------
210
211 Feature requests are welcome. But take a moment to find out whether your idea
212 fits with the scope and aims of the project. It's up to *you* to make a strong
213 case to convince the project's developers of the merits of this feature. Please
214 provide as much detail and context as possible.
215
216 Pull requests
217 -------------
218
219 Good pull requests - patches, improvements, new features - are a fantastic
220 help. They should remain focused in scope and avoid containing unrelated
221 commits.
222
223 Follow this process if you'd like your work considered for inclusion in the
224 project:
181225
182226 1. Check for open issues or open a fresh issue to start a discussion around a
183227 feature idea or a bug.
184 2. Fork `the repository <https://github.com/joke2k/django-environ>`_ on GitHub
185 to start making your changes to the **develop** branch (or branch off of it).
228 2. Fork `the repository <https://github.com/joke2k/django-environ>`_
229 on GitHub to start making your changes to the ``develop`` branch
230 (or branch off of it).
186231 3. Write a test which shows that the bug was fixed or that the feature works as
187232 expected.
188233 4. Send a pull request and bug the maintainer until it gets merged and published.
189234
235 If you are intending to implement a fairly large feature we'd appreciate if you
236 open an issue with GitHub detailing your use case and intended solution to
237 discuss how it might impact other work that is in flight.
238
239 We also appreciate it if you take the time to update and write tests for any
240 changes you submit.
241
242 **By submitting a patch, you agree to allow the project owner to license your
243 work under the same license as that used by the project.**
244
245 Resources
246 ---------
247
248 * `How to Contribute to Open Source <https://opensource.guide/how-to-contribute/>`_
249 * `Using Pull Requests <https://help.github.com/articles/about-pull-requests/>`_
250 * `Writing good commit messages <http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html>`_
251
190252
191253 Release Information
192254 ===================
193255
194 v0.9.0 - 15-June-2022
195 ------------------------------
256 v0.10.0 - 2-March-2023
257 -------------------------------
196258 Added
197259 +++++
198 - Added support for Postgresql cluster URI
199 `#355 <https://github.com/joke2k/django-environ/pull/355>`_.
200 - Added support for Django 4.0
201 `#371 <https://github.com/joke2k/django-environ/issues/371>`_.
202 - Added support for prefixed variables
203 `#362 <https://github.com/joke2k/django-environ/issues/362>`_.
204 - Amended documentation.
205
260 - Use the core redis library by default if running Django >= 4.0
261 `#356 <https://github.com/joke2k/django-environ/issues/356>`_.
262 - Value of dict can now contain an equal sign
263 `#241 <https://github.com/joke2k/django-environ/pull/241>`_.
264 - Added support for Python 3.11.
265 - Added ``CONN_HEALTH_CHECKS`` to database base options
266 `#413 <https://github.com/joke2k/django-environ/issues/413>`_.
267 - Added ``encoding`` parameter to ``read_env`` with default value 'utf8'
268 `#442 <https://github.com/joke2k/django-environ/pull/442>`_.
269 - Added support for Django 4.1
270 `#416 <https://github.com/joke2k/django-environ/issues/416>`_.
206271
207272 Deprecated
208273 ++++++++++
209 - ``Env.unicode()`` is deprecated and will be removed in the next
210 major release. Use ``Env.str()`` instead.
211
274 - Support of Python < 3.6 is deprecated and will be removed
275 in next major version.
212276
213277 Changed
214278 +++++++
215 - Attach cause to ``ImproperlyConfigured`` exception
216 `#360 <https://github.com/joke2k/django-environ/issues/360>`_.
217
279 - Used UTF-8 as a encoding when open ``.env`` file.
280 - Provided access to ```DB_SCHEMES`` through ``cls`` rather than
281 ``Env`` in ``db_url_config``
282 `#414 <https://github.com/joke2k/django-environ/pull/414>`_.
283 - Correct CI workflow to use supported Python versions/OS matrix
284 `#441 <https://github.com/joke2k/django-environ/pull/441>`_.
285 - Reworked trigger CI workflows strategy
286 `#440 <https://github.com/joke2k/django-environ/pull/440>`_.
218287
219288 Fixed
220289 +++++
221 - Fixed ``_cast_urlstr`` unquoting
222 `#357 <https://github.com/joke2k/django-environ/issues/357>`_.
223 - Fixed documentation regarding unsafe characters in URLs
224 `#220 <https://github.com/joke2k/django-environ/issues/220>`_.
225 - Fixed ``environ.Path.__eq__()`` to compare paths correctly
226 `#86 <https://github.com/joke2k/django-environ/issues/86>`_,
227 `#197 <https://github.com/joke2k/django-environ/issues/197>`_.
290 - Fixed logic of ``Env.get_value()`` to skip parsing only when
291 ``default=None``, not for all default values that coerce to ``False``
292 `#404 <https://github.com/joke2k/django-environ/issues/404>`_.
293 - Deleted duplicated include in docs/quickstart.rst
294 `#439 <https://github.com/joke2k/django-environ/pull/439>`_.
295
296 Removed
297 +++++++
298 - Removed deprecated ``Env.unicode()``.
299 - Removed ``environ.register_schemes`` calls and do not modify global
300 ``urllib.parse.urlparse``'s ``uses_*`` variables as this no longer needed
301 `#246 <https://github.com/joke2k/django-environ/pull/246>`_.
228302
229303 `Full changelog <https://django-environ.readthedocs.org/en/latest/changelog.html>`_.
230304
126126 and the latest release on `PyPI <https://pypi.org/project/django-environ/>`_.
127127
128128 It’s rigorously tested on Python 3.5+, and officially supports
129 Django 1.11, 2.2, 3.0, 3.1, 3.2 and 4.0.
129 Django 1.11, 2.2, 3., 3.1, 3.2, 4.0 and 4.1.
130130
131131 If you'd like to contribute to ``django-environ`` you're most welcome!
132132
0 django-environ (0.9.0-1) UNRELEASED; urgency=low
0 django-environ (0.10.0-1) UNRELEASED; urgency=low
11
22 * New upstream release.
3 * New upstream release.
34
4 -- Debian Janitor <janitor@jelmer.uk> Tue, 31 Jan 2023 16:58:43 -0000
5 -- Debian Janitor <janitor@jelmer.uk> Wed, 09 Aug 2023 21:05:02 -0000
56
67 django-environ (0.4.4-5) unstable; urgency=medium
78
00 Metadata-Version: 2.1
11 Name: django-environ
2 Version: 0.9.0
2 Version: 0.10.0
33 Summary: A package that allows you to utilize 12factor inspired environment variables to configure your Django application.
44 Home-page: https://django-environ.readthedocs.org
55 Author: Daniele Faraglia
2525 Classifier: Framework :: Django :: 3.1
2626 Classifier: Framework :: Django :: 3.2
2727 Classifier: Framework :: Django :: 4.0
28 Classifier: Framework :: Django :: 4.1
2829 Classifier: Operating System :: OS Independent
2930 Classifier: Intended Audience :: Developers
3031 Classifier: Natural Language :: English
3132 Classifier: Programming Language :: Python
3233 Classifier: Programming Language :: Python :: 3
33 Classifier: Programming Language :: Python :: 3.4
3434 Classifier: Programming Language :: Python :: 3.5
3535 Classifier: Programming Language :: Python :: 3.6
3636 Classifier: Programming Language :: Python :: 3.7
3737 Classifier: Programming Language :: Python :: 3.8
3838 Classifier: Programming Language :: Python :: 3.9
3939 Classifier: Programming Language :: Python :: 3.10
40 Classifier: Programming Language :: Python :: 3.11
4041 Classifier: Programming Language :: Python :: Implementation :: CPython
4142 Classifier: Programming Language :: Python :: Implementation :: PyPy
4243 Classifier: Topic :: Software Development :: Libraries :: Python Modules
4344 Classifier: Topic :: Utilities
4445 Classifier: License :: OSI Approved :: MIT License
45 Requires-Python: >=3.4,<4
46 Requires-Python: >=3.5,<4
4647 Description-Content-Type: text/x-rst
4748 Provides-Extra: testing
4849 Provides-Extra: docs
155156 and the latest release on `PyPI <https://pypi.org/project/django-environ/>`_.
156157
157158 It’s rigorously tested on Python 3.5+, and officially supports
158 Django 1.11, 2.2, 3.0, 3.1, 3.2 and 4.0.
159 Django 1.11, 2.2, 3., 3.1, 3.2, 4.0 and 4.1.
159160
160161 If you'd like to contribute to ``django-environ`` you're most welcome!
161162
176177 `current issues <https://github.com/joke2k/django-environ/issues>`_. If there is
177178 a bug or feature that you want but it isn't listed, make an issue and work on it.
178179
179 How to Contribute
180 -----------------
180 Bug reports
181 -----------
182
183 *Before raising an issue, please ensure that you are using the latest version
184 of django-environ.*
185
186 Please provide the following information with your issue to enable us to
187 respond as quickly as possible.
188
189 * The relevant versions of the packages you are using.
190 * The steps to recreate your issue.
191 * The full stacktrace if there is an exception.
192 * An executable code example where possible
193
194 Guidelines for bug reports:
195
196 * **Use the GitHub issue search** — check if the issue has already been
197 reported.
198 * **Check if the issue has been fixed** — try to reproduce it using the latest
199 ``main`` or ``develop`` branch in the repository.
200 * Isolate the problem — create a reduced test case and a live example.
201
202 A good bug report shouldn't leave others needing to chase you up for more
203 information. Please try to be as detailed as possible in your report. What is
204 your environment? What steps will reproduce the issue? What OS experience the
205 problem? What would you expect to be the outcome? All these details will help
206 people to fix any potential bugs.
207
208 Feature requests
209 ----------------
210
211 Feature requests are welcome. But take a moment to find out whether your idea
212 fits with the scope and aims of the project. It's up to *you* to make a strong
213 case to convince the project's developers of the merits of this feature. Please
214 provide as much detail and context as possible.
215
216 Pull requests
217 -------------
218
219 Good pull requests - patches, improvements, new features - are a fantastic
220 help. They should remain focused in scope and avoid containing unrelated
221 commits.
222
223 Follow this process if you'd like your work considered for inclusion in the
224 project:
181225
182226 1. Check for open issues or open a fresh issue to start a discussion around a
183227 feature idea or a bug.
184 2. Fork `the repository <https://github.com/joke2k/django-environ>`_ on GitHub
185 to start making your changes to the **develop** branch (or branch off of it).
228 2. Fork `the repository <https://github.com/joke2k/django-environ>`_
229 on GitHub to start making your changes to the ``develop`` branch
230 (or branch off of it).
186231 3. Write a test which shows that the bug was fixed or that the feature works as
187232 expected.
188233 4. Send a pull request and bug the maintainer until it gets merged and published.
189234
235 If you are intending to implement a fairly large feature we'd appreciate if you
236 open an issue with GitHub detailing your use case and intended solution to
237 discuss how it might impact other work that is in flight.
238
239 We also appreciate it if you take the time to update and write tests for any
240 changes you submit.
241
242 **By submitting a patch, you agree to allow the project owner to license your
243 work under the same license as that used by the project.**
244
245 Resources
246 ---------
247
248 * `How to Contribute to Open Source <https://opensource.guide/how-to-contribute/>`_
249 * `Using Pull Requests <https://help.github.com/articles/about-pull-requests/>`_
250 * `Writing good commit messages <http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html>`_
251
190252
191253 Release Information
192254 ===================
193255
194 v0.9.0 - 15-June-2022
195 ------------------------------
256 v0.10.0 - 2-March-2023
257 -------------------------------
196258 Added
197259 +++++
198 - Added support for Postgresql cluster URI
199 `#355 <https://github.com/joke2k/django-environ/pull/355>`_.
200 - Added support for Django 4.0
201 `#371 <https://github.com/joke2k/django-environ/issues/371>`_.
202 - Added support for prefixed variables
203 `#362 <https://github.com/joke2k/django-environ/issues/362>`_.
204 - Amended documentation.
205
260 - Use the core redis library by default if running Django >= 4.0
261 `#356 <https://github.com/joke2k/django-environ/issues/356>`_.
262 - Value of dict can now contain an equal sign
263 `#241 <https://github.com/joke2k/django-environ/pull/241>`_.
264 - Added support for Python 3.11.
265 - Added ``CONN_HEALTH_CHECKS`` to database base options
266 `#413 <https://github.com/joke2k/django-environ/issues/413>`_.
267 - Added ``encoding`` parameter to ``read_env`` with default value 'utf8'
268 `#442 <https://github.com/joke2k/django-environ/pull/442>`_.
269 - Added support for Django 4.1
270 `#416 <https://github.com/joke2k/django-environ/issues/416>`_.
206271
207272 Deprecated
208273 ++++++++++
209 - ``Env.unicode()`` is deprecated and will be removed in the next
210 major release. Use ``Env.str()`` instead.
211
274 - Support of Python < 3.6 is deprecated and will be removed
275 in next major version.
212276
213277 Changed
214278 +++++++
215 - Attach cause to ``ImproperlyConfigured`` exception
216 `#360 <https://github.com/joke2k/django-environ/issues/360>`_.
217
279 - Used UTF-8 as a encoding when open ``.env`` file.
280 - Provided access to ```DB_SCHEMES`` through ``cls`` rather than
281 ``Env`` in ``db_url_config``
282 `#414 <https://github.com/joke2k/django-environ/pull/414>`_.
283 - Correct CI workflow to use supported Python versions/OS matrix
284 `#441 <https://github.com/joke2k/django-environ/pull/441>`_.
285 - Reworked trigger CI workflows strategy
286 `#440 <https://github.com/joke2k/django-environ/pull/440>`_.
218287
219288 Fixed
220289 +++++
221 - Fixed ``_cast_urlstr`` unquoting
222 `#357 <https://github.com/joke2k/django-environ/issues/357>`_.
223 - Fixed documentation regarding unsafe characters in URLs
224 `#220 <https://github.com/joke2k/django-environ/issues/220>`_.
225 - Fixed ``environ.Path.__eq__()`` to compare paths correctly
226 `#86 <https://github.com/joke2k/django-environ/issues/86>`_,
227 `#197 <https://github.com/joke2k/django-environ/issues/197>`_.
290 - Fixed logic of ``Env.get_value()`` to skip parsing only when
291 ``default=None``, not for all default values that coerce to ``False``
292 `#404 <https://github.com/joke2k/django-environ/issues/404>`_.
293 - Deleted duplicated include in docs/quickstart.rst
294 `#439 <https://github.com/joke2k/django-environ/pull/439>`_.
295
296 Removed
297 +++++++
298 - Removed deprecated ``Env.unicode()``.
299 - Removed ``environ.register_schemes`` calls and do not modify global
300 ``urllib.parse.urlparse``'s ``uses_*`` variables as this no longer needed
301 `#246 <https://github.com/joke2k/django-environ/pull/246>`_.
228302
229303 `Full changelog <https://django-environ.readthedocs.org/en/latest/changelog.html>`_.
230304
1212 .github/FUNDING.yml
1313 .github/dependabot.yml
1414 .github/workflows/build.yml
15 .github/workflows/change-pr-target.yml
1516 .github/workflows/ci.yml
17 .github/workflows/codeql.yml
1618 .github/workflows/cs.yml
1719 .github/workflows/docs.yml
1820 django_environ.egg-info/PKG-INFO
125125 # In nitpick mode (-n), still ignore any of the following "broken" references
126126 # to non-types.
127127 nitpick_ignore = [
128 ('py:func', 'str.rfind'),
129 ('py:func', 'str.find'),
128130 ]
129131
130132 #
00 ============
11 Deprecations
22 ============
3
4 Features deprecated in 0.10.0
5 =============================
6
7 Python
8 ------
9
10 * Support of Python < 3.6 is deprecated and will be removed
11 in next major version.
12
313
414 Features deprecated in 0.9.0
515 ============================
717 Methods
818 -------
919
10 * The :meth:`.environ.Env.unicode` method is deprecated as it was used
20 * The ``environ.Env.unicode`` method is deprecated as it was used
1121 for Python 2.x only. Use :meth:`.environ.Env.str` instead.
44
55 #. **Can django-environ determine the location of .env file automatically?**
66
7 ``django-environ`` will try to get and read ``.env`` file from the project
7 django-environ will try to get and read ``.env`` file from the project
88 root if you haven't specified the path for it when call :meth:`.environ.Env.read_env`.
99 However, this is not the recommended way. When it is possible always specify
1010 the path tho ``.env`` file. Alternatively, you can use a trick with a
2626
2727 #. **Is .env file going to be imported in settings file?**
2828
29 No need to import, ``django-environ`` automatically picks variables
29 No need to import, django-environ automatically picks variables
3030 from there.
31
32 #. **Should I commit my .env file?**
33
34 Credentials should only be accessible on the machines that need access to them.
35 Never commit sensitive information to a repository that is not needed by every
36 development machine and server.
37
38 #. **Why is it not overriding existing environment variables?**
39
40 By default, django-environ won't overwrite existing environment variables as
41 it assumes the deployment environment has more knowledge about configuration
42 than the application does. To overwrite existing environment variables you can
43 pass ``overwrite=True`` to :meth:`.environ.Env.read_env`. For more see
44 ":ref:`overwriting-existing-env`"
1111 Installing django-environ
1212 =========================
1313
14 ``django-environ`` is a Python-only package `hosted_on_pypi`_.
14 django-environ is a Python-only package `hosted_on_pypi`_.
1515 The recommended installation method is `pip`_-installing into a
1616 :mod:`virtualenv <python:venv>`:
1717
2121
2222 .. note::
2323
24 After installing ``django-environ``, no need to add it to ``INSTALLED_APPS``.
24 After installing django-environ, no need to add it to ``INSTALLED_APPS``.
2525
2626
2727 .. _hosted_on_pypi: https://pypi.org/project/django-environ/
4242 # OR
4343 $ pip install --upgrade https://github.com/joke2k/django-environ.git/archive/develop.tar.gz
4444
45 This command will download the latest version of ``django-environ`` and install
45 This command will download the latest version of django-environ and install
4646 it to your system.
4747
4848 .. note::
11 License and Credits
22 ===================
33
4 ``django-environ`` is open source software licensed under the
4 django-environ is open source software licensed under the
55 `MIT / X11 License <https://choosealicense.com/licenses/mit/>`_.
66 The full license text can be also found in the `source code repository <https://github.com/joke2k/django-environ/blob/main/LICENSE.txt>`_.
77
00 ===========
11 Quick Start
22 ===========
3
4 .. include:: ../README.rst
5 :start-after: -code-begin-
6 :end-before: -overview-
73
84 Usage
95 =====
5454 Smart Casting
5555 =============
5656
57 ``django-environ`` has a "Smart-casting" enabled by default, if you don't provide a ``cast`` type, it will be detected from ``default`` type.
57 django-environ has a "Smart-casting" enabled by default, if you don't provide a ``cast`` type, it will be detected from ``default`` type.
5858 This could raise side effects (see `#192 <https://github.com/joke2k/django-environ/issues/192>`_).
5959 To disable it use ``env.smart_cast = False``.
6060
316316 env.read_env(pathlib.Path(str(BASE_DIR)) / '.env')
317317
318318
319 .. _overwriting-existing-env:
320
319321 Overwriting existing environment values from env files
320322 ------------------------------------------------------
321323
1717 from .environ import *
1818
1919
20 __copyright__ = 'Copyright (C) 2021 Daniele Faraglia'
20 __copyright__ = 'Copyright (C) 2013-2022 Daniele Faraglia'
2121 """The copyright notice of the package."""
2222
23 __version__ = '0.9.0'
23 __version__ = '0.10.0'
2424 """The version of the package."""
2525
2626 __license__ = 'MIT'
4141 __url__ = 'https://django-environ.readthedocs.org'
4242 """The URL of the package."""
4343
44 # pylint: disable=line-too-long
4445 __description__ = 'A package that allows you to utilize 12factor inspired environment variables to configure your Django application.' # noqa: E501
4546 """The description of the package."""
2222 DJANGO_VERSION = None
2323
2424 class ImproperlyConfigured(Exception):
25 pass
25 """Django is somehow improperly configured"""
2626
27 # back compatibility with django postgresql package
28 if DJANGO_VERSION is not None and DJANGO_VERSION < (2, 0):
29 DJANGO_POSTGRES = 'django.db.backends.postgresql_psycopg2'
30 else:
31 # https://docs.djangoproject.com/en/2.0/releases/2.0/#id1
32 DJANGO_POSTGRES = 'django.db.backends.postgresql'
3327
34 # back compatibility with redis_cache package
35 if find_loader('redis_cache'):
36 REDIS_DRIVER = 'redis_cache.RedisCache'
37 else:
38 REDIS_DRIVER = 'django_redis.cache.RedisCache'
28 def choose_rediscache_driver():
29 """Backward compatibility for RedisCache driver."""
30 # use built-in support if Django 4+
31 if DJANGO_VERSION is not None and DJANGO_VERSION >= (4, 0):
32 return 'django.core.cache.backends.redis.RedisCache'
33
34 # back compatibility with redis_cache package
35 if find_loader('redis_cache'):
36 return 'redis_cache.RedisCache'
37 return 'django_redis.cache.RedisCache'
38
39
40 def choose_postgres_driver():
41 """Backward compatibility for postgresql driver."""
42 old_django = DJANGO_VERSION is not None and DJANGO_VERSION < (2, 0)
43 if old_django:
44 return 'django.db.backends.postgresql_psycopg2'
45 return 'django.db.backends.postgresql'
3946
4047
4148 def choose_pymemcache_driver():
4855 return 'django.core.cache.backends.memcached.PyMemcacheCache'
4956
5057
58 REDIS_DRIVER = choose_rediscache_driver()
59 """The name of the RedisCache driver."""
60
61 DJANGO_POSTGRES = choose_postgres_driver()
62 """The name of the PostgreSQL driver."""
63
5164 PYMEMCACHE_DRIVER = choose_pymemcache_driver()
65 """The name of the Pymemcache driver."""
1616 import os
1717 import re
1818 import sys
19 import urllib.parse as urlparselib
2019 import warnings
2120 from urllib.parse import (
2221 parse_qs,
6665
6766
6867 class NoValue:
68 """Represent of no value object."""
6969
7070 def __repr__(self):
7171 return '<{}>'.format(self.__class__.__name__)
133133 'ATOMIC_REQUESTS',
134134 'AUTOCOMMIT',
135135 'DISABLE_SERVER_SIDE_CURSORS',
136 'CONN_HEALTH_CHECKS',
136137 ]
137138
138139 DEFAULT_CACHE_ENV = 'CACHE_URL'
203204 def __contains__(self, var):
204205 return var in self.ENVIRON
205206
206 # Shortcuts
207
208207 def str(self, var, default=NOTSET, multiline=False):
209208 """
210209 :rtype: str
213212 if multiline:
214213 return re.sub(r'(\\r)?\\n', r'\n', value)
215214 return value
216
217 def unicode(self, var, default=NOTSET):
218 """Helper for python2
219 :rtype: unicode
220 """
221 warnings.warn(
222 '`%s.unicode` is deprecated, use `%s.str` instead' % (
223 self.__class__.__name__,
224 self.__class__.__name__,
225 ),
226 DeprecationWarning,
227 stacklevel=2
228 )
229
230 return self.get_value(var, cast=str, default=default)
231215
232216 def bytes(self, var, default=NOTSET, encoding='utf8'):
233217 """
372356 :rtype: typing.IO[typing.Any]
373357 """
374358
375 logger.debug("get '{}' casted as '{}' with default '{}'".format(
376 var, cast, default
377 ))
359 logger.debug(
360 "get '%s' casted as '%s' with default '%s'",
361 var, cast, default)
378362
379363 var_name = "{}{}".format(self.prefix, var)
380364 if var_name in self.scheme:
425409
426410 value = None if default is None and value == '' else value
427411
428 if value != default or (parse_default and value):
412 if value != default or (parse_default and value is not None):
429413 value = self.parse_value(value, cast)
430414
431415 return value
432
433 # Class and static methods
434416
435417 @classmethod
436418 def parse_value(cls, value, cast):
443425 """
444426 if cast is None:
445427 return value
446 elif cast is bool:
428 if cast is bool:
447429 try:
448430 value = int(value) != 0
449431 except ValueError:
456438 elif isinstance(cast, dict):
457439 key_cast = cast.get('key', str)
458440 value_cast = cast.get('value', str)
459 value_cast_by_key = cast.get('cast', dict())
441 value_cast_by_key = cast.get('cast', {})
460442 value = dict(map(
461443 lambda kv: (
462444 key_cast(kv[0]),
468450 [val.split('=') for val in value.split(';') if val]
469451 ))
470452 elif cast is dict:
471 value = dict([val.split('=') for val in value.split(',') if val])
453 value = dict([v.split('=', 1) for v in value.split(',') if v])
472454 elif cast is list:
473455 value = [x for x in value.split(',') if x]
474456 elif cast is tuple:
475457 val = value.strip('(').strip(')').split(',')
458 # pylint: disable=consider-using-generator
476459 value = tuple([x for x in val if x])
477460 elif cast is float:
478461 # clean string
589572 if url.scheme == 'oracle':
590573 # Django oracle/base.py strips port and fails on non-string value
591574 if not config['PORT']:
592 del (config['PORT'])
575 del config['PORT']
593576 else:
594577 config['PORT'] = str(config['PORT'])
595578
607590 else:
608591 config['ENGINE'] = url.scheme
609592
610 if config['ENGINE'] in Env.DB_SCHEMES:
611 config['ENGINE'] = Env.DB_SCHEMES[config['ENGINE']]
593 if config['ENGINE'] in cls.DB_SCHEMES:
594 config['ENGINE'] = cls.DB_SCHEMES[config['ENGINE']]
612595
613596 if not config.get('ENGINE', False):
614597 warnings.warn("Engine not recognized from url: {}".format(config))
630613 if not isinstance(url, cls.URL_CLASS):
631614 if not url:
632615 return {}
633 else:
634 url = urlparse(url)
616 url = urlparse(url)
635617
636618 if url.scheme not in cls.CACHE_SCHEMES:
637619 raise ImproperlyConfigured(
775757 params = {} # type: dict
776758 if url.query:
777759 params = parse_qs(url.query)
778 if 'EXCLUDED_INDEXES' in params.keys():
760 if 'EXCLUDED_INDEXES' in params:
779761 config['EXCLUDED_INDEXES'] \
780762 = params['EXCLUDED_INDEXES'][0].split(',')
781 if 'INCLUDE_SPELLING' in params.keys():
763 if 'INCLUDE_SPELLING' in params:
782764 config['INCLUDE_SPELLING'] = cls.parse_value(
783765 params['INCLUDE_SPELLING'][0],
784766 bool
785767 )
786 if 'BATCH_SIZE' in params.keys():
768 if 'BATCH_SIZE' in params:
787769 config['BATCH_SIZE'] = cls.parse_value(
788770 params['BATCH_SIZE'][0],
789771 int
791773
792774 if url.scheme == 'simple':
793775 return config
794 elif url.scheme in ['solr'] + cls.ELASTICSEARCH_FAMILY:
795 if 'KWARGS' in params.keys():
776 if url.scheme in ['solr'] + cls.ELASTICSEARCH_FAMILY:
777 if 'KWARGS' in params:
796778 config['KWARGS'] = params['KWARGS'][0]
797779
798780 # remove trailing slash
803785 config['URL'] = urlunparse(
804786 ('http',) + url[1:2] + (path,) + ('', '', '')
805787 )
806 if 'TIMEOUT' in params.keys():
788 if 'TIMEOUT' in params:
807789 config['TIMEOUT'] = cls.parse_value(params['TIMEOUT'][0], int)
808790 return config
809791
820802 config['URL'] = urlunparse(
821803 ('http',) + url[1:2] + (path,) + ('', '', '')
822804 )
823 if 'TIMEOUT' in params.keys():
805 if 'TIMEOUT' in params:
824806 config['TIMEOUT'] = cls.parse_value(params['TIMEOUT'][0], int)
825807 config['INDEX_NAME'] = index
826808 return config
828810 config['PATH'] = '/' + path
829811
830812 if url.scheme == 'whoosh':
831 if 'STORAGE' in params.keys():
813 if 'STORAGE' in params:
832814 config['STORAGE'] = params['STORAGE'][0]
833 if 'POST_LIMIT' in params.keys():
815 if 'POST_LIMIT' in params:
834816 config['POST_LIMIT'] = cls.parse_value(
835817 params['POST_LIMIT'][0],
836818 int
837819 )
838820 elif url.scheme == 'xapian':
839 if 'FLAGS' in params.keys():
821 if 'FLAGS' in params:
840822 config['FLAGS'] = params['FLAGS'][0]
841823
842824 if engine:
845827 return config
846828
847829 @classmethod
848 def read_env(cls, env_file=None, overwrite=False, **overrides):
830 def read_env(cls, env_file=None, overwrite=False, encoding='utf8',
831 **overrides):
849832 r"""Read a .env file into os.environ.
850833
851834 If not given a path to a dotenv path, does filthy magic stack
865848 the Django settings module from the Django project root.
866849 :param overwrite: ``overwrite=True`` will force an overwrite of
867850 existing environment variables.
851 :param encoding: The encoding to use when reading the environment file.
868852 :param \**overrides: Any additional keyword arguments provided directly
869853 to read_env will be added to the environment. If the key matches an
870854 existing environment variable, the value will be overridden.
871855 """
872856 if env_file is None:
857 # pylint: disable=protected-access
873858 frame = sys._getframe()
874859 env_file = os.path.join(
875860 os.path.dirname(frame.f_back.f_code.co_filename),
878863 if not os.path.exists(env_file):
879864 logger.info(
880865 "%s doesn't exist - if you're not configuring your "
881 "environment separately, create one." % env_file)
866 "environment separately, create one.", env_file)
882867 return
883868
884869 try:
885870 if isinstance(env_file, Openable):
886871 # Python 3.5 support (wrap path with str).
887 with open(str(env_file)) as f:
872 with open(str(env_file), encoding=encoding) as f:
888873 content = f.read()
889874 else:
890875 with env_file as f:
892877 except OSError:
893878 logger.info(
894879 "%s not found - if you're not configuring your "
895 "environment separately, check this." % env_file)
880 "environment separately, check this.", env_file)
896881 return
897882
898 logger.debug('Read environment variables from: {}'.format(env_file))
883 logger.debug('Read environment variables from: %s', env_file)
899884
900885 def _keep_escaped_format_characters(match):
901886 """Keep escaped newline/tabs in quoted strings"""
975960 :param \**kwargs: ``**kwargs`` passed to :py:func:`open`
976961 :rtype: typing.IO[typing.Any]
977962 """
963 # pylint: disable=unspecified-encoding
978964 return open(self(name), *args, **kwargs)
979965
980966 @property
982968 """Current directory for this Path"""
983969 return self.__root__
984970
971 # pylint: disable=keyword-arg-before-vararg
985972 def __init__(self, start='', *paths, **kwargs):
986973
987974 super().__init__()
10151002 def __sub__(self, other):
10161003 if isinstance(other, int):
10171004 return self.path('../' * other)
1018 elif isinstance(other, str):
1019 if self.__root__.endswith(other):
1020 return Path(self.__root__.rstrip(other))
1005 if isinstance(other, str) and self.__root__.endswith(other):
1006 return Path(self.__root__.rstrip(other))
1007
10211008 raise TypeError(
10221009 "unsupported operand type(s) for -: '{self}' and '{other}' "
10231010 "unless value of {self} ends with value of {other}".format(
10501037 return self.__str__()
10511038
10521039 def rfind(self, *args, **kwargs):
1053 return self.__str__().rfind(*args, **kwargs)
1040 """Proxy method to :py:func:`str.rfind`"""
1041 return str(self).rfind(*args, **kwargs)
10541042
10551043 def find(self, *args, **kwargs):
1056 return self.__str__().find(*args, **kwargs)
1044 """Proxy method to :py:func:`str.find`"""
1045 return str(self).find(*args, **kwargs)
10571046
10581047 @staticmethod
10591048 def _absolute_join(base, *paths, **kwargs):
10621051 raise ImproperlyConfigured(
10631052 "Create required path: {}".format(absolute_path))
10641053 return absolute_path
1065
1066
1067 def register_scheme(scheme):
1068 for method in dir(urlparselib):
1069 if method.startswith('uses_'):
1070 getattr(urlparselib, method).append(scheme)
1071
1072
1073 def register_schemes(schemes):
1074 for scheme in schemes:
1075 register_scheme(scheme)
1076
1077
1078 # Register database and cache schemes in URLs.
1079 register_schemes(Env.DB_SCHEMES.keys())
1080 register_schemes(Env.CACHE_SCHEMES.keys())
1081 register_schemes(Env.SEARCH_SCHEMES.keys())
1082 register_schemes(Env.EMAIL_SCHEMES.keys())
4444 return self.files_cache[key]
4545 key_file = self.env.get(key + "_FILE")
4646 if key_file:
47 with open(key_file) as f:
47 with open(key_file, encoding='utf-8') as f:
4848 value = f.read()
4949 if self.cache:
5050 self.files_cache[key] = value
99
1010 import codecs
1111 import re
12 import sys
13 import warnings
1214 from os import path
1315
1416 from setuptools import find_packages, setup
17
18
19 if sys.version_info < (3, 6):
20 warnings.warn(
21 "Support of Python < 3.6 is deprecated"
22 "and will be removed in a future release.",
23 DeprecationWarning
24 )
1525
1626
1727 def read_file(filepath):
130140 'Framework :: Django :: 3.1',
131141 'Framework :: Django :: 3.2',
132142 'Framework :: Django :: 4.0',
143 'Framework :: Django :: 4.1',
133144
134145 'Operating System :: OS Independent',
135146
138149
139150 'Programming Language :: Python',
140151 'Programming Language :: Python :: 3',
141 'Programming Language :: Python :: 3.4',
142152 'Programming Language :: Python :: 3.5',
143153 'Programming Language :: Python :: 3.6',
144154 'Programming Language :: Python :: 3.7',
145155 'Programming Language :: Python :: 3.8',
146156 'Programming Language :: Python :: 3.9',
147157 'Programming Language :: Python :: 3.10',
158 'Programming Language :: Python :: 3.11',
148159 'Programming Language :: Python :: Implementation :: CPython',
149160 'Programming Language :: Python :: Implementation :: PyPy',
150161
216227 platforms=['any'],
217228 include_package_data=True,
218229 zip_safe=False,
219 python_requires='>=3.4,<4',
230 python_requires='>=3.5,<4',
220231 install_requires=INSTALL_REQUIRES,
221232 dependency_links=DEPENDENCY_LINKS,
222233 extras_require=EXTRAS_REQUIRE,
2424 EMAIL = 'smtps://user@domain.com:password@smtp.example.com:587'
2525 JSON = dict(one='bar', two=2, three=33.44)
2626 DICT = dict(foo='bar', test='on')
27 DICT_WITH_EQ = dict(key1='sub_key1=sub_value1', key2='value2')
2728 PATH = '/home/dev'
2829 EXPORTED = 'exported var'
2930 SAML_ATTRIBUTE_MAPPING = dict(
6667 STR_LIST_WITH_SPACES=' foo, bar',
6768 EMPTY_LIST='',
6869 DICT_VAR='foo=bar,test=on',
70 DICT_WITH_EQ_VAR='key1=sub_key1=sub_value1,key2=value2',
6971 DATABASE_URL=cls.POSTGRES,
7072 DATABASE_MYSQL_URL=cls.MYSQL,
7173 DATABASE_MYSQL_GIS_URL=cls.MYSQLGIS,
00 # This file is part of the django-environ.
11 #
2 # Copyright (c) 2021, Serghei Iakovlev <egrep@protonmail.ch>
2 # Copyright (c) 2021-2022, Serghei Iakovlev <egrep@protonmail.ch>
33 # Copyright (c) 2013-2021, Daniele Faraglia <daniele.faraglia@gmail.com>
44 #
55 # For the full copyright and license information, please view
1111
1212 import environ.compat
1313 from environ import Env
14 from environ.compat import PYMEMCACHE_DRIVER, REDIS_DRIVER, ImproperlyConfigured
14 from environ.compat import (
15 ImproperlyConfigured,
16 PYMEMCACHE_DRIVER,
17 REDIS_DRIVER,
18 )
1519
1620
1721 def test_base_options_parsing():
5357 ('rediscache://host1:6379,host2:6379,host3:9999/1', REDIS_DRIVER,
5458 ['redis://host1:6379/1', 'redis://host2:6379/1',
5559 'redis://host3:9999/1']),
56 ('rediscache:///path/to/socket:1', 'django_redis.cache.RedisCache',
60 ('rediscache:///path/to/socket:1', REDIS_DRIVER,
5761 'unix:///path/to/socket:1'),
5862 ('memcache:///tmp/memcached.sock',
5963 'django.core.cache.backends.memcached.MemcachedCache',
111115 assert driver == new if pymemcache_installed else old
112116
113117
118 @pytest.mark.parametrize('django_version', ((4, 0), (3, 2), None))
119 @pytest.mark.parametrize('redis_cache_installed', (True, False))
120 def test_rediscache_compat(django_version, redis_cache_installed):
121 django_new = 'django.core.cache.backends.redis.RedisCache'
122 redis_cache = 'redis_cache.RedisCache'
123 django_old = 'django_redis.cache.RedisCache'
124
125 with mock.patch.object(environ.compat, 'DJANGO_VERSION', django_version):
126 with mock.patch('environ.compat.find_loader') as mock_find_loader:
127 mock_find_loader.return_value = redis_cache_installed
128 driver = environ.compat.choose_rediscache_driver()
129 if django_version and django_version >= (4, 0):
130 assert driver == django_new
131 else:
132 assert driver == redis_cache if redis_cache_installed else django_old
133
134
114135 def test_redis_parsing():
115136 url = ('rediscache://127.0.0.1:6379/1?client_class='
116137 'django_redis.client.DefaultClient&password=secret')
185206 env = Env()
186207
187208 result = env.cache()
188 assert result['BACKEND'] == 'django_redis.cache.RedisCache'
209 assert result['BACKEND'] == REDIS_DRIVER
189210 assert result['LOCATION'] == url
190211
191212 result = env.cache_url_config(url)
192 assert result['BACKEND'] == 'django_redis.cache.RedisCache'
213 assert result['BACKEND'] == REDIS_DRIVER
193214 assert result['LOCATION'] == url
194215
195216 url = 'rediss://enigma:sec{}ret@ondigitalocean.com:25061/2'.format(chars)
197218 env = Env()
198219
199220 result = env.cache()
200 assert result['BACKEND'] == 'django_redis.cache.RedisCache'
221 assert result['BACKEND'] == REDIS_DRIVER
201222 assert result['LOCATION'] == url
202223
203224 result = env.cache_url_config(url)
204 assert result['BACKEND'] == 'django_redis.cache.RedisCache'
225 assert result['BACKEND'] == REDIS_DRIVER
205226 assert result['LOCATION'] == url
206227
207228 url = 'rediss://enigma:{}secret@ondigitalocean.com:25061/2'.format(chars)
209230 env = Env()
210231
211232 result = env.cache()
212 assert result['BACKEND'] == 'django_redis.cache.RedisCache'
233 assert result['BACKEND'] == REDIS_DRIVER
213234 assert result['LOCATION'] == url
214235
215236 result = env.cache_url_config(url)
216 assert result['BACKEND'] == 'django_redis.cache.RedisCache'
237 assert result['BACKEND'] == REDIS_DRIVER
217238 assert result['LOCATION'] == url
218239
219240
229250 env = Env()
230251
231252 result = env.cache()
232 assert result['BACKEND'] == 'django_redis.cache.RedisCache'
253 assert result['BACKEND'] == REDIS_DRIVER
233254 assert result['LOCATION'] == url
234255
235256 url = 'rediss://enigma:sec{}ret@ondigitalocean.com:25061/2'.format(chars)
237258 env = Env()
238259
239260 result = env.cache()
240 assert result['BACKEND'] == 'django_redis.cache.RedisCache'
261 assert result['BACKEND'] == REDIS_DRIVER
241262 assert result['LOCATION'] == url
242263
243264 url = 'rediss://enigma:{}secret@ondigitalocean.com:25061/2'.format(chars)
245266 env = Env()
246267
247268 result = env.cache()
248 assert result['BACKEND'] == 'django_redis.cache.RedisCache'
269 assert result['BACKEND'] == REDIS_DRIVER
249270 assert result['LOCATION'] == url
250271
251272
00 # This file is part of the django-environ.
11 #
2 # Copyright (c) 2021, Serghei Iakovlev <egrep@protonmail.ch>
2 # Copyright (c) 2021-2022, Serghei Iakovlev <egrep@protonmail.ch>
33 # Copyright (c) 2013-2021, Daniele Faraglia <daniele.faraglia@gmail.com>
44 #
55 # For the full copyright and license information, please view
167167
168168 if host == 'reconnect.com':
169169 assert config['OPTIONS'] == {'reconnect': 'true'}
170
171170
172171
173172 def test_postgres_complex_db_name_parsing():
77
88 import os
99 from urllib.parse import quote
10 from warnings import catch_warnings
1110
1211 import pytest
1312
1413 from environ import Env, Path
15 from environ.compat import ImproperlyConfigured, DJANGO_POSTGRES
14 from environ.compat import (
15 DJANGO_POSTGRES,
16 ImproperlyConfigured,
17 REDIS_DRIVER,
18 )
1619 from .asserts import assert_type_and_value
1720 from .fixtures import FakeEnv
1821
6972 if not multiline:
7073 assert self.env(var) == val
7174 assert self.env.str(var, multiline=multiline) == val
72
73 def test_unicode(self, recwarn):
74 actual = self.env.unicode('CYRILLIC_VAR', default='фуубар')
75 expected = self.env.str('CYRILLIC_VAR', default='фуубар')
76
77 assert actual == expected
78 assert len(recwarn) == 1
79 w = recwarn.pop(DeprecationWarning)
80 assert issubclass(w.category, DeprecationWarning)
81 assert str(w.message) == '`%s.unicode` is deprecated, use `%s.str` instead' %(
82 self.env.__class__.__name__,
83 self.env.__class__.__name__,
84 )
85 assert w.filename
86 assert w.lineno
8775
8876 @pytest.mark.parametrize(
8977 'var,val,default',
167155
168156 def test_mix_tuple_issue_387(self):
169157 """Cast a tuple of mixed types.
170
158
171159 Casts a string like "(42,Test)" to a tuple like (42, 'Test').
172160 See: https://github.com/joke2k/django-environ/issues/387 for details."""
173 caster = lambda v: int(v) if v.isdigit() else v.strip()
174 cast = lambda t: tuple(map(caster, [c for c in t.strip('()').split(',')]))
175 assert_type_and_value(tuple, (42, 'Test'), self.env( 'MIX_TUPLE', default=(0, ''), cast=cast))
161 assert_type_and_value(
162 tuple,
163 (42, 'Test'),
164 self.env(
165 'MIX_TUPLE',
166 default=(0, ''),
167 cast=lambda t: tuple(
168 map(
169 lambda v: int(v) if v.isdigit() else v.strip(),
170 [c for c in t.strip('()').split(',')]
171 )
172 ),
173 )
174 )
176175
177176 def test_str_list_with_spaces(self):
178177 assert_type_and_value(list, [' foo', ' bar'],
185184
186185 def test_dict_value(self):
187186 assert_type_and_value(dict, FakeEnv.DICT, self.env.dict('DICT_VAR'))
187 assert_type_and_value(dict, FakeEnv.DICT_WITH_EQ, self.env.dict('DICT_WITH_EQ_VAR'))
188188
189189 def test_complex_dict_value(self):
190190 assert_type_and_value(
225225 assert url.__class__ == self.env.URL_CLASS
226226 assert url.geturl() == FakeEnv.URL
227227 assert self.env.url('OTHER_URL', default=None) is None
228
229 def test_url_empty_string_default_value(self):
230 unset_var_name = 'VARIABLE_NOT_SET_IN_ENVIRONMENT'
231 assert unset_var_name not in os.environ
232 url = self.env.url(unset_var_name, '')
233 assert url.__class__ == self.env.URL_CLASS
234 assert url.geturl() == ''
228235
229236 def test_url_encoded_parts(self):
230237 password_with_unquoted_characters = "#password"
290297 (Env.DEFAULT_CACHE_ENV,
291298 'django.core.cache.backends.memcached.MemcachedCache',
292299 '127.0.0.1:11211', None),
293 ('CACHE_REDIS', 'django_redis.cache.RedisCache',
300 ('CACHE_REDIS', REDIS_DRIVER,
294301 'redis://127.0.0.1:6379/1',
295302 {'CLIENT_CLASS': 'django_redis.client.DefaultClient',
296303 'PASSWORD': 'secret'}),
00 DICT_VAR=foo=bar,test=on
1 DICT_WITH_EQ_VAR=key1=sub_key1=sub_value1,key2=value2
12
23 # Database variables
34 DATABASE_MYSQL_URL=mysql://bea6eb0:69772142@us-cdbr-east.cleardb.com/heroku_97681?reconnect=true
00 # This file is part of the django-environ.
11 #
2 # Copyright (c) 2021, Serghei Iakovlev <egrep@protonmail.ch>
2 # Copyright (c) 2021-2022, Serghei Iakovlev <egrep@protonmail.ch>
33 # Copyright (c) 2013-2021, Daniele Faraglia <daniele.faraglia@gmail.com>
44 #
55 # For the full copyright and license information, please view
99 import tempfile
1010 from contextlib import contextmanager
1111
12 import pytest
13
1214 import environ
13 import pytest
1415
1516
1617 @contextmanager
00 # This file is part of the django-environ.
11 #
2 # Copyright (c) 2021, Serghei Iakovlev <egrep@protonmail.ch>
2 # Copyright (c) 2021-2022, Serghei Iakovlev <egrep@protonmail.ch>
33 # Copyright (c) 2013-2021, Daniele Faraglia <daniele.faraglia@gmail.com>
44 #
55 # For the full copyright and license information, please view
66 # the LICENSE.txt file that was distributed with this source code.
77
88 import os
9 import sys
10
911 import pytest
10 import sys
12
1113
1214 from environ import Path
1315 from environ.compat import ImproperlyConfigured
6971 assert '/home' == Path('/home')
7072
7173 assert Path('/home') != '/usr'
74
7275
7376 def test_sum():
7477 """Make sure Path correct handle __add__."""
00 # This file is part of the django-environ.
11 #
2 # Copyright (c) 2021, Serghei Iakovlev <egrep@protonmail.ch>
2 # Copyright (c) 2021-2022, Serghei Iakovlev <egrep@protonmail.ch>
33 # Copyright (c) 2013-2021, Daniele Faraglia <daniele.faraglia@gmail.com>
44 #
55 # For the full copyright and license information, please view
66 # the LICENSE.txt file that was distributed with this source code.
77
88 import pytest
9
910 from environ.environ import _cast, _cast_urlstr
1011
1112
1920
2021 See https://github.com/joke2k/django-environ/issues/200 for details."""
2122 assert _cast(literal) == literal
23
2224
2325 @pytest.mark.parametrize(
2426 "quoted_url_str,expected_unquoted_str",
1717 docs
1818 lint
1919 manifest
20 py{35,36,37,38,39,310}-django{111,22}
21 py{36,37,38,39,310}-django{30,31,32}
22 py{38,39,310}-django{40}
20 py{35,36,37,38,39,310,311}-django{111,22}
21 py{36,37,38,39,310,311}-django{30,31,32}
22 py{38,39,310,311}-django{40,41}
2323 pypy-django{111,22,30,31,32}
2424
2525 [gh-actions]
3030 3.8: py38
3131 3.9: py39
3232 3.10: py310
33 3.11: py311
3334 pypy-3.7: pypy
3435
3536 [testenv]
4243 django31: Django>=3.1,<3.2
4344 django32: Django>=3.2,<3.3
4445 django40: Django>=4.0,<4.1
46 django41: Django>=4.1,<4.2
4547 commands_pre =
4648 python -m pip install --upgrade pip
4749 python -m pip install .
6668 flake8
6769 flake8-blind-except
6870 flake8-import-order
71 pylint
6972 commands_pre =
7073 python -m pip install --upgrade pip
7174 python -m pip install .
72 commands = flake8 environ setup.py
75 commands =
76 flake8 environ setup.py
77 # Format ("f") strings have not been introduced before Python 3.6,
78 # thus disable "consider-using-f-string" at this moment.
79 pylint \
80 --logging-format-style=old \
81 --good-names-rgxs=m[0-9],f,v \
82 --disable=too-few-public-methods \
83 --disable=import-error \
84 --disable=unused-import \
85 --disable=consider-using-f-string \
86 --disable=too-many-locals \
87 --disable=too-many-branches \
88 --disable=too-many-public-methods \
89 --disable=too-many-lines \
90 environ
7391
7492 [testenv:linkcheck]
7593 description = Check external links in the package documentation