Skip to content

Commit 3ba44d0

Browse files
committed
Adds ability to set a custom zoneinfo directory.
1 parent dbea70e commit 3ba44d0

8 files changed

Lines changed: 132 additions & 4 deletions

File tree

README.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,17 @@ If you just want to know the path to a specific timezone file, you may use the `
3636
3737
tz_path('Europe/Paris')
3838
39+
By default, ``pytzdata`` will use the bundled timezone database, however you can set
40+
a custom directory that holds the timezone files using the ``set_directory`` function:
41+
42+
.. code-block:: python
43+
44+
import pytzdata
45+
46+
pytzdata.set_directory('/custom/zoneinfo')
47+
48+
You can also set the ``PYTZDATA_TZDATADIR`` environment variable to set a custom directory.
49+
3950

4051
Release
4152
=======

pytzdata/__init__.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@
66
from ._compat import FileNotFoundError
77

88

9+
DEFAULT_DIRECTORY = os.path.join(
10+
os.path.dirname(__file__),
11+
'zoneinfo'
12+
)
13+
14+
_DIRECTORY = os.getenv('PYTZDATA_TZDATADIR', DEFAULT_DIRECTORY)
15+
16+
917
def tz_file(name):
1018
"""
1119
Open a timezone file from the zoneinfo subdir for reading.
@@ -50,10 +58,18 @@ def tz_path(name):
5058
if part == os.path.pardir or os.path.sep in part:
5159
raise ValueError('Bad path segment: %r' % part)
5260

53-
filepath = os.path.join(os.path.dirname(__file__),
54-
'zoneinfo', *name_parts)
61+
filepath = os.path.join(_DIRECTORY, *name_parts)
5562

5663
if not os.path.exists(filepath):
5764
raise TimezoneNotFound('Timezone {} not found at {}'.format(name, filepath))
5865

5966
return filepath
67+
68+
69+
def set_directory(directory=None):
70+
global _DIRECTORY
71+
72+
if directory is None:
73+
directory = os.getenv('PYTZDATA_TZDATADIR', DEFAULT_DIRECTORY)
74+
75+
_DIRECTORY = directory

tests/__init__.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,11 @@
11
# -*- coding: utf-8 -*-
2+
3+
from pytzdata import set_directory
4+
5+
6+
def setup_module(module):
7+
set_directory()
8+
9+
10+
def teardown_module(module):
11+
set_directory()

tests/fixtures/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# -*- coding: utf-8 -*-
2+

tests/fixtures/tz/Europe/Paris

2.9 KB
Binary file not shown.

tests/test_set_directory.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# -*- coding: utf-8 -*-
2+
3+
import os
4+
import pytest
5+
from pytzdata import set_directory, tz_path, TimezoneNotFound
6+
7+
8+
fixtures_path = os.path.join(os.path.dirname(__file__), 'fixtures', 'tz')
9+
10+
11+
def setup_module(module):
12+
if 'PYTZDATA_TZDATADIR' in os.environ:
13+
del os.environ['PYTZDATA_TZDATADIR']
14+
15+
set_directory()
16+
17+
18+
def teardown_module(module):
19+
if 'PYTZDATA_TZDATADIR' in os.environ:
20+
del os.environ['PYTZDATA_TZDATADIR']
21+
22+
set_directory()
23+
24+
25+
def test_set_directory():
26+
set_directory(fixtures_path)
27+
28+
assert tz_path('Europe/Paris') == os.path.join(fixtures_path, 'Europe/Paris')
29+
30+
with pytest.raises(TimezoneNotFound):
31+
tz_path('America/New_York')
32+
33+
here = os.path.realpath(os.path.dirname(__file__))
34+
filepath = os.path.realpath(
35+
os.path.join(here, '..', 'pytzdata', 'zoneinfo', 'America', 'New_York')
36+
)
37+
38+
set_directory()
39+
40+
assert tz_path('America/New_York') == filepath
41+
42+
43+
def test_env_variable():
44+
os.environ['PYTZDATA_TZDATADIR'] = fixtures_path
45+
set_directory()
46+
47+
assert tz_path('Europe/Paris') == os.path.join(fixtures_path, 'Europe/Paris')
48+
49+
with pytest.raises(TimezoneNotFound):
50+
tz_path('America/New_York')
51+
52+
del os.environ['PYTZDATA_TZDATADIR']
53+
54+
here = os.path.realpath(os.path.dirname(__file__))
55+
filepath = os.path.realpath(
56+
os.path.join(here, '..', 'pytzdata', 'zoneinfo', 'America', 'New_York')
57+
)
58+
59+
set_directory()
60+
61+
assert tz_path('America/New_York') == filepath

tests/test_tz_file.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,24 @@
33
import os
44
import pytest
55

6-
from pytzdata import tz_file
6+
from pytzdata import tz_file, set_directory
77
from pytzdata.exceptions import TimezoneNotFound
88

99

10+
def setup_module(module):
11+
if 'PYTZDATA_TZDATADIR' in os.environ:
12+
del os.environ['PYTZDATA_TZDATADIR']
13+
14+
set_directory()
15+
16+
17+
def teardown_module(module):
18+
if 'PYTZDATA_TZDATADIR' in os.environ:
19+
del os.environ['PYTZDATA_TZDATADIR']
20+
21+
set_directory()
22+
23+
1024
def test_tz_file():
1125
here = os.path.realpath(os.path.dirname(__file__))
1226
filepath = os.path.realpath(

tests/test_tz_path.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,24 @@
33
import os
44
import pytest
55

6-
from pytzdata import tz_path
6+
from pytzdata import tz_path, set_directory
77
from pytzdata.exceptions import TimezoneNotFound
88

99

10+
def setup_module(module):
11+
if 'PYTZDATA_TZDATADIR' in os.environ:
12+
del os.environ['PYTZDATA_TZDATADIR']
13+
14+
set_directory()
15+
16+
17+
def teardown_module(module):
18+
if 'PYTZDATA_TZDATADIR' in os.environ:
19+
del os.environ['PYTZDATA_TZDATADIR']
20+
21+
set_directory()
22+
23+
1024
def test_tz_path():
1125
here = os.path.realpath(os.path.dirname(__file__))
1226
filepath = os.path.realpath(

0 commit comments

Comments
 (0)