Python 3 POST multipart/form-data with encode()

``` bash
server# FreeBSD 8.1-RELEASE
server# python3 -V
Python 3.3.0
server# python3 -c 'import requests; print(requests.__version__)'
1.2.0
```

I need to solve one issue by using Python3 and requests. So the main purpose:
I have Python script on my PC on the one hand and Web Forum with forms on the other hand.
Web forum accept in forms only multipart/form-data, so I POST them to it by:

``` python
s = requests.Session()
q = s.post('http://siteforum.com/index.php?', headers=headers, data=postdata, files={'':''})
```

All is ok, data are posted. 

But the main problem appears when I'm using text encoding in dictionary (cp1251) with .encode()

This is my example of the code:

``` python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import requests
def main():
    s_cp1251 = 'тест'.encode('cp1251')

    postdata = {
        "TopicTitle" : s_cp1251,
        "TopicDesc" : 'тест'.encode('cp1251'),
        "Post" : 'test'
    }
    headers = {
        'User-Agent' : 'Mozilla/5.0 (Windows NT 5.1; rv:20.0) Gecko/20100101 Firefox/20.0',
        'Accept' : 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        'Accept-Language' : 'en-US,en;q=0.5',
        'Accept-Encoding' : 'gzip, deflate',
        'Connection' : 'keep-alive'
    }

    s = requests.Session()
    q = s.post('http://siteforum.com/index.php?', headers=headers, data=postdata, files={'':''})
    print(q.status_code)

if __name__ == '__main__':
    main()
```
1. 'тест' is a 'test' in cyrillic windows 1251 encoding
2. POST multipart/form-data to Web Forum forms:
   `
   TopicTitle -> b'\xf2\xe5\xf1\xf2'
   `
   `
   TopicDesc -> b'\xf2\xe5\xf1\xf2'
   `
   `
   Post -> test
   `
3. The interesting thing is, that in The Python2 code example works fine, TopicTitle - is 'тест' in Web Forum form,
   but with Python 3 something like this: b'\xf2\xe5\xf1\xf2'
4. If i send POST form-urlencoded , everything is ok too.


Welcome to the exciting world of Python string handling!

The reason this is happening is that, somewhere in the web stack, someone is calling `str()` on your string. In Python3, calling `str()` on a bytestring returns the exact same thing as calling `repr()`. In this case, that's the byte literal form.

Unfortunately, the current rule is that urllib3 _must_ take native strings. This means you cannot encode your post data: they need to stay as unicode, to be encoded later.

Will your webserver accept UTF-8 encoded data?


Thank's for the quick answer ;)
No, native encoding on this web site is `Windows-1251`, I know it is not right, but I have no access to web server, so i can't change encoding or encode/decode my data in their forms.


In that case, can you leave the `files` argument out?


Not in all cases, but yes. If i leave `files` argument out, the data in `POST` send is  `form-urlencoded`, and everything is fine. Maybe i'll try to use it or use `Python2`. Anyway thanks for the explanation of the situation in `Python 3`.


Ok, and I'm sorry there's not much we can do about this at the moment. I'd offer to investigate adding functionality for using specific encodings, but we're in feature freeze at the moment.


@omatic-hacker is it possible to do `'тест'.encode('cp-1252').decode('utf-8')` or perhaps to `utf-16` or `utf-32` in the event that 8 isn't big enough? That would then be a string and might post correctly.


@sigmavirus24 That's not how character encodings work. Encoding as CP-1252 gives a series of bytes: decoding those bytes as UTF-8 will give you another 'unicode' string, but its characters will be meaningless. If you encode to CP-1252, you can only ever meaningfully decode as CP-1252.


Ugh, I need to get over whatever this cold is. Sorry.


No worries, I've felt the same before. =)