Repository: dixudx/rtcclient

Issue:
why long attributes are skipped ?
Hi,
I was trying to get as many attributes from work item as I can, and I was stucked [here](https://github.com/dixudx/rtcclient/blob/266768d35808af5cc4fdaa7c8855842e3e227331/rtcclient/base.py#L310-L313), is there a reason to have this check to skip "long attributes" ?

I've removed that block of code, on 0.6.0 version, and finally I can get all the workitem's attributes (some of them are still links to be parsed).

Let me know, thanks.


Discussion:
gpongelli: I see merge conflict, I’ll resolve them after a rebase.

Patch:
diff --git a/rtcclient/base.py b/rtcclient/base.py
index ea6453d..2c79e5f 100644
--- a/rtcclient/base.py
+++ b/rtcclient/base.py
@@ -17,12 +17,17 @@ class RTCBase(object):
     OSLC_CR_XML = "application/x-oslc-cm-change-request+xml"
     OSLC_CR_JSON = "application/x-oslc-cm-change-request+json"
 
-    def __init__(self, url):
+    def __init__(self, url, skip_full_attributes=True, **kwargs):
         self.url = self.validate_url(url)
+        self.__skip_full_attributes = skip_full_attributes
 
     def __repr__(self):
         return "<%s %s>" % (self.__class__.__name__, str(self))
 
+    @property
+    def skip_full_attributes(self):
+        return self.__skip_full_attributes
+
     @abc.abstractmethod
     def __str__(self):
         pass
@@ -244,8 +249,8 @@ class FieldBase(RTCBase):
     __metaclass__ = abc.ABCMeta
     log = logging.getLogger("base.FieldBase")
 
-    def __init__(self, url, rtc_obj, raw_data=None):
-        RTCBase.__init__(self, url)
+    def __init__(self, url, rtc_obj, raw_data=None, **kwargs):
+        RTCBase.__init__(self, url, **kwargs)
         self.field_alias = dict()
         self.rtc_obj = rtc_obj
         self.raw_data = raw_data
@@ -306,8 +311,8 @@ class FieldBase(RTCBase):
         attr = key.split(":")[-1].replace("-", "_")
         attr_list = attr.split(".")
 
-        # ignore long attributes
-        if len(attr_list) > 1:
+        # user want to ignore long attributes
+        if self.skip_full_attributes and len(attr_list) > 1:
             # attr = "_".join([attr_list[-2],
             #                  attr_list[-1]])
             return None
diff --git a/rtcclient/client.py b/rtcclient/client.py
index 5d2be51..ac7cb58 100644
--- a/rtcclient/client.py
+++ b/rtcclient/client.py
@@ -59,7 +59,8 @@ class RTCClient(RTCBase):
                  searchpath=None,
                  ends_with_jazz=True,
                  verify: Union[bool, str] = False,
-                 old_rtc_authentication=False):
+                 old_rtc_authentication=False,
+                 **kwargs):
         """Initialization
 
         See params above
@@ -70,7 +71,7 @@ class RTCClient(RTCBase):
         self.proxies = proxies
         self.verify = verify
         self.old_rtc_authentication = old_rtc_authentication
-        RTCBase.__init__(self, url)
+        RTCBase.__init__(self, url, **kwargs)
 
         if not isinstance(ends_with_jazz, bool):
             raise exception.BadValue("ends_with_jazz is not boolean")
@@ -980,13 +981,17 @@ class RTCClient(RTCBase):
 
         return self.templater.listFieldsFromWorkitem(copied_from, keep=keep)
 
-    def getWorkitem(self, workitem_id, returned_properties=None):
+    def getWorkitem(self,
+                    workitem_id,
+                    returned_properties=None,
+                    skip_full_attributes=True):
         """Get :class:`rtcclient.workitem.Workitem` object by its id/number
 
         :param workitem_id: the workitem id/number
             (integer or equivalent string)
         :param returned_properties: the returned properties that you want.
             Refer to :class:`rtcclient.client.RTCClient` for more explanations
