Skip to content

Commit c4b477a

Browse files
jbrockmendelvictor
authored and
victor
committed
[CLN] resolve circular Period dependency, prepare setup.py (pandas-dev#21854)
1 parent 119208f commit c4b477a

File tree

5 files changed

+52
-58
lines changed

5 files changed

+52
-58
lines changed

pandas/_libs/__init__.py

+2-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
# -*- coding: utf-8 -*-
22
# flake8: noqa
33

4-
from .tslibs import iNaT, NaT, Timestamp, Timedelta, OutOfBoundsDatetime
5-
6-
# TODO
7-
# period is directly dependent on tslib and imports python
8-
# modules, so exposing Period as an alias is currently not possible
9-
# from period import Period
4+
from .tslibs import (
5+
iNaT, NaT, Timestamp, Timedelta, OutOfBoundsDatetime, Period)

pandas/_libs/tslibs/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@
44
from .conversion import normalize_date, localize_pydatetime, tz_convert_single
55
from .nattype import NaT, iNaT
66
from .np_datetime import OutOfBoundsDatetime
7+
from .period import Period, IncompatibleFrequency
78
from .timestamps import Timestamp
89
from .timedeltas import delta_to_nanoseconds, ints_to_pytimedelta, Timedelta

pandas/_libs/tslibs/resolution.pyx

+8-2
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@ from timestamps import Timestamp
2828

2929
from pandas._libs.properties import cache_readonly
3030

31-
from pandas.core.algorithms import unique # TODO: Avoid this non-cython import
32-
3331
# ----------------------------------------------------------------------
3432
# Constants
3533

@@ -574,6 +572,10 @@ cdef class _FrequencyInferer(object):
574572
if len(self.ydiffs) > 1:
575573
return None
576574

575+
# lazy import to prevent circularity
576+
# TODO: Avoid non-cython dependency
577+
from pandas.core.algorithms import unique
578+
577579
if len(unique(self.fields['M'])) > 1:
578580
return None
579581

@@ -618,6 +620,10 @@ cdef class _FrequencyInferer(object):
618620
# if not lib.ismember(wdiffs, set([4, 5, -47, -49, -48])).all():
619621
# return None
620622

623+
# lazy import to prevent circularity
624+
# TODO: Avoid non-cython dependency
625+
from pandas.core.algorithms import unique
626+
621627
weekdays = unique(self.index.weekday)
622628
if len(weekdays) > 1:
623629
return None

pandas/tests/tslibs/test_api.py

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ def test_namespace():
2424
api = ['NaT',
2525
'iNaT',
2626
'OutOfBoundsDatetime',
27+
'Period',
28+
'IncompatibleFrequency',
2729
'Timedelta',
2830
'Timestamp',
2931
'delta_to_nanoseconds',

setup.py

+39-50
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,6 @@ def is_platform_windows():
2424
return sys.platform == 'win32' or sys.platform == 'cygwin'
2525

2626

27-
def is_platform_linux():
28-
return sys.platform == 'linux2'
29-
30-
31-
def is_platform_mac():
32-
return sys.platform == 'darwin'
33-
34-
35-
min_cython_ver = '0.28.2'
36-
try:
37-
import Cython
38-
ver = Cython.__version__
39-
_CYTHON_INSTALLED = ver >= LooseVersion(min_cython_ver)
40-
except ImportError:
41-
_CYTHON_INSTALLED = False
42-
43-
4427
min_numpy_ver = '1.9.0'
4528
setuptools_kwargs = {
4629
'install_requires': [
@@ -53,24 +36,29 @@ def is_platform_mac():
5336
}
5437

5538

39+
min_cython_ver = '0.28.2'
40+
try:
41+
import Cython
42+
ver = Cython.__version__
43+
_CYTHON_INSTALLED = ver >= LooseVersion(min_cython_ver)
44+
except ImportError:
45+
_CYTHON_INSTALLED = False
46+
47+
# The import of Extension must be after the import of Cython, otherwise
48+
# we do not get the appropriately patched class.
49+
# See https://cython.readthedocs.io/en/latest/src/reference/compilation.html
5650
from distutils.extension import Extension # noqa:E402
5751
from distutils.command.build import build # noqa:E402
58-
from distutils.command.build_ext import build_ext as _build_ext # noqa:E402
5952

6053
try:
6154
if not _CYTHON_INSTALLED:
6255
raise ImportError('No supported version of Cython installed.')
63-
try:
64-
from Cython.Distutils.old_build_ext import old_build_ext as _build_ext # noqa:F811,E501
65-
except ImportError:
66-
# Pre 0.25
67-
from Cython.Distutils import build_ext as _build_ext
56+
from Cython.Distutils.old_build_ext import old_build_ext as _build_ext
6857
cython = True
6958
except ImportError:
59+
from distutils.command.build_ext import build_ext as _build_ext
7060
cython = False
71-
72-
73-
if cython:
61+
else:
7462
try:
7563
try:
7664
from Cython import Tempita as tempita
@@ -103,27 +91,30 @@ def is_platform_mac():
10391

10492

10593
class build_ext(_build_ext):
106-
def build_extensions(self):
94+
@classmethod
95+
def render_templates(cls, pxifiles):
96+
for pxifile in pxifiles:
97+
# build pxifiles first, template extension must be .pxi.in
98+
assert pxifile.endswith('.pxi.in')
99+
outfile = pxifile[:-3]
107100

108-
# if builing from c files, don't need to
109-
# generate template output
110-
if cython:
111-
for pxifile in _pxifiles:
112-
# build pxifiles first, template extension must be .pxi.in
113-
assert pxifile.endswith('.pxi.in')
114-
outfile = pxifile[:-3]
115-
116-
if (os.path.exists(outfile) and
117-
os.stat(pxifile).st_mtime < os.stat(outfile).st_mtime):
118-
# if .pxi.in is not updated, no need to output .pxi
119-
continue
101+
if (os.path.exists(outfile) and
102+
os.stat(pxifile).st_mtime < os.stat(outfile).st_mtime):
103+
# if .pxi.in is not updated, no need to output .pxi
104+
continue
120105

121-
with open(pxifile, "r") as f:
122-
tmpl = f.read()
123-
pyxcontent = tempita.sub(tmpl)
106+
with open(pxifile, "r") as f:
107+
tmpl = f.read()
108+
pyxcontent = tempita.sub(tmpl)
124109

125-
with open(outfile, "w") as f:
126-
f.write(pyxcontent)
110+
with open(outfile, "w") as f:
111+
f.write(pyxcontent)
112+
113+
def build_extensions(self):
114+
# if building from c files, don't need to
115+
# generate template output
116+
if cython:
117+
self.render_templates(_pxifiles)
127118

128119
numpy_incl = pkg_resources.resource_filename('numpy', 'core/include')
129120

@@ -360,7 +351,6 @@ def run(self):
360351
class CheckingBuildExt(build_ext):
361352
"""
362353
Subclass build_ext to get clearer report if Cython is necessary.
363-
364354
"""
365355

366356
def check_cython_extensions(self, extensions):
@@ -379,9 +369,11 @@ def build_extensions(self):
379369

380370

381371
class CythonCommand(build_ext):
382-
"""Custom distutils command subclassed from Cython.Distutils.build_ext
372+
"""
373+
Custom distutils command subclassed from Cython.Distutils.build_ext
383374
to compile pyx->c, and stop there. All this does is override the
384-
C-compile method build_extension() with a no-op."""
375+
C-compile method build_extension() with a no-op.
376+
"""
385377
def build_extension(self, ext):
386378
pass
387379

@@ -445,7 +437,6 @@ def srcpath(name=None, suffix='.pyx', subdir='src'):
445437
lib_depends.append('pandas/_libs/src/util.pxd')
446438
else:
447439
lib_depends = []
448-
plib_depends = []
449440

450441
common_include = ['pandas/_libs/src/klib', 'pandas/_libs/src']
451442

@@ -471,8 +462,6 @@ def pxd(name):
471462

472463
tseries_depends = np_datetime_headers + ['pandas/_libs/tslibs/np_datetime.pxd']
473464

474-
# some linux distros require it
475-
libraries = ['m'] if not is_platform_windows() else []
476465

477466
ext_data = {
478467
'_libs.algos': {

0 commit comments

Comments
 (0)