diff --git a/graphene/__init__.py b/graphene/__init__.py index 79504a10..f376994b 100644 --- a/graphene/__init__.py +++ b/graphene/__init__.py @@ -1,49 +1,67 @@ -from .types import ( - AbstractType, - ObjectType, - InputObjectType, - Interface, - Field, - InputField, - Schema, - Scalar, - String, ID, Int, Float, Boolean, - List, NonNull, - Enum, - Argument, - Dynamic -) -from .relay import ( - Node, - is_node, - ClientIDMutation, - Connection, - ConnectionField -) -from .utils.resolve_only_args import resolve_only_args +from .pyutils.version import get_version -__all__ = [ - 'AbstractType', - 'ObjectType', - 'InputObjectType', - 'Interface', - 'Field', - 'InputField', - 'Schema', - 'Scalar', - 'String', - 'ID', - 'Int', - 'Float', - 'Enum', - 'Boolean', - 'List', - 'NonNull', - 'Argument', - 'Dynamic', - 'resolve_only_args', - 'Node', - 'is_node', - 'ClientIDMutation', - 'Connection', - 'ConnectionField'] + +try: + # This variable is injected in the __builtins__ by the build + # process. It used to enable importing subpackages when + # the required packages are not installed + __SETUP__ +except NameError: + __SETUP__ = False + + +VERSION = (1, 0, 0, 'alpha', 0) + +__version__ = get_version(VERSION) + +if not __SETUP__: + + from .types import ( + AbstractType, + ObjectType, + InputObjectType, + Interface, + Field, + InputField, + Schema, + Scalar, + String, ID, Int, Float, Boolean, + List, NonNull, + Enum, + Argument, + Dynamic + ) + from .relay import ( + Node, + is_node, + ClientIDMutation, + Connection, + ConnectionField + ) + from .utils.resolve_only_args import resolve_only_args + + __all__ = [ + 'AbstractType', + 'ObjectType', + 'InputObjectType', + 'Interface', + 'Field', + 'InputField', + 'Schema', + 'Scalar', + 'String', + 'ID', + 'Int', + 'Float', + 'Enum', + 'Boolean', + 'List', + 'NonNull', + 'Argument', + 'Dynamic', + 'resolve_only_args', + 'Node', + 'is_node', + 'ClientIDMutation', + 'Connection', + 'ConnectionField'] diff --git a/graphene/pyutils/__init__.py b/graphene/pyutils/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/graphene/pyutils/version.py b/graphene/pyutils/version.py new file mode 100644 index 00000000..643149c7 --- /dev/null +++ b/graphene/pyutils/version.py @@ -0,0 +1,77 @@ +from __future__ import unicode_literals + +import datetime +import os +import subprocess + + +def get_version(version=None): + "Returns a PEP 440-compliant version number from VERSION." + version = get_complete_version(version) + + # Now build the two parts of the version number: + # main = X.Y[.Z] + # sub = .devN - for pre-alpha releases + # | {a|b|rc}N - for alpha, beta, and rc releases + + main = get_main_version(version) + + sub = '' + if version[3] == 'alpha' and version[4] == 0: + git_changeset = get_git_changeset() + if git_changeset: + sub = '.dev%s' % git_changeset + + elif version[3] != 'final': + mapping = {'alpha': 'a', 'beta': 'b', 'rc': 'rc'} + sub = mapping[version[3]] + str(version[4]) + + return str(main + sub) + + +def get_main_version(version=None): + "Returns main version (X.Y[.Z]) from VERSION." + version = get_complete_version(version) + parts = 2 if version[2] == 0 else 3 + return '.'.join(str(x) for x in version[:parts]) + + +def get_complete_version(version=None): + """Returns a tuple of the graphene version. If version argument is non-empty, + then checks for correctness of the tuple provided. + """ + if version is None: + from graphene import VERSION as version + else: + assert len(version) == 5 + assert version[3] in ('alpha', 'beta', 'rc', 'final') + + return version + + +def get_docs_version(version=None): + version = get_complete_version(version) + if version[3] != 'final': + return 'dev' + else: + return '%d.%d' % version[:2] + + +def get_git_changeset(): + """Returns a numeric identifier of the latest git changeset. + The result is the UTC timestamp of the changeset in YYYYMMDDHHMMSS format. + This value isn't guaranteed to be unique, but collisions are very unlikely, + so it's sufficient for generating the development version numbers. + """ + repo_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + git_log = subprocess.Popen( + 'git log --pretty=format:%ct --quiet -1 HEAD', + stdout=subprocess.PIPE, stderr=subprocess.PIPE, + shell=True, cwd=repo_dir, universal_newlines=True, + ) + timestamp = git_log.communicate()[0] + try: + timestamp = datetime.datetime.utcfromtimestamp(int(timestamp)) + except ValueError: + return None + return timestamp.strftime('%Y%m%d%H%M%S') diff --git a/setup.py b/setup.py index 649ff575..8cd04b5c 100644 --- a/setup.py +++ b/setup.py @@ -3,6 +3,21 @@ import sys from setuptools import find_packages, setup from setuptools.command.test import test as TestCommand +if sys.version_info[0] < 3: + import __builtin__ as builtins +else: + import builtins + +# This is a bit (!) hackish: we are setting a global variable so that the main +# graphql __init__ can detect if it is being loaded by the setup routine, to +# avoid attempting to load components that aren't built yet: +# the numpy distutils extensions that are used by scikit-learn to recursively +# build the compiled extensions in sub-packages is based on the Python import +# machinery. +builtins.__SETUP__ = True + +version = __import__('graphene').get_version() + class PyTest(TestCommand): user_options = [('pytest-args=', 'a', "Arguments to pass to py.test")] @@ -24,7 +39,7 @@ class PyTest(TestCommand): setup( name='graphene', - version='1.0.0', + version=version, description='GraphQL Framework for Python', long_description=open('README.rst').read(),