Skip to content

Commit 6deef72

Browse files
committed
Merge pull request #9487 from jreback/imports
CLN: import packers/gbq/html only on-demand (GH9482)
2 parents 5a0bfad + cbb6fe8 commit 6deef72

File tree

3 files changed

+109
-64
lines changed

3 files changed

+109
-64
lines changed

pandas/io/gbq.py

+57-39
Original file line numberDiff line numberDiff line change
@@ -13,60 +13,74 @@
1313
from pandas.tools.merge import concat
1414
from pandas.core.common import PandasError
1515

16-
16+
_IMPORTS = False
1717
_GOOGLE_API_CLIENT_INSTALLED = False
1818
_GOOGLE_API_CLIENT_VALID_VERSION = False
1919
_GOOGLE_FLAGS_INSTALLED = False
2020
_GOOGLE_FLAGS_VALID_VERSION = False
2121
_HTTPLIB2_INSTALLED = False
2222
_SETUPTOOLS_INSTALLED = False
2323

24-
if not compat.PY3:
24+
def _importers():
25+
# import things we need
26+
# but make this done on a first use basis
2527

26-
try:
27-
import pkg_resources
28-
_SETUPTOOLS_INSTALLED = True
29-
except ImportError:
30-
_SETUPTOOLS_INSTALLED = False
31-
32-
if _SETUPTOOLS_INSTALLED:
33-
try:
34-
from apiclient.discovery import build
35-
from apiclient.http import MediaFileUpload
36-
from apiclient.errors import HttpError
28+
global _IMPORTS
29+
if _IMPORTS:
30+
return
3731

38-
from oauth2client.client import OAuth2WebServerFlow
39-
from oauth2client.client import AccessTokenRefreshError
40-
from oauth2client.client import flow_from_clientsecrets
41-
from oauth2client.file import Storage
42-
from oauth2client.tools import run
43-
_GOOGLE_API_CLIENT_INSTALLED=True
44-
_GOOGLE_API_CLIENT_VERSION = pkg_resources.get_distribution('google-api-python-client').version
32+
_IMPORTS = True
4533

46-
if LooseVersion(_GOOGLE_API_CLIENT_VERSION) >= '1.2.0':
47-
_GOOGLE_API_CLIENT_VALID_VERSION = True
34+
if not compat.PY3:
4835

36+
global _GOOGLE_API_CLIENT_INSTALLED, _GOOGLE_API_CLIENT_VALID_VERSION, \
37+
_GOOGLE_FLAGS_INSTALLED, _GOOGLE_FLAGS_VALID_VERSION, \
38+
_HTTPLIB2_INSTALLED, _SETUPTOOLS_INSTALLED
39+
40+
try:
41+
import pkg_resources
42+
_SETUPTOOLS_INSTALLED = True
4943
except ImportError:
50-
_GOOGLE_API_CLIENT_INSTALLED = False
44+
_SETUPTOOLS_INSTALLED = False
5145

46+
if _SETUPTOOLS_INSTALLED:
47+
try:
48+
from apiclient.discovery import build
49+
from apiclient.http import MediaFileUpload
50+
from apiclient.errors import HttpError
5251

53-
try:
54-
import gflags as flags
55-
_GOOGLE_FLAGS_INSTALLED = True
52+
from oauth2client.client import OAuth2WebServerFlow
53+
from oauth2client.client import AccessTokenRefreshError
54+
from oauth2client.client import flow_from_clientsecrets
55+
from oauth2client.file import Storage
56+
from oauth2client.tools import run
57+
_GOOGLE_API_CLIENT_INSTALLED=True
58+
_GOOGLE_API_CLIENT_VERSION = pkg_resources.get_distribution('google-api-python-client').version
5659

57-
_GOOGLE_FLAGS_VERSION = pkg_resources.get_distribution('python-gflags').version
60+
if LooseVersion(_GOOGLE_API_CLIENT_VERSION) >= '1.2.0':
61+
_GOOGLE_API_CLIENT_VALID_VERSION = True
5862

59-
if LooseVersion(_GOOGLE_FLAGS_VERSION) >= '2.0':
60-
_GOOGLE_FLAGS_VALID_VERSION = True
63+
except ImportError:
64+
_GOOGLE_API_CLIENT_INSTALLED = False
6165

62-
except ImportError:
63-
_GOOGLE_FLAGS_INSTALLED = False
6466

65-
try:
66-
import httplib2
67-
_HTTPLIB2_INSTALLED = True
68-
except ImportError:
69-
_HTTPLIB2_INSTALLED = False
67+
try:
68+
import gflags as flags
69+
_GOOGLE_FLAGS_INSTALLED = True
70+
71+
_GOOGLE_FLAGS_VERSION = pkg_resources.get_distribution('python-gflags').version
72+
73+
if LooseVersion(_GOOGLE_FLAGS_VERSION) >= '2.0':
74+
_GOOGLE_FLAGS_VALID_VERSION = True
75+
76+
except ImportError:
77+
_GOOGLE_FLAGS_INSTALLED = False
78+
79+
try:
80+
import httplib2
81+
_HTTPLIB2_INSTALLED = True
82+
except ImportError:
83+
_HTTPLIB2_INSTALLED = False
7084

7185

