We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Encoding is always UTF-8 in POST data
## Long story short

I'm doing a `POST` request via `client.post`:

```
data = aiohttp.FormData({
            'FindText': name,
        }, charset='windows-1251')

client.post(base_url, params={'RowFrom': offset}, data=data)
```

where `name` contains some none-latin text (`'хан'`)

## Expected behaviour

POST data should contain: `FindText=%D5%E0%ED`

## Actual behaviour

`FindText=%D1%85%D0%B0%D0%BD'`

## Steps to reproduce

Looking through the code of `formdata.py:99`

```
urlencode(data, doseq=True).encode(charset),
```

I noticed, that `data` is urlencoded in UTF-8 first and then encoded to `windows-1251` (and that has no effect on `%D1...`).

For now, I just manually do in my code:

```
data = urlencode({
            'FindText': name,
        }, encoding='windows-1251')
```

And I get the string that I need.

Is it a bug? Or am I doing it wrong?

## Your environment

```
Python 3.6.0 (default, Jan 16 2017, 12:12:55) 
[GCC 6.3.1 20170109] on linux
---
aiohttp==2.0.3
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `aiohttp/formdata.py`
Content:
```
1 import io
2 from urllib.parse import urlencode
3 
4 from multidict import MultiDict, MultiDictProxy
5 
6 from . import hdrs, multipart, payload
7 from .helpers import guess_filename
8 
9 __all__ = ('FormData',)
10 
11 
12 class FormData:
13     """Helper class for multipart/form-data and
14     application/x-www-form-urlencoded body generation."""
15 
16     def __init__(self, fields=(), quote_fields=True, charset=None):
17         self._writer = multipart.MultipartWriter('form-data')
18         self._fields = []
19         self._is_multipart = False
20         self._quote_fields = quote_fields
21         self._charset = charset
22 
23         if isinstance(fields, dict):
24             fields = list(fields.items())
25         elif not isinstance(fields, (list, tuple)):
26             fields = (fields,)
27         self.add_fields(*fields)
28 
29     @property
30     def is_multipart(self):
31         return self._is_multipart
32 
33     def add_field(self, name, value, *, content_type=None, filename=None,
34                   content_transfer_encoding=None):
35 
36         if isinstance(value, io.IOBase):
37             self._is_multipart = True
38         elif isinstance(value, (bytes, bytearray, memoryview)):
39             if filename is None and content_transfer_encoding is None:
40                 filename = name
41 
42         type_options = MultiDict({'name': name})
43         if filename is not None and not isinstance(filename, str):
44             raise TypeError('filename must be an instance of str. '
45                             'Got: %s' % filename)
46         if filename is None and isinstance(value, io.IOBase):
47             filename = guess_filename(value, name)
48         if filename is not None:
49             type_options['filename'] = filename
50             self._is_multipart = True
51 
52         headers = {}
53         if content_type is not None:
54             if not isinstance(content_type, str):
55                 raise TypeError('content_type must be an instance of str. '
56                                 'Got: %s' % content_type)
57             headers[hdrs.CONTENT_TYPE] = content_type
58             self._is_multipart = True
59         if content_transfer_encoding is not None:
60             if not isinstance(content_transfer_encoding, str):
61                 raise TypeError('content_transfer_encoding must be an instance'
62                                 ' of str. Got: %s' % content_transfer_encoding)
63             headers[hdrs.CONTENT_TRANSFER_ENCODING] = content_transfer_encoding
64             self._is_multipart = True
65 
66         self._fields.append((type_options, headers, value))
67 
68     def add_fields(self, *fields):
69         to_add = list(fields)
70 
71         while to_add:
72             rec = to_add.pop(0)
73 
74             if isinstance(rec, io.IOBase):
75                 k = guess_filename(rec, 'unknown')
76                 self.add_field(k, rec)
77 
78             elif isinstance(rec, (MultiDictProxy, MultiDict)):
79                 to_add.extend(rec.items())
80 
81             elif isinstance(rec, (list, tuple)) and len(rec) == 2:
82                 k, fp = rec
83                 self.add_field(k, fp)
84 
85             else:
86                 raise TypeError('Only io.IOBase, multidict and (name, file) '
87                                 'pairs allowed, use .add_field() for passing '
88                                 'more complex parameters, got {!r}'
89                                 .format(rec))
90 
91     def _gen_form_urlencoded(self):
92         # form data (x-www-form-urlencoded)
93         data = []
94         for type_options, _, value in self._fields:
95             data.append((type_options['name'], value))
96 
97         charset = self._charset if self._charset is not None else 'utf-8'
98         return payload.BytesPayload(
99             urlencode(data, doseq=True).encode(charset),
100             content_type='application/x-www-form-urlencoded')
101 
102     def _gen_form_data(self):
103         """Encode a list of fields using the multipart/form-data MIME format"""
104         for dispparams, headers, value in self._fields:
105             try:
106                 if hdrs.CONTENT_TYPE in headers:
107                     part = payload.get_payload(
108                         value, content_type=headers[hdrs.CONTENT_TYPE],
109                         headers=headers, encoding=self._charset)
110                 else:
111                     part = payload.get_payload(
112                         value, headers=headers, encoding=self._charset)
113             except Exception as exc:
114                 raise TypeError(
115                     'Can not serialize value type: %r\n '
116                     'headers: %r\n value: %r' % (
117                         type(value), headers, value)) from exc
118 
119             if dispparams:
120                 part.set_content_disposition(
121                     'form-data', quote_fields=self._quote_fields, **dispparams
122                 )
123                 # FIXME cgi.FieldStorage doesn't likes body parts with
124                 # Content-Length which were sent via chunked transfer encoding
125                 part.headers.pop(hdrs.CONTENT_LENGTH, None)
126 
127             self._writer.append_payload(part)
128 
129         return self._writer
130 
131     def __call__(self):
132         if self._is_multipart:
133             return self._gen_form_data()
134         else:
135             return self._gen_form_urlencoded()
136
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/aiohttp/formdata.py b/aiohttp/formdata.py
--- a/aiohttp/formdata.py
+++ b/aiohttp/formdata.py
@@ -96,7 +96,7 @@
 
         charset = self._charset if self._charset is not None else 'utf-8'
         return payload.BytesPayload(
-            urlencode(data, doseq=True).encode(charset),
+            urlencode(data, doseq=True, encoding=charset).encode(),
             content_type='application/x-www-form-urlencoded')
 
     def _gen_form_data(self):

