Issue 1:
This issue is related to character encoding of the request parameters when sending a GET request. In my scenario, I need the percent character to not be encoded as %25. The urllib.parse.urlencode function has the safe input for this purpose. However, the requests.get function does not have such input. Therefore, I use urllib.parse.urlencode with safe='%' to get an ampersand-separated string of my request parameters and send that in for the params value of requests.get. Even with this trick, the response that I get is different than what I get with urllib.request.Request. The interesting thing is that when I print response.url (where response is the response object of requests.get), I see that the percent character is not encoded, but still the response is incorrect. It seems like encoding takes place somewhere else. I really hate abandoning the requests package because of this defect. I was wondering if there is any way this can be fixed in a future release.

Expected Result

<result>
<TotalMatches>1135</TotalMatches>
<TotalPages>57</TotalPages>
<PageNumber>1</PageNumber>
<item>
<mid>36145</mid>
<merchantname> ...

Actual Result

<result>
<TotalMatches>0</TotalMatches>
<TotalPages>0</TotalPages>
<PageNumber>1</PageNumber>
</result>

Reproduction Steps

This is the URL I am hitting:

http://productsearch.linksynergy.com/productsearch?token=<token>&mid=36145&cat=Women%27s+Warehouse+Sale+-+Up+To+70%+Off&keyword=dress&pagenumber=1

Unfortunately, I cannot share the token. The decoded value for the cat parameter is "Women's Warehouse Sale - Up To 70% Off". The percent sign after 70 is the one that is causing the issue.

import requests

with requests.Session() as http_session:
response = http_session.get('http://productsearch.linksynergy.com/productsearch', params='token=<token>&mid=36145&cat=Women%27s+Warehouse+Sale+-+Up+To+70%+Off&keyword=dress&pagenumber=1')

System Information

$ python -m requests.help

{
"chardet": {
"version": "4.0.0"
},
"cryptography": {
"version": ""
},
"idna": {
"version": "2.10"
},
"implementation": {
"name": "CPython",
"version": "3.7.2"
},
"platform": {
"release": "5.8.0-40-generic",
"system": "Linux"
},
"pyOpenSSL": {
"openssl_version": "",
"version": null
},
"requests": {
"version": "2.25.1"
},
"system_ssl": {
"version": "1010106f"
},
"urllib3": {
"version": "1.26.3"
},
"using_pyopenssl": false
}

This command is only available on Requests v2.16.4 and greater. Otherwise,

please provide some basic information about your system (Python version,

operating system, &c).

Issue 2:
I'm using requests to download asynchronously and parse the content of a bunch of URLs from different hosts. When the number of URLs is small (up to 1000 URLs) all works fine. When I run the same script with 10000 I get the following error only when there are about 10 URLs left to download:

Traceback (most recent call last):
File "many_async_req.py", line 35, in <module>
File "/home/alex/code/.virtualenvs/testreq/local/lib/python2.7/site-packages/requests-0.11.2-py2.7.egg/requests/async.py", line 83, in map
File "/home/alex/code/.virtualenvs/testreq/local/lib/python2.7/site-packages/gevent/greenlet.py", line 487, in joinall
ImportError: No module named queue

Sometimes the script just hangs with about 10 URLs left. I observed this behavior with requests installed from pipy and with the code downloaded from the development branch.

This happened to me using the version of gevent from pypi and using the latest version downloaded from gevent's Google Code repository.

I'm using a virtualenv with only the relevant modules installed:

(testreq)alex@haiku:~/code$ pip freeze
certifi==0.0.8
chardet==1.0.1
distribute==0.6.19
gevent==0.13.7
greenlet==0.3.4
requests==0.11.2
wsgiref==0.1.2

To reproduce the error I'm using the following script (that is a stripped-down version of the original) that basically just print the status code of each URL.

import codecs
import random
from requests import async
from requests import defaults
import sys

defaults.defaults['base_headers']['User-Agent'] = "Mozilla/5.0 (Windows NT 5.1; rv:11.0) Gecko/20100101 Firefox/11.0"
defaults.defaults['max_retries'] = 5
defaults.defaults['verbose'] = sys.stderr

def check(response):
global counter
print "\t %s HTTP status code: %s" % (counter, response.status_code)
counter += 1

def load_urls(fname):
""" Read URLs from file and remove duplicates """
with codecs.open(fname, 'r', 'utf-8') as fh:
urls = list(set([url.strip() for url in fh.readlines()]))
random.shuffle(urls)
return urls

if __name__ == '__main__':

urls = load_urls('urls.txt')
limit = int(sys.argv[1])
urls = urls[:limit]
rs = []
counter = 0
todo = len(urls)
for url in urls:
rs.append(async.get(url, hooks=dict(response=check), timeout=5.0))
async.map(rs, size=10)
print "To check: %s" % todo
print "To checked: %s" % counter