test_imports.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. import sys
  2. import unittest
  3. import pytest
  4. import six
  5. MODULE_TYPE = type(sys)
  6. # Tests live in datetutil/test which cause a RuntimeWarning for Python2 builds.
  7. # But since we expect lazy imports tests to fail for Python < 3.7 we'll ignore those
  8. # warnings with this filter.
  9. if six.PY2:
  10. filter_import_warning = pytest.mark.filterwarnings("ignore::RuntimeWarning")
  11. else:
  12. def filter_import_warning(f):
  13. return f
  14. @pytest.fixture(scope="function")
  15. def clean_import():
  16. """Create a somewhat clean import base for lazy import tests"""
  17. du_modules = {
  18. mod_name: mod
  19. for mod_name, mod in sys.modules.items()
  20. if mod_name.startswith("dateutil")
  21. }
  22. other_modules = {
  23. mod_name for mod_name in sys.modules if mod_name not in du_modules
  24. }
  25. for mod_name in du_modules:
  26. del sys.modules[mod_name]
  27. yield
  28. # Delete anything that wasn't in the origin sys.modules list
  29. for mod_name in list(sys.modules):
  30. if mod_name not in other_modules:
  31. del sys.modules[mod_name]
  32. # Restore original modules
  33. for mod_name, mod in du_modules.items():
  34. sys.modules[mod_name] = mod
  35. @filter_import_warning
  36. @pytest.mark.parametrize(
  37. "module",
  38. ["easter", "parser", "relativedelta", "rrule", "tz", "utils", "zoneinfo"],
  39. )
  40. def test_lazy_import(clean_import, module):
  41. """Test that dateutil.[submodule] works for py version > 3.7"""
  42. import dateutil, importlib
  43. if sys.version_info < (3, 7):
  44. pytest.xfail("Lazy loading does not work for Python < 3.7")
  45. mod_obj = getattr(dateutil, module, None)
  46. assert isinstance(mod_obj, MODULE_TYPE)
  47. mod_imported = importlib.import_module("dateutil.%s" % module)
  48. assert mod_obj is mod_imported
  49. HOST_IS_WINDOWS = sys.platform.startswith('win')
  50. def test_import_version_str():
  51. """ Test that dateutil.__version__ can be imported"""
  52. from dateutil import __version__
  53. def test_import_version_root():
  54. import dateutil
  55. assert hasattr(dateutil, '__version__')
  56. # Test that dateutil.easter-related imports work properly
  57. def test_import_easter_direct():
  58. import dateutil.easter
  59. def test_import_easter_from():
  60. from dateutil import easter
  61. def test_import_easter_start():
  62. from dateutil.easter import easter
  63. # Test that dateutil.parser-related imports work properly
  64. def test_import_parser_direct():
  65. import dateutil.parser
  66. def test_import_parser_from():
  67. from dateutil import parser
  68. def test_import_parser_all():
  69. # All interface
  70. from dateutil.parser import parse
  71. from dateutil.parser import parserinfo
  72. # Other public classes
  73. from dateutil.parser import parser
  74. for var in (parse, parserinfo, parser):
  75. assert var is not None
  76. # Test that dateutil.relativedelta-related imports work properly
  77. def test_import_relative_delta_direct():
  78. import dateutil.relativedelta
  79. def test_import_relative_delta_from():
  80. from dateutil import relativedelta
  81. def test_import_relative_delta_all():
  82. from dateutil.relativedelta import relativedelta
  83. from dateutil.relativedelta import MO, TU, WE, TH, FR, SA, SU
  84. for var in (relativedelta, MO, TU, WE, TH, FR, SA, SU):
  85. assert var is not None
  86. # In the public interface but not in all
  87. from dateutil.relativedelta import weekday
  88. assert weekday is not None
  89. # Test that dateutil.rrule related imports work properly
  90. def test_import_rrule_direct():
  91. import dateutil.rrule
  92. def test_import_rrule_from():
  93. from dateutil import rrule
  94. def test_import_rrule_all():
  95. from dateutil.rrule import rrule
  96. from dateutil.rrule import rruleset
  97. from dateutil.rrule import rrulestr
  98. from dateutil.rrule import YEARLY, MONTHLY, WEEKLY, DAILY
  99. from dateutil.rrule import HOURLY, MINUTELY, SECONDLY
  100. from dateutil.rrule import MO, TU, WE, TH, FR, SA, SU
  101. rr_all = (rrule, rruleset, rrulestr,
  102. YEARLY, MONTHLY, WEEKLY, DAILY,
  103. HOURLY, MINUTELY, SECONDLY,
  104. MO, TU, WE, TH, FR, SA, SU)
  105. for var in rr_all:
  106. assert var is not None
  107. # In the public interface but not in all
  108. from dateutil.rrule import weekday
  109. assert weekday is not None
  110. # Test that dateutil.tz related imports work properly
  111. def test_import_tztest_direct():
  112. import dateutil.tz
  113. def test_import_tz_from():
  114. from dateutil import tz
  115. def test_import_tz_all():
  116. from dateutil.tz import tzutc
  117. from dateutil.tz import tzoffset
  118. from dateutil.tz import tzlocal
  119. from dateutil.tz import tzfile
  120. from dateutil.tz import tzrange
  121. from dateutil.tz import tzstr
  122. from dateutil.tz import tzical
  123. from dateutil.tz import gettz
  124. from dateutil.tz import tzwin
  125. from dateutil.tz import tzwinlocal
  126. from dateutil.tz import UTC
  127. from dateutil.tz import datetime_ambiguous
  128. from dateutil.tz import datetime_exists
  129. from dateutil.tz import resolve_imaginary
  130. tz_all = ["tzutc", "tzoffset", "tzlocal", "tzfile", "tzrange",
  131. "tzstr", "tzical", "gettz", "datetime_ambiguous",
  132. "datetime_exists", "resolve_imaginary", "UTC"]
  133. tz_all += ["tzwin", "tzwinlocal"] if sys.platform.startswith("win") else []
  134. lvars = locals()
  135. for var in tz_all:
  136. assert lvars[var] is not None
  137. # Test that dateutil.tzwin related imports work properly
  138. @pytest.mark.skipif(not HOST_IS_WINDOWS, reason="Requires Windows")
  139. def test_import_tz_windows_direct():
  140. import dateutil.tzwin
  141. @pytest.mark.skipif(not HOST_IS_WINDOWS, reason="Requires Windows")
  142. def test_import_tz_windows_from():
  143. from dateutil import tzwin
  144. @pytest.mark.skipif(not HOST_IS_WINDOWS, reason="Requires Windows")
  145. def test_import_tz_windows_star():
  146. from dateutil.tzwin import tzwin
  147. from dateutil.tzwin import tzwinlocal
  148. tzwin_all = [tzwin, tzwinlocal]
  149. for var in tzwin_all:
  150. assert var is not None
  151. # Test imports of Zone Info
  152. def test_import_zone_info_direct():
  153. import dateutil.zoneinfo
  154. def test_import_zone_info_from():
  155. from dateutil import zoneinfo
  156. def test_import_zone_info_star():
  157. from dateutil.zoneinfo import gettz
  158. from dateutil.zoneinfo import gettz_db_metadata
  159. from dateutil.zoneinfo import rebuild
  160. zi_all = (gettz, gettz_db_metadata, rebuild)
  161. for var in zi_all:
  162. assert var is not None