Repository: joke2k/faker

Issue:
Can we have a "non formatted" postcode for pt_BR localization?
* Faker version: 3.0.0
* OS: Windows 10 pro (x64)

I'm using Faker to generate postcode using the pt_BR localization. The example on [`address` section](https://faker.readthedocs.io/en/latest/locales/pt_BR.html#faker-providers-address) shows a numeric sequence containing 8 numbers and that was what I expect.

```python
fake.postcode()
# '35285968'
```

Anyway, I'm getting some problems in my tests because the output of this function sometimes returns a formatted postcode. Example:

```python
fake.postcode()
# '35285968'    -- cool :D

fake.postcode()
# '35285-968'    -- sad :(
```

### Expected behavior

I would like to generate postcode exactly hows the documentation says, just numbers, without any formatting. As a temporary solution, I'm using a `replace` to remove any `-` present, but I would like to have a cleaner solution using just Faker. Maybe this "formatted" version can be specified by an argument in the `postcode` function. 

### Actual behavior

Getting a non deterministic postcode, I don't know which type of postalcode format I will get.


Discussion:
I nice implementation should be `fake.postcode(formated=True)`

By default can be True, 'Cause many times you need a formatted postcode, but in other moments you need a raw postcode.

In many cases, pt_BR localization has these problems 
What's the most common case use in Brazil? Do postcodes ever get printed without the hyphen?
I think that the formatted postcode is just something "visual" for the user.
For manipulation and persistence, the raw postcode is typically used.
> I think that the formatted postcode is just something "visual" for the user.
For manipulation and persistence, the raw postcode is typically used.

Let me rephrase my question. Does the average person in Brazil encounter raw postcodes (ie: without the hypens) in their daily life?
I understand where @reebr might be coming from, because in some systems, postcodes like this are only ever stored in "raw" form, i.e. no dashes, whitespaces, and what-have-you that only serve as visual aids for humans. The visual aids might only be for presentation purposes, e.g. part of the GUI/physical forms to make them easy to fill out or formatted only when displayed to end users, so formatted postcodes can be out of scope for certain use cases. 

Perhaps we can do something like this (with better variable names) for similar provider methods as @dunossauro suggested. This way, it will still be backward compatible, and there is an option to only generate the raw forms.
 
```
Class Provider:

    postcode_raw_templates = ( '########', )

    postcode_all_templates = postcode_raw_templates + ( '#####-###', )

    def postcode(self, formatted=True):
        templates = self.postcode_all_templates if formatted else self.postcode_raw_templates 
        return self.bothify(self.random_element(templates)).upper()
```
@malefice That solution is fine short-term, but at some point we may have to decide if we want to tackle this issue (ie: outputting formatted vs non-formatted) across providers in a more generalized way.
I think it will prove very difficult to generalize this for all provider methods, so the second best thing IMO is to have provider methods that are at least able to output fake data in (1) raw form, (2) simplest noncomposite form, or (3) a format that adheres to an international standard.

An example of (1) will be simple alphanumeric strings like postcodes, credit card numbers, and identity numbers. For (2), a good example of this will be addresses (which `Faker` already does) wherein it is built upon simpler stuff like street names, building name, city, etc. An example of (3) will be E.164 for phone numbering.

I favor unformatted data or in simplest form whenever possible, because it is far more trivial to change the presentation later on VS parsing through many different formats to get a raw form or to change the formatting.


How about you? What are your thoughts and personal experience on this? Oh and happy new year and decade!

Resolving patch:
diff --git a/faker/providers/address/pt_BR/__init__.py b/faker/providers/address/pt_BR/__init__.py
--- a/faker/providers/address/pt_BR/__init__.py
+++ b/faker/providers/address/pt_BR/__init__.py
@@ -99,7 +99,8 @@ class Provider(AddressProvider):
 
     building_number_formats = ('%', '%#', '%#', '%#', '%##')
 
-    postcode_formats = ('########', '#####-###')
+    postcode_raw_formats = ('########', )
+    postcode_all_formats = postcode_raw_formats + ('#####-###', )
 
     bairros = (
         'Aarão Reis', 'Acaba Mundo', 'Acaiaca', 'Ademar Maldonado', 'Aeroporto', 'Aguas Claras', 'Alípio De Melo',
@@ -296,6 +297,16 @@ def bairro(self):
         """
         return self.random_element(self.bairros)
 
+    def postcode(self, formatted=True):
+        """
+        Randomly returns a postcode.
+        :param formatted: True to allow formatted postcodes, else False (default True)
+        :example formatted: '41224-212' '83992-291' '12324322'
+        :example raw: '43920231' '34239530'
+        """
+        template = self.postcode_all_formats if formatted else self.postcode_raw_formats
+        return self.bothify(self.random_element(template))
+
     # aliases
     def neighborhood(self):
         return self.bairro()


Test patch:
diff --git a/tests/providers/test_address.py b/tests/providers/test_address.py
--- a/tests/providers/test_address.py
+++ b/tests/providers/test_address.py
@@ -1029,6 +1029,18 @@ def test_address(self):
         address = self.fake.address()
         assert isinstance(address, str)
 
+    def test_raw_postcode(self):
+        for _ in range(100):
+            postcode = self.fake.postcode(formatted=False)
+            assert isinstance(postcode, str)
+            assert re.match(r'^\d{8}$', postcode)
+
+    def test_formatted_postcode(self):
+        for _ in range(100):
+            postcode = self.fake.postcode()
+            assert isinstance(postcode, str)
+            assert re.match(r'^\d{5}-?\d{3}$', postcode)
+
 
 class TestPtPT(unittest.TestCase):