{"golden_diff": "diff --git a/aiohttp/formdata.py b/aiohttp/formdata.py\n--- a/aiohttp/formdata.py\n+++ b/aiohttp/formdata.py\n@@ -96,7 +96,7 @@\n \n         charset = self._charset if self._charset is not None else 'utf-8'\n         return payload.BytesPayload(\n-            urlencode(data, doseq=True).encode(charset),\n+            urlencode(data, doseq=True, encoding=charset).encode(),\n             content_type='application/x-www-form-urlencoded')\n \n     def _gen_form_data(self):\n", "issue": "Encoding is always UTF-8 in POST data\n## Long story short\r\n\r\nI'm doing a `POST` request via `client.post`:\r\n\r\n```\r\ndata = aiohttp.FormData({\r\n            'FindText': name,\r\n        }, charset='windows-1251')\r\n\r\nclient.post(base_url, params={'RowFrom': offset}, data=data)\r\n```\r\n\r\nwhere `name` contains some none-latin text (`'\u0445\u0430\u043d'`)\r\n\r\n## Expected behaviour\r\n\r\nPOST data should contain: `FindText=%D5%E0%ED`\r\n\r\n## Actual behaviour\r\n\r\n`FindText=%D1%85%D0%B0%D0%BD'`\r\n\r\n## Steps to reproduce\r\n\r\nLooking through the code of `formdata.py:99`\r\n\r\n```\r\nurlencode(data, doseq=True).encode(charset),\r\n```\r\n\r\nI noticed, that `data` is urlencoded in UTF-8 first and then encoded to `windows-1251` (and that has no effect on `%D1...`).\r\n\r\nFor now, I just manually do in my code:\r\n\r\n```\r\ndata = urlencode({\r\n            'FindText': name,\r\n        }, encoding='windows-1251')\r\n```\r\n\r\nAnd I get the string that I need.\r\n\r\nIs it a bug? Or am I doing it wrong?\r\n\r\n## Your environment\r\n\r\n```\r\nPython 3.6.0 (default, Jan 16 2017, 12:12:55) \r\n[GCC 6.3.1 20170109] on linux\r\n---\r\naiohttp==2.0.3\r\n```\r\n\n", "before_files": [{"content": "import io\nfrom urllib.parse import urlencode\n\nfrom multidict import MultiDict, MultiDictProxy\n\nfrom . import hdrs, multipart, payload\nfrom .helpers import guess_filename\n\n__all__ = ('FormData',)\n\n\nclass FormData:\n    \"\"\"Helper class for multipart/form-data and\n    application/x-www-form-urlencoded body generation.\"\"\"\n\n    def __init__(self, fields=(), quote_fields=True, charset=None):\n        self._writer = multipart.MultipartWriter('form-data')\n        self._fields = []\n        self._is_multipart = False\n        self._quote_fields = quote_fields\n        self._charset = charset\n\n        if isinstance(fields, dict):\n            fields = list(fields.items())\n        elif not isinstance(fields, (list, tuple)):\n            fields = (fields,)\n        self.add_fields(*fields)\n\n    @property\n    def is_multipart(self):\n        return self._is_multipart\n\n    def add_field(self, name, value, *, content_type=None, filename=None,\n                  content_transfer_encoding=None):\n\n        if isinstance(value, io.IOBase):\n            self._is_multipart = True\n        elif isinstance(value, (bytes, bytearray, memoryview)):\n            if filename is None and content_transfer_encoding is None:\n                filename = name\n\n        type_options = MultiDict({'name': name})\n        if filename is not None and not isinstance(filename, str):\n            raise TypeError('filename must be an instance of str. '\n                            'Got: %s' % filename)\n        if filename is None and isinstance(value, io.IOBase):\n            filename = guess_filename(value, name)\n        if filename is not None:\n            type_options['filename'] = filename\n            self._is_multipart = True\n\n        headers = {}\n        if content_type is not None:\n            if not isinstance(content_type, str):\n                raise TypeError('content_type must be an instance of str. '\n                                'Got: %s' % content_type)\n            headers[hdrs.CONTENT_TYPE] = content_type\n            self._is_multipart = True\n        if content_transfer_encoding is not None:\n            if not isinstance(content_transfer_encoding, str):\n                raise TypeError('content_transfer_encoding must be an instance'\n                                ' of str. Got: %s' % content_transfer_encoding)\n            headers[hdrs.CONTENT_TRANSFER_ENCODING] = content_transfer_encoding\n            self._is_multipart = True\n\n        self._fields.append((type_options, headers, value))\n\n    def add_fields(self, *fields):\n        to_add = list(fields)\n\n        while to_add:\n            rec = to_add.pop(0)\n\n            if isinstance(rec, io.IOBase):\n                k = guess_filename(rec, 'unknown')\n                self.add_field(k, rec)\n\n            elif isinstance(rec, (MultiDictProxy, MultiDict)):\n                to_add.extend(rec.items())\n\n            elif isinstance(rec, (list, tuple)) and len(rec) == 2:\n                k, fp = rec\n                self.add_field(k, fp)\n\n            else:\n                raise TypeError('Only io.IOBase, multidict and (name, file) '\n                                'pairs allowed, use .add_field() for passing '\n                                'more complex parameters, got {!r}'\n                                .format(rec))\n\n    def _gen_form_urlencoded(self):\n        # form data (x-www-form-urlencoded)\n        data = []\n        for type_options, _, value in self._fields:\n            data.append((type_options['name'], value))\n\n        charset = self._charset if self._charset is not None else 'utf-8'\n        return payload.BytesPayload(\n            urlencode(data, doseq=True).encode(charset),\n            content_type='application/x-www-form-urlencoded')\n\n    def _gen_form_data(self):\n        \"\"\"Encode a list of fields using the multipart/form-data MIME format\"\"\"\n        for dispparams, headers, value in self._fields:\n            try:\n                if hdrs.CONTENT_TYPE in headers:\n                    part = payload.get_payload(\n                        value, content_type=headers[hdrs.CONTENT_TYPE],\n                        headers=headers, encoding=self._charset)\n                else:\n                    part = payload.get_payload(\n                        value, headers=headers, encoding=self._charset)\n            except Exception as exc:\n                raise TypeError(\n                    'Can not serialize value type: %r\\n '\n                    'headers: %r\\n value: %r' % (\n                        type(value), headers, value)) from exc\n\n            if dispparams:\n                part.set_content_disposition(\n                    'form-data', quote_fields=self._quote_fields, **dispparams\n                )\n                # FIXME cgi.FieldStorage doesn't likes body parts with\n                # Content-Length which were sent via chunked transfer encoding\n                part.headers.pop(hdrs.CONTENT_LENGTH, None)\n\n            self._writer.append_payload(part)\n\n        return self._writer\n\n    def __call__(self):\n        if self._is_multipart:\n            return self._gen_form_data()\n        else:\n            return self._gen_form_urlencoded()\n", "path": "aiohttp/formdata.py"}], "after_files": [{"content": "import io\nfrom urllib.parse import urlencode\n\nfrom multidict import MultiDict, MultiDictProxy\n\nfrom . import hdrs, multipart, payload\nfrom .helpers import guess_filename\n\n__all__ = ('FormData',)\n\n\nclass FormData:\n    \"\"\"Helper class for multipart/form-data and\n    application/x-www-form-urlencoded body generation.\"\"\"\n\n    def __init__(self, fields=(), quote_fields=True, charset=None):\n        self._writer = multipart.MultipartWriter('form-data')\n        self._fields = []\n        self._is_multipart = False\n        self._quote_fields = quote_fields\n        self._charset = charset\n\n        if isinstance(fields, dict):\n            fields = list(fields.items())\n        elif not isinstance(fields, (list, tuple)):\n            fields = (fields,)\n        self.add_fields(*fields)\n\n    @property\n    def is_multipart(self):\n        return self._is_multipart\n\n    def add_field(self, name, value, *, content_type=None, filename=None,\n                  content_transfer_encoding=None):\n\n        if isinstance(value, io.IOBase):\n            self._is_multipart = True\n        elif isinstance(value, (bytes, bytearray, memoryview)):\n            if filename is None and content_transfer_encoding is None:\n                filename = name\n\n        type_options = MultiDict({'name': name})\n        if filename is not None and not isinstance(filename, str):\n            raise TypeError('filename must be an instance of str. '\n                            'Got: %s' % filename)\n        if filename is None and isinstance(value, io.IOBase):\n            filename = guess_filename(value, name)\n        if filename is not None:\n            type_options['filename'] = filename\n            self._is_multipart = True\n\n        headers = {}\n        if content_type is not None:\n            if not isinstance(content_type, str):\n                raise TypeError('content_type must be an instance of str. '\n                                'Got: %s' % content_type)\n            headers[hdrs.CONTENT_TYPE] = content_type\n            self._is_multipart = True\n        if content_transfer_encoding is not None:\n            if not isinstance(content_transfer_encoding, str):\n                raise TypeError('content_transfer_encoding must be an instance'\n                                ' of str. Got: %s' % content_transfer_encoding)\n            headers[hdrs.CONTENT_TRANSFER_ENCODING] = content_transfer_encoding\n            self._is_multipart = True\n\n        self._fields.append((type_options, headers, value))\n\n    def add_fields(self, *fields):\n        to_add = list(fields)\n\n        while to_add:\n            rec = to_add.pop(0)\n\n            if isinstance(rec, io.IOBase):\n                k = guess_filename(rec, 'unknown')\n                self.add_field(k, rec)\n\n            elif isinstance(rec, (MultiDictProxy, MultiDict)):\n                to_add.extend(rec.items())\n\n            elif isinstance(rec, (list, tuple)) and len(rec) == 2:\n                k, fp = rec\n                self.add_field(k, fp)\n\n            else:\n                raise TypeError('Only io.IOBase, multidict and (name, file) '\n                                'pairs allowed, use .add_field() for passing '\n                                'more complex parameters, got {!r}'\n                                .format(rec))\n\n    def _gen_form_urlencoded(self):\n        # form data (x-www-form-urlencoded)\n        data = []\n        for type_options, _, value in self._fields:\n            data.append((type_options['name'], value))\n\n        charset = self._charset if self._charset is not None else 'utf-8'\n        return payload.BytesPayload(\n            urlencode(data, doseq=True, encoding=charset).encode(),\n            content_type='application/x-www-form-urlencoded')\n\n    def _gen_form_data(self):\n        \"\"\"Encode a list of fields using the multipart/form-data MIME format\"\"\"\n        for dispparams, headers, value in self._fields:\n            try:\n                if hdrs.CONTENT_TYPE in headers:\n                    part = payload.get_payload(\n                        value, content_type=headers[hdrs.CONTENT_TYPE],\n                        headers=headers, encoding=self._charset)\n                else:\n                    part = payload.get_payload(\n                        value, headers=headers, encoding=self._charset)\n            except Exception as exc:\n                raise TypeError(\n                    'Can not serialize value type: %r\\n '\n                    'headers: %r\\n value: %r' % (\n                        type(value), headers, value)) from exc\n\n            if dispparams:\n                part.set_content_disposition(\n                    'form-data', quote_fields=self._quote_fields, **dispparams\n                )\n                # FIXME cgi.FieldStorage doesn't likes body parts with\n                # Content-Length which were sent via chunked transfer encoding\n                part.headers.pop(hdrs.CONTENT_LENGTH, None)\n\n            self._writer.append_payload(part)\n\n        return self._writer\n\n    def __call__(self):\n        if self._is_multipart:\n            return self._gen_form_data()\n        else:\n            return self._gen_form_urlencoded()\n", "path": "aiohttp/formdata.py"}]}