+        :param skip_full_attributes: flag to retrieve all attributes.
         :return: the :class:`rtcclient.workitem.Workitem` object
         :rtype: rtcclient.workitem.Workitem
         """
@@ -1019,7 +1024,8 @@ class RTCClient(RTCBase):
             return Workitem(workitem_url,
                             self,
                             workitem_id=workitem_id,
-                            raw_data=workitem_raw)
+                            raw_data=workitem_raw,
+                            skip_full_attributes=skip_full_attributes)
 
         except ValueError:
             excp_msg = "Please input a valid workitem id"
diff --git a/rtcclient/workitem.py b/rtcclient/workitem.py
index 7507774..e3684ec 100644
--- a/rtcclient/workitem.py
+++ b/rtcclient/workitem.py
@@ -27,9 +27,9 @@ class Workitem(FieldBase):
 
     OSLC_CR_RDF = "application/rdf+xml"
 
-    def __init__(self, url, rtc_obj, workitem_id=None, raw_data=None):
+    def __init__(self, url, rtc_obj, workitem_id=None, raw_data=None, **kwargs):
         self.identifier = workitem_id
-        FieldBase.__init__(self, url, rtc_obj, raw_data)
+        FieldBase.__init__(self, url, rtc_obj, raw_data, **kwargs)
         if self.identifier is None:
             self.identifier = self.url.split("/")[-1]
 


Test patch:
diff --git a/tests/test_client.py b/tests/test_client.py
index 49e7fd5..6d93c8c 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -1626,6 +1626,73 @@ class TestRTCClient:
                               raw_data=utils_test.workitem1)
         assert workitem1 == workitem11
 
+    @pytest.mark.parametrize('item,expected', [
+        ('com.ibm.workitem.attribute.custom.completeperc', "0"),
+        ("com.ibm.team.workitem.linktype.parentworkitem.parent",
+         "input title here for 161"),
+        ("com.ibm.team.workitem.linktype.attachment.attachment",
+         "input title here for 161"),
+        ("com.ibm.team.workitem.linktype.resolvesworkitem.resolves",
+         "input title here for 161"),
+        ('com.ibm.team.workitem.linktype.relatedworkitem.related',
+         "input title here for 161"),
+        ('com.ibm.team.workitem.linktype.resolvesworkitem.resolves',
+         "input title here for 161"),
+        ("com.ibm.team.enterprise.promotion.linktype.promotionBuildResult.promotionBuildResult",
+         "input title here for 161"),
+        ("com.ibm.team.enterprise.deployment.linktype.deploymentDefinition.packageDefinition",
+         "input title here for 161"),
+        ("com.ibm.team.enterprise.deployment.linktype.deploymentBuildResult.packageBuildResult",
+         "input title here for 161"),
+        ("com.ibm.team.enterprise.promotion.linktype.resultWorkItem.promoted",
+         "input title here for 161"),
+        ("com.ibm.team.workitem.linktype.schedulePredecessor.predecessor",
+         "input title here for 161"),
+        ("com.ibm.team.build.linktype.includedPackages.com.ibm.team.build.common.link.includedInPackages",
+         "input title here for 161"),
+        ("com.ibm.team.enterprise.promotion.linktype.gapChangeSets.gapChangeSets",
+         "input title here for 161"),
+        ("com.ibm.team.workitem.linktype.resolvesworkitem.resolvedBy",
+         "input title here for 161"),
+        ("com.ibm.team.workitem.linktype.duplicateworkitem.duplicates",
+         "input title here for 161"),
+        ("com.ibm.team.workitem.linktype.parentworkitem.children",
+         "input title here for 161"),
+        ("com.ibm.team.enterprise.promotion.linktype.promotedBuildMaps.promotedBuildMaps",
+         "input title here for 161"),
+        ("com.ibm.team.workitem.linktype.schedulePredecessor.successor",
+         "input title here for 161"),
+        ("com.ibm.team.filesystem.workitems.change_set.com.ibm.team.scm.ChangeSet",
+         "input title here for 161"),
+        ("com.ibm.team.workitem.linktype.blocksworkitem.dependsOn",
+         "input title here for 161"),
+        ("com.ibm.team.enterprise.promotion.linktype.resultWorkItem.result",
+         "input title here for 161"),
+        ("com.ibm.team.workitem.linktype.relatedartifact.relatedArtifact",
+         "input title here for 161"),
+        ("com.ibm.workitem.attribute.custom.odc.deftype", None),
+        ("com.ibm.workitem.attribute.custom.odc.history", None),
+        ("com.ibm.workitem.attribute.custom.odc.qualifier", None),
+        ("com.ibm.workitem.attribute.custom.odc.trigger", None),
+        ("com.ibm.workitem.attribute.custome.isvalid", None)
+    ])
+    def test_get_workitem_full_attributes(self, mocker, myrtcclient, item,
+                                          expected):
+        mocked_get = mocker.patch("requests.get")
+        mock_resp = mocker.MagicMock(spec=requests.Response)
+        mock_resp.status_code = 200
+        mock_resp.content = utils_test.workitem1_raw
+        mocked_get.return_value = mock_resp
+
+        # Workitem1
+        workitem1 = Workitem("http://test.url:9443/jazz/oslc/workitems/161",
+                             myrtcclient,
+                             workitem_id=161,
+                             raw_data=utils_test.workitem1,
+                             skip_full_attributes=False)
+        assert workitem1.identifier == "161"
+        assert workitem1[item] == expected
+
     @pytest.fixture
     def mock_get_workitems(self, mocker):
         mocked_get = mocker.patch("requests.get")