From 5a3c843eb0365d257bcbdf63688c78231a23d764 Mon Sep 17 00:00:00 2001 From: Bryan Malyn Date: Mon, 1 Feb 2021 23:03:38 -0600 Subject: [PATCH] Pick up the docstrings of hybrid properties Use the docstring of hybrid properties as the description. Bumped build requirments for sqlalchemy becase as noted in the documentation before version 1.3.19 the ordering for all_orm_descriptors was not deterministic: ``` .. versionchanged:: 1.3.19 ensured deterministic ordering for :meth:`_orm.Mapper.all_orm_descriptors`. ``` Updated .travis.yml to match tox.ini and setup.py --- .travis.yml | 8 -------- graphene_sqlalchemy/converter.py | 3 +++ graphene_sqlalchemy/tests/models.py | 5 +++++ graphene_sqlalchemy/tests/test_types.py | 17 ++++++++++++++++- setup.py | 4 ++-- tox.ini | 6 ++---- 6 files changed, 28 insertions(+), 15 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5a988428..1d241862 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,14 +14,6 @@ matrix: - env: TOXENV=py37 python: 3.7 dist: xenial - # SQLAlchemy 1.1 - - env: TOXENV=py37-sql11 - python: 3.7 - dist: xenial - # SQLAlchemy 1.2 - - env: TOXENV=py37-sql12 - python: 3.7 - dist: xenial # SQLAlchemy 1.3 - env: TOXENV=py37-sql13 python: 3.7 diff --git a/graphene_sqlalchemy/converter.py b/graphene_sqlalchemy/converter.py index f4b805e2..4997d9ab 100644 --- a/graphene_sqlalchemy/converter.py +++ b/graphene_sqlalchemy/converter.py @@ -114,6 +114,9 @@ def convert_sqlalchemy_hybrid_method(hybrid_prop, resolver, **field_kwargs): # TODO The default type should be dependent on the type of the property propety. field_kwargs['type'] = String + if 'description' not in field_kwargs: + field_kwargs['description'] = getattr(hybrid_prop, "__doc__", None) + return Field( resolver=resolver, **field_kwargs diff --git a/graphene_sqlalchemy/tests/models.py b/graphene_sqlalchemy/tests/models.py index 88e992b9..93cafbe5 100644 --- a/graphene_sqlalchemy/tests/models.py +++ b/graphene_sqlalchemy/tests/models.py @@ -65,6 +65,11 @@ class Reporter(Base): articles = relationship("Article", backref="reporter") favorite_article = relationship("Article", uselist=False) + @hybrid_property + def hybrid_prop_with_doc(self): + """Docstring test""" + return self.first_name + @hybrid_property def hybrid_prop(self): return self.first_name diff --git a/graphene_sqlalchemy/tests/test_types.py b/graphene_sqlalchemy/tests/test_types.py index bf563b6e..df444d36 100644 --- a/graphene_sqlalchemy/tests/test_types.py +++ b/graphene_sqlalchemy/tests/test_types.py @@ -82,6 +82,7 @@ class Meta: # Composite "composite_prop", # Hybrid + "hybrid_prop_with_doc", "hybrid_prop", # Relationship "pets", @@ -112,6 +113,12 @@ class Meta: # "doc" is ignored by hybrid_property assert hybrid_prop.description is None + # hybrid_prop_with_doc + hybrid_prop_with_doc = ReporterType._meta.fields['hybrid_prop_with_doc'] + assert hybrid_prop_with_doc.type == String + # docstring is picked up from hybrid_prop_with_doc + assert hybrid_prop_with_doc.description == "Docstring test" + # relationship favorite_article_field = ReporterType._meta.fields['favorite_article'] assert isinstance(favorite_article_field, Dynamic) @@ -145,6 +152,7 @@ class Meta: composite_prop = ORMField() # hybrid_property + hybrid_prop_with_doc = ORMField(description='Overridden') hybrid_prop = ORMField(description='Overridden') # relationships @@ -172,6 +180,7 @@ class Meta: "email_v2", "column_prop", "composite_prop", + "hybrid_prop_with_doc", "hybrid_prop", "favorite_article", "articles", @@ -207,6 +216,11 @@ class Meta: assert hybrid_prop_field.description == "Overridden" assert hybrid_prop_field.deprecation_reason is None + hybrid_prop_with_doc_field = ReporterType._meta.fields['hybrid_prop_with_doc'] + assert hybrid_prop_with_doc_field.type == String + assert hybrid_prop_with_doc_field.description == "Overridden" + assert hybrid_prop_with_doc_field.deprecation_reason is None + column_prop_field_v2 = ReporterType._meta.fields['column_prop'] assert column_prop_field_v2.type == String assert column_prop_field_v2.description is None @@ -275,6 +289,7 @@ class Meta: "email", "favorite_pet_kind", "composite_prop", + "hybrid_prop_with_doc", "hybrid_prop", "pets", "articles", @@ -384,7 +399,7 @@ class Meta: assert issubclass(CustomReporterType, ObjectType) assert CustomReporterType._meta.model == Reporter - assert len(CustomReporterType._meta.fields) == 11 + assert len(CustomReporterType._meta.fields) == 12 # Test Custom SQLAlchemyObjectType with Custom Options diff --git a/setup.py b/setup.py index 7b350c39..ba8652ff 100644 --- a/setup.py +++ b/setup.py @@ -15,8 +15,8 @@ # To keep things simple, we only support newer versions of Graphene "graphene>=2.1.3,<3", "promise>=2.3", - # Tests fail with 1.0.19 - "SQLAlchemy>=1.2,<2", + # Tests fail with 1.3.18 + "SQLAlchemy>=1.3.19,<2", "six>=1.10.0,<2", "singledispatch>=3.4.0.3,<4", ] diff --git a/tox.ini b/tox.ini index 562da2dc..ec8249b9 100644 --- a/tox.ini +++ b/tox.ini @@ -1,14 +1,12 @@ [tox] -envlist = pre-commit,py{27,35,36,37}-sql{11,12,13} +envlist = pre-commit,py{27,35,36,37}-sql13 skipsdist = true minversion = 3.7.0 [testenv] deps = .[test] - sql11: sqlalchemy>=1.1,<1.2 - sql12: sqlalchemy>=1.2,<1.3 - sql13: sqlalchemy>=1.3,<1.4 + sql13: sqlalchemy>=1.3.19,<1.4 commands = pytest graphene_sqlalchemy --cov=graphene_sqlalchemy {posargs}