Repository: joke2k/faker

Issue:
Default to Safe Email Addresses
By default `faker.email()` will generate email addresses that are potentially valid, especially considering `@gmail.com`, `@yahoo.com` and other free providers are included in the data. 

This can be problematic considering there are a few potential outcomes that can come of this that can affect the developers using `faker` or the people who have unwittingly had their emails generated as part of a test suite.

While there is the argument that developers should be configuring mailers in test environments to not send outbound, using the in-built `ascii_safe_email()` or provide the optional `domain` argument, I also think that `faker` would benefit from having the `email()` provider use the safe domains by default and require developers to enable unsafe email address generation.

### Expected behavior

Here was something I very quickly put together, to demonstrate what I'd like to see happen, with how it could be used by a developer:

```python
@lowercase
def email(self, unsafe=False, domain=None):
    if domain:
      email = f'{self.user_name()}@{domain}'
    if unsafe:
      pattern = self.random_element(self.email_formats)
      email = "".join(self.generator.parse(pattern).split(" "))
    else:
      domain = self.random_element(self.safe_domain_name)
      email = f'{self.user_name()}@{domain}'
    return email
```

Which when used by the developer would look something like:
```
fake = Faker()

# safe by default
print(fake.email())

# enable unsafe mode
print(fake.email(unsafe=True))

# use a domain
print(fake.email(domain="mycooldomain.com"))
```

```
>>> justinramos@domain.com
>>> justinramos@jackson-cuevas.net
>>> justinramos@mycooldomain.com
```

### Actual behavior

Currently, the default behaviour is for `faker` to generate email addresses that may be valid. 

I'd be more than happy to open a PR to make these changes if you'd like to pursue this approach!

Thanks!


Discussion:
Thank you @errbufferoverfl !

I think that's a good idea. The only thing I'm not sure about is the argument name. I wonder is using `safe=True` as default would be more intuitive.
@fcurella using `safe=True` is a lot more intuitive, I'll put together a PR this week and we can go from there.

Resolving patch:
diff --git a/faker/providers/internet/__init__.py b/faker/providers/internet/__init__.py
--- a/faker/providers/internet/__init__.py
+++ b/faker/providers/internet/__init__.py
@@ -119,9 +119,11 @@ def _to_ascii(self, string):
         return string
 
     @lowercase
-    def email(self, domain=None):
+    def email(self, safe=True, domain=None):
         if domain:
             email = f'{self.user_name()}@{domain}'
+        elif safe:
+            email = f'{self.user_name()}@{self.safe_domain_name()}'
         else:
             pattern = self.random_element(self.email_formats)
             email = "".join(self.generator.parse(pattern).split(" "))


Test patch:
diff --git a/tests/providers/test_internet.py b/tests/providers/test_internet.py
--- a/tests/providers/test_internet.py
+++ b/tests/providers/test_internet.py
@@ -39,6 +39,18 @@ def test_email(self, faker, num_samples):
             email = faker.email()
             assert '@' in email
 
+    def test_safe_default_email(self, faker, num_samples):
+        expected_domains = ['example.com', 'example.org', 'example.net']
+        for _ in range(num_samples):
+            email = faker.email()
+            assert email.split('@')[1] in expected_domains
+
+    def test_unsafe_email(self, faker, num_samples):
+        not_expected_domains = ['example.com', 'example.org', 'example.net']
+        for _ in range(num_samples):
+            email = faker.email(safe=False)
+            assert email.split('@')[1] not in not_expected_domains
+
     def test_email_with_domain(self, faker):
         domain = 'example.com'
         email = faker.email(domain=domain)