In [ ]:
from insupportable import Context
c = Context(version=(1,0,0))
if c.deprecated(version=(2,0,0), remove=(3,0,0)):
pass
In [1]:
import warnings; warnings.simplefilter('default')
from insupportable import support
In [2]:
import sys
print(sys.version_info)
In [ ]:
As a developper enable warnings, (or use python -Wd
)
You support both Python 2 and Python 3 ?
In [3]:
from insupportable import support
if support('PY2'):
print("You are on python 2")
else:
print("You are on python 3")
In [4]:
from insupportable import PY2,PY3 # PY2, PY3, for convenience and avoid typos :-)
In [5]:
support.config(PY2=False)
if support(PY3):
print("You are on python 2")
else:
print("You are on python 3")
(I'm writing that in IPython, so stack is wrong here)
works also if I test if(PY3)
!
In [6]:
support.config(PY2=False, PY3=True) # this woudl be in config file
if support(PY3):
print("You are on python 3")
else:
print("You are on python 2")
Say you use to support 3 platforms,
In [7]:
support.config(({'WindowsPhone':True,
'Android':True,
'iOs':False
},))
In [8]:
if support('WindowsPhone'):
print('Click on start menu')
else:
print('Probably Android')
And actually you decide to drop android
In [9]:
support.config(config=({'WindowsPhone':True,
'Android':False,
'iOs':False
},))
In [10]:
support.config(config=({'WindowsPhone':True,
'Android':False,
'iOs':False
},))
if support('WindowsPhone'):
print('Click on start menu')
else:
print("Probably Android - but you don't support it anymore")
In [11]:
if support('WindowsPhone'):
print('Click on start menu')
else:
print("Probably Android - but you don't support it anymore")
Nothing more anoying that having to write the configuration before actually having working code. support
assume by default that you support the feature though it will warn that it does not know it. So you can just set up everything after.
In [12]:
from insupportable import support
if support('PY1'):
# Well, we need some work around for old versions:'
import sys
sys.stdout.write('in python one you had to write to sys !')
It gently warn you that maybe you should tell it wether or not you stil support PY1, which let you write code and decide wether ot not to support later.
In [13]:
import insupportable
In [14]:
insupportable.predicates
Out[14]:
In [15]:
support('PY35+')
Out[15]:
In [16]:
import insupportable
from insupportable import support
In [17]:
def jp():
import sys
return ('jupyter_notebook' in sys.modules)
support.s.add_feature('JUPYTER', jp, supported=True)
In [18]:
support('JUPYTER')
Out[18]:
In [19]:
class Item(object):
def __init__(self, name, predicate=True, support=True):
"""An item in a discret support set.
An item is consituted of
- a name (string)
- a predicate (`Bool | funtion:()->Bool`) to determine if we are typically in this case.
- the support status (bool)
"""
self.name = name
if callabale(predicate):
predicate = predicate()
self.predicate = predicate
self.support = support
In [20]:
support.s.predicates
Out[20]:
In [2]:
import insupportable
In [5]:
def fun(a, *args):
print(args)
In [7]:
fun(1,2,3)
In [5]:
DF
Out[5]:
In [ ]:
In [1]:
from insupportable import DiscreatFeature as DF, FeatureGroup#, FeatureTracker
PY2 = DF('PY2', lambda x: sys.version_info.major == 2)
PY3 = DF('PY3', lambda x: sys.version_info.major == 3)
JPY = DF('JUPYTER', lambda x: True)
IPY = DF('IPYTHON', lambda x: False)
group_py = FeatureGroup(PY2,PY3)
group_jpy = FeatureGroup(JPY,IPY)
In [116]:
vx = lambda: re.compile('^(\S+) ?(\d+)\.(\d+)(\+|-)?$')
class NumeralFeature(object):
def __init__(self ,name, predicate):
self.name = name
self.features = []
if callable(predicate):
self.current_version = predicate()
else :
self.current_version = predicate
In [117]:
import re
In [118]:
import sys
pyv = NumeralFeature('python', lambda :sys.version_info)
In [119]:
print(vx().search('foo2.3').groups())
print(vx().search('foo2.3+').groups())
print(vx().search('tornado 2.3-').groups())
print(vx().search('python 2.7+').groups())
In [153]:
class FeatureTracker(object):
def __init__(self, *args):
self.args = args
self._known_versions = [f.name for g in args for f in g.features if type(f) == DF]
self._known_numerals = [g.name for g in args if type(g) == NumeralFeature]
self._numeral_map = {}
for g in args:
if type(g) == NumeralFeature:
self._numeral_map[g.name] = g.current_version
else:
continue
def support(self, indetifier):
pass
def know(self, identifier):
if identifier in self._known_versions:
return True
elif vx().match(identifier):
feat = vx().search(identifier).groups()
print(tuple(map(int, feat[1:3])) >= self._numeral_map[feat[0]][:2])
return feat[0] in self._known_numerals
ft = FeatureTracker(group_jpy, group_py, pyv)
In [154]:
ft._numeral_map
Out[154]:
In [156]:
ft.know('python 3.5+')
Out[156]:
In [102]:
FeatureTracker
Out[102]:
So, we have a bunch of feature-sets with predicate and support:
like:
Python
- PY2 – sys.version_info.major == 2 – True
- PY3 – sys.version_info.major == 3 – True
Python3.x
- PY33 - sys.version_info.minor >=3 - True
- PY34 - sys.version_info.minor >=4 - True
- PY35 - sys.version_info.minor >=5 - True
- PY36 - sys.version_info.minor >=6 - True
PyQtGui
- PyQt - ? - True
- PySide - ? - False
Features:
- if name not in set: warn unknown feature.
- if last of group: warn last availlable.