Pylinting a python 2 fallback - python

I have a python module with a python 2 fallback set up through try/catch.
try:
from urllib.parse import urlencode
except ImportError:
from urlib import urlencode
When I pylint the file I get no name 'urlencode' in module 'urllib' and similar errors. Is there anyway to specify python 2 linting for a block, disable all linting for a block, or am I stuck hand squelching all errors?

I settled on a nicer way of doing this by disabling the linting errors at the beginning of a python 2 block, and then re enabling them at the end.
# pylint: disable=no-name-in-module, import-error
from urllib import urlencode
from urllib2 import urlopen
# pylint: enable=no-name-in-module, import-error

Related

grequests with requests has collision

I am using grequests python module to call some APIs. I want to make two functions.
A single request(use requests module)
A multiple request(use grequests module)
When I use two modules in two different files, it runs normally, but when I import two modules in the same file, requests module fall in infinity recursive.
#!/usr/bin/env python
#-*- encoding:utf-8 -*-
import requests
import grequests
def SingleRequest():
rs = requests.get("www.example.com")
return rs
def MultiRequest():
urls = [
"www.example1.com",
"www.example2.com",
"www.example3.com"
]
rs = [grequests.get(u) for u in urls]
rs_map = grequests.map(rs);
return rs_map;
If I call MultiRequest() -> do Well!
but if I call SingleRequest() ..... ↓
Exception Type: RecursionError
Exception Value: maximum recursion depth exceeded
Exception Location: /usr/local/lib/python3.6/ssl.py in options, line 459
/usr/local/lib/python3.6/ssl.py in options
super(SSLContext, SSLContext).options.__set__(self, value) X 100 times...
Is it possible to use requests and grequests in one file?
Yes.
Import requests after grequests.
Here is an open issue about this.
This is the only thing that worked for me (Python 3.8.6, a module needed imports of grequests and requests) (source). This should precede all other imports:
from gevent import monkey
def stub(*args, **kwargs): # pylint: disable=unused-argument
pass
monkey.patch_all = stub
import grequests

Get rid of urllib not defined error

Keep getting the same thing every time I try to run the program, urllib is not defined. How do I get rid of it?
from urllib.request import urlopen
from urllib.error import HTTPError
aname = 'http://website.com'
try:
htm = urlopen(aname + '/').read()
except urllib.error.HTTPError as e:
print(e)
Yes, I do have another problem I sure wish I could figure out as well, I can't get bs4 to install correctly, it keep trying to install to Python 2.7, which I don't have any 2.7 interpreter installed, only 3.4.3 is installed on the computer. I have a strange feeling that might be causing me some other issues as well with some some other programs.
Just because you have the line from urllib.error import HTTPError or the from urllib.request import urlopen doesn't mean that urrlib is available as a name in your script.
This is specified in the documentation for the import statement specifically in the section dealing with the from form; see the examples there to see what becomes available and what doesn't.
Therefore, when you except:
except urllib.error.HTTPError as e:
it fails when trying to find the name urrlib. Either just use HTTPError, as imported and bound to your namespace, in the except clause:
except HTTPError as e:
or, if you need the name for urllib available in your namespace, import urllib instead of from urllib.error import HTTPError and use the original except clause.
As for the installation issue, try using pip3 instead of pip.

Mocking no ssl installed

I am trying to test the compatibility wrapper for library against the possibility that Python was compiled without SSL support.
The problem is that this is detected using the following statement.
try:
import ssl
except ImportError:
ssl = None
How would I go about mocking this safely when removing the ssl import, before the compatibility file is even loaded (or reloaded)? Without disrupting all the other tests.
You can assign Mock() to the ssl module:
import sys
sys.modules['ssl'] = Mock()
Before running the code where ssl gets imported.
I was able to achieve the behavior I wanted by first saving the module as a local variable, then setting the ssl module in sys.modules to None and reloading the file we are testing.
Once the test is complete I simply restore the the ssl module in sys.modules and again reload the file I am testing.
# Module we will be testing.
import my_package
def test_ssl_module_not_available(self):
# Save the module we are going to modify.
restore_module = sys.modules['ssl']
try:
# Set ssl import as None.
sys.modules['ssl'] = None
# Reload the code referencing the ssl module.
imp.reload(my_package.compatibility)
# Perform the tests.
self.assertIsNone(compatibility.ssl)
self.assertIsNone(compatibility.DEFAULT_SSL_VERSION)
self.assertFalse(compatibility.SSL_SUPPORTED)
self.assertFalse(compatibility.SSL_CERT_MAP)
self.assertFalse(compatibility.SSL_VERSIONS)
finally:
# Restore the ssl module.
sys.modules['ssl'] = restore_module
imp.reload(compatibility)

Python: Importing urllib.quote

I would like to use urllib.quote(). But python (python3) is not finding the module.
Suppose, I have this line of code:
print(urllib.quote("châteu", safe=''))
How do I import urllib.quote?
import urllib or
import urllib.quote both give
AttributeError: 'module' object has no attribute 'quote'
What confuses me is that urllib.request is accessible via import urllib.request
In Python 3.x, you need to import urllib.parse.quote:
>>> import urllib.parse
>>> urllib.parse.quote("châteu", safe='')
'ch%C3%A2teu'
According to Python 2.x urllib module documentation:
NOTE
The urllib module has been split into parts and renamed in Python 3 to
urllib.request, urllib.parse, and urllib.error.
If you need to handle both Python 2.x and 3.x you can catch the exception and load the alternative.
try:
from urllib import quote # Python 2.X
except ImportError:
from urllib.parse import quote # Python 3+
You could also use the python compatibility wrapper six to handle this.
from six.moves.urllib.parse import quote
urllib went through some changes in Python3 and can now be imported from the parse submodule
>>> from urllib.parse import quote
>>> quote('"')
'%22'
This is how I handle this, without using exceptions.
import sys
if sys.version_info.major > 2: # Python 3 or later
from urllib.parse import quote
else: # Python 2
from urllib import quote
Use six:
from six.moves.urllib.parse import quote
six will simplify compatibility problems between Python 2 and Python 3, such as different import paths.

Importing a module based on installed python version?

My module currently imports the json module, which is only available in 2.6. I'd like to make a check against the python version to import simplejson, which can be built for 2.5 (and is the module adopted in 2.6 anyway). Something like:
if __version__ 2.5:
import simplejson as json
else:
import json
What's the best way to approach this?
try:
import simplejson as json
except ImportError:
import json
of course, it doesn't work around cases when in python-2.5 you don't have simplejson installed, the same as your example.
Though the ImportError approach (SilentGhost's answer) is definitely best for this example, anyone wanting to do that __version__ thing would use something like this:
import sys
if sys.version_info < (2, 6):
import simplejson as json
else:
import json
To be absolutely clear though, this is not the "best way" to do what you wanted... it's merely the correct way to do what you were trying to show with __version__.
You can import one or more modules without Handling ImportError error:
import sys
major_version = sys.version_info.major
if major_version == 2:
import SocketServer
import SimpleHTTPServer
import urllib2
elif major_version == 3:
import http.server as SimpleHTTPServer
import socketserver as SocketServer
import urllib.request as urllib2

Categories

Resources