7286
logger = logging.getLogger('pandas.io.gbq')
@@ -118,8 +132,10 @@ class InvalidColumnOrder(PandasError, IOError):
118132
"""
119133
pass
120134

121-
class GbqConnector:
135+
class GbqConnector(object):
136+
122137
def __init__(self, project_id, reauth=False):
138+
123139
self.project_id = project_id
124140
self.reauth = reauth
125141
self.credentials = self.get_credentials()
@@ -298,6 +314,8 @@ def _parse_entry(field_value, field_type):
298314
return field_value
299315

300316
def _test_imports():
317+
318+
_importers()
301319
_GOOGLE_API_CLIENT_INSTALLED
302320
_GOOGLE_API_CLIENT_VALID_VERSION
303321
_GOOGLE_FLAGS_INSTALLED
@@ -410,8 +428,8 @@ def to_gbq(dataframe, destination_table, project_id=None, chunksize=10000,
410428
the defined table schema and column types. For simplicity, this method
411429
uses the Google BigQuery streaming API. The to_gbq method chunks data
412430
into a default chunk size of 10,000. Failures return the complete error
413-
response which can be quite long depending on the size of the insert.
414-
There are several important limitations of the Google streaming API
431+
response which can be quite long depending on the size of the insert.
432+
There are several important limitations of the Google streaming API
415433
which are detailed at:
416434
https://developers.google.com/bigquery/streaming-data-into-bigquery.
417435

pandas/io/html.py

+31-18
Original file line numberDiff line numberDiff line change
@@ -20,29 +20,40 @@
2020
from pandas.core import common as com
2121
from pandas import Series
2222

23+
_IMPORTS = False
24+
_HAS_BS4 = False
25+
_HAS_LXML = False
26+
_HAS_HTML5LIB = False
2327

24-
try:
25-
import bs4
26-
except ImportError:
27-
_HAS_BS4 = False
28-
else:
29-
_HAS_BS4 = True
28+
def _importers():
29+
# import things we need
30+
# but make this done on a first use basis
3031

32+
global _IMPORTS
33+
if _IMPORTS:
34+
return
3135

32-
try:
33-
import lxml
34-
except ImportError:
35-
_HAS_LXML = False
36-
else:
37-
_HAS_LXML = True
36+
_IMPORTS = True
3837

38+
global _HAS_BS4, _HAS_LXML, _HAS_HTML5LIB
3939

40-
try:
41-
import html5lib
42-
except ImportError:
43-
_HAS_HTML5LIB = False
44-
else:
45-
_HAS_HTML5LIB = True
40+
try:
41+
import bs4
42+
_HAS_BS4 = True
43+
except ImportError:
44+
pass
45+
46+
try:
47+
import lxml
48+
_HAS_LXML = True
49+
except ImportError:
50+
pass
51+
52+
try:
53+
import html5lib
54+
_HAS_HTML5LIB = True
55+
except ImportError:
56+
pass
4657

4758

4859
#############
@@ -651,6 +662,7 @@ def _parser_dispatch(flavor):
651662
raise ImportError("html5lib not found, please install it")
652663
if not _HAS_BS4:
653664
raise ImportError("BeautifulSoup4 (bs4) not found, please install it")
665+
import bs4
654666
if bs4.__version__ == LooseVersion('4.2.0'):
655667
raise ValueError("You're using a version"
656668
" of BeautifulSoup4 (4.2.0) that has been"
@@ -839,6 +851,7 @@ def read_html(io, match='.+', flavor=None, header=None, index_col=None,
839851
--------
840852
pandas.read_csv
841853
"""
854+
_importers()
842855
if infer_types is not None:
843856
warnings.warn("infer_types has no effect since 0.15", FutureWarning)
844857

pandas/io/packers.py

+21-7
Original file line numberDiff line numberDiff line change
@@ -61,18 +61,30 @@
6161
import pandas.core.internals as internals
6262

6363
from pandas.msgpack import Unpacker as _Unpacker, Packer as _Packer
64-
import zlib
65-
66-
try:
67-
import blosc
68-
_BLOSC = True
69-
except:
70-
_BLOSC = False
7164

7265
# until we can pass this into our conversion functions,
7366
# this is pretty hacky
7467
compressor = None
68+
_IMPORTS = False
69+
_BLOSC = False
70+
71+
def _importers():
72+
# import things we need
73+
# but make this done on a first use basis
74+
75+
global _IMPORTS
76+
if _IMPORTS:
77+
return
78+
79+
_IMPORTS = True
7580

81+
global _BLOSC
82+
import zlib
83+
try:
84+
import blosc
85+
_BLOSC = True
86+
except:
87+
pass
7688

7789
def to_msgpack(path_or_buf, *args, **kwargs):
7890
"""
@@ -91,6 +103,7 @@ def to_msgpack(path_or_buf, *args, **kwargs):
91103
compress : type of compressor (zlib or blosc), default to None (no
92104
compression)
93105
"""
106+
_importers()
94107
global compressor
95108
compressor = kwargs.pop('compress', None)
96109
append = kwargs.pop('append', None)
@@ -133,6 +146,7 @@ def read_msgpack(path_or_buf, iterator=False, **kwargs):
133146
obj : type of object stored in file
134147
135148
"""
149+
_importers()
136150
path_or_buf, _ = get_filepath_or_buffer(path_or_buf)
137151
if iterator:
138152
return Iterator(path_or_buf)

0 commit comments

Comments
 (0)