Repository: joke2k/faker (python)

Issue:
[Question] Why is Faker dependent on tzdata?

We are trying to use Faker in an Odoo addon and are currently facing the issue, that tzdata is breaking Odoo on Ubuntu 24.04 (because [odoo](https://github.com/odoo/odoo/) depends on [pytz](https://github.com/stub42/pytz), which uses zoneinfo, [which behaves differently when tzdata is installed](https://github.com/python/cpython/blob/6493a6aaf3cfd7ccf6bb9de76e1a5c5e28feb75b/Lib/zoneinfo/_tzpath.py#L134) for deprecated timezones like `US/Eastern`).

From the history I can see, that the dependency was introduced shortly after [removing dateutil](https://github.com/joke2k/faker/pull/2173), but I don't understand why.

Can you tell us the reason?


Patch:
diff --git a/faker/providers/date_time/__init__.py b/faker/providers/date_time/__init__.py
index dc9533ab7a..7a447d4f56 100644
--- a/faker/providers/date_time/__init__.py
+++ b/faker/providers/date_time/__init__.py
@@ -2549,7 +2549,16 @@ def pytimezone(self, *args: Any, **kwargs: Any) -> Optional[TzInfo]:
 
         :sample:
         """
-        return zoneinfo.ZoneInfo(self.timezone(*args, **kwargs))  # type: ignore
+        try:
+            return zoneinfo.ZoneInfo(self.timezone(*args, **kwargs))  # type: ignore
+        except zoneinfo.ZoneInfoNotFoundError as exc:
+            msg = (
+                f"Timezone data not found: {exc}. "
+                "The 'tzdata' package provides timezone database files needed by Python's zoneinfo module. "
+                "While most systems have these files built-in, some minimal environments may not. "
+                f"Install faker with tzdata support: pip install 'faker[tzdata]'"
+            )
+            raise ImportError(msg) from exc
 
     def date_of_birth(
         self,
diff --git a/setup.py b/setup.py
index 345f8c705f..2543153880 100644
--- a/setup.py
+++ b/setup.py
@@ -67,6 +67,9 @@
     },
     platforms=["any"],
     zip_safe=zip_safe,
-    install_requires=["tzdata"],
+    install_requires=['tzdata; platform_system=="Windows"'],
+    extras_require={
+        "tzdata": ["tzdata"],
+    },
     python_requires=">=3.10",
 )


Test patch:
diff --git a/tests/providers/test_date_time.py b/tests/providers/test_date_time.py
index 58152b6752..56ee5687f7 100644
--- a/tests/providers/test_date_time.py
+++ b/tests/providers/test_date_time.py
@@ -177,6 +177,26 @@ def test_pytimezone_usable(self):
         date = datetime(2000, 1, 1, tzinfo=pytz)
         assert date.tzinfo == pytz
 
+    def test_pytimezone_tzdata_missing_error(self):
+        """Test that helpful error is raised when tzdata is needed but missing."""
+        from unittest.mock import patch
+        
+        # Mock ZoneInfo to raise ZoneInfoNotFoundError
+        with patch("zoneinfo.ZoneInfo") as mock_zoneinfo:
+            mock_zoneinfo.side_effect = zoneinfo.ZoneInfoNotFoundError("America/New_York")
+            
+            # Should raise ImportError with helpful message
+            with pytest.raises(ImportError) as exc_info:
+                self.fake.pytimezone()
+            
+            error_msg = str(exc_info.value)
+            # Verify error message contains helpful information
+            assert "tzdata" in error_msg.lower()
+            assert "faker[tzdata]" in error_msg
+            assert "pip install" in error_msg.lower()
+            # Verify it explains what tzdata is
+            assert "timezone" in error_msg.lower()
+
     def test_datetimes_with_and_without_tzinfo(self):
         assert self.fake.date_time().tzinfo is None
         assert self.fake.date_time(utc).tzinfo == utc