cli2 3.3.36__tar.gz → 3.3.40__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. {cli2-3.3.36/cli2.egg-info → cli2-3.3.40}/PKG-INFO +13 -2
  2. {cli2-3.3.36 → cli2-3.3.40}/cli2/client.py +29 -89
  3. {cli2-3.3.36 → cli2-3.3.40}/cli2/test_client.py +69 -48
  4. {cli2-3.3.36 → cli2-3.3.40/cli2.egg-info}/PKG-INFO +13 -2
  5. {cli2-3.3.36 → cli2-3.3.40}/setup.py +1 -1
  6. {cli2-3.3.36 → cli2-3.3.40}/MANIFEST.in +0 -0
  7. {cli2-3.3.36 → cli2-3.3.40}/README.rst +0 -0
  8. {cli2-3.3.36 → cli2-3.3.40}/classifiers.txt +0 -0
  9. {cli2-3.3.36 → cli2-3.3.40}/cli2/__init__.py +0 -0
  10. {cli2-3.3.36 → cli2-3.3.40}/cli2/argument.py +0 -0
  11. {cli2-3.3.36 → cli2-3.3.40}/cli2/asyncio.py +0 -0
  12. {cli2-3.3.36 → cli2-3.3.40}/cli2/cli.py +0 -0
  13. {cli2-3.3.36 → cli2-3.3.40}/cli2/colors.py +0 -0
  14. {cli2-3.3.36 → cli2-3.3.40}/cli2/command.py +0 -0
  15. {cli2-3.3.36 → cli2-3.3.40}/cli2/configuration.py +0 -0
  16. {cli2-3.3.36 → cli2-3.3.40}/cli2/decorators.py +0 -0
  17. {cli2-3.3.36 → cli2-3.3.40}/cli2/display.py +0 -0
  18. {cli2-3.3.36 → cli2-3.3.40}/cli2/entry_point.py +0 -0
  19. {cli2-3.3.36 → cli2-3.3.40}/cli2/example_client.py +0 -0
  20. {cli2-3.3.36 → cli2-3.3.40}/cli2/example_client_complex.py +0 -0
  21. {cli2-3.3.36 → cli2-3.3.40}/cli2/example_nesting.py +0 -0
  22. {cli2-3.3.36 → cli2-3.3.40}/cli2/example_obj.py +0 -0
  23. {cli2-3.3.36 → cli2-3.3.40}/cli2/group.py +0 -0
  24. {cli2-3.3.36 → cli2-3.3.40}/cli2/logging.py +0 -0
  25. {cli2-3.3.36 → cli2-3.3.40}/cli2/node.py +0 -0
  26. {cli2-3.3.36 → cli2-3.3.40}/cli2/overrides.py +0 -0
  27. {cli2-3.3.36 → cli2-3.3.40}/cli2/sphinx.py +0 -0
  28. {cli2-3.3.36 → cli2-3.3.40}/cli2/table.py +0 -0
  29. {cli2-3.3.36 → cli2-3.3.40}/cli2/test.py +0 -0
  30. {cli2-3.3.36 → cli2-3.3.40}/cli2/test_cli.py +0 -0
  31. {cli2-3.3.36 → cli2-3.3.40}/cli2/test_command.py +0 -0
  32. {cli2-3.3.36 → cli2-3.3.40}/cli2/test_configuration.py +0 -0
  33. {cli2-3.3.36 → cli2-3.3.40}/cli2/test_decorators.py +0 -0
  34. {cli2-3.3.36 → cli2-3.3.40}/cli2/test_display.py +0 -0
  35. {cli2-3.3.36 → cli2-3.3.40}/cli2/test_entry_point.py +0 -0
  36. {cli2-3.3.36 → cli2-3.3.40}/cli2/test_group.py +0 -0
  37. {cli2-3.3.36 → cli2-3.3.40}/cli2/test_inject.py +0 -0
  38. {cli2-3.3.36 → cli2-3.3.40}/cli2/test_node.py +0 -0
  39. {cli2-3.3.36 → cli2-3.3.40}/cli2/test_table.py +0 -0
  40. {cli2-3.3.36 → cli2-3.3.40}/cli2.egg-info/SOURCES.txt +0 -0
  41. {cli2-3.3.36 → cli2-3.3.40}/cli2.egg-info/dependency_links.txt +0 -0
  42. {cli2-3.3.36 → cli2-3.3.40}/cli2.egg-info/entry_points.txt +0 -0
  43. {cli2-3.3.36 → cli2-3.3.40}/cli2.egg-info/requires.txt +0 -0
  44. {cli2-3.3.36 → cli2-3.3.40}/cli2.egg-info/top_level.txt +0 -0
  45. {cli2-3.3.36 → cli2-3.3.40}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: cli2
3
- Version: 3.3.36
3
+ Version: 3.3.40
4
4
  Summary: image:: https://yourlabs.io/oss/cli2/badges/master/pipeline.svg
5
5
  Home-page: https://yourlabs.io/oss/cli2
6
6
  Author: James Pic
@@ -23,6 +23,17 @@ Requires-Dist: pytest-cov; extra == "test"
23
23
  Requires-Dist: pytest-mock; extra == "test"
24
24
  Requires-Dist: pytest-asyncio; extra == "test"
25
25
  Requires-Dist: pytest-httpx; extra == "test"
26
+ Dynamic: author
27
+ Dynamic: author-email
28
+ Dynamic: description
29
+ Dynamic: description-content-type
30
+ Dynamic: home-page
31
+ Dynamic: keywords
32
+ Dynamic: license
33
+ Dynamic: provides-extra
34
+ Dynamic: requires-dist
35
+ Dynamic: requires-python
36
+ Dynamic: summary
26
37
 
27
38
  .. image:: https://yourlabs.io/oss/cli2/badges/master/pipeline.svg
28
39
  :target: https://yourlabs.io/oss/cli2/pipelines
@@ -34,19 +34,11 @@ class Paginator:
34
34
  """
35
35
  Generic pagination class.
36
36
 
37
- You don't have to override that class to do basic paginator customization,
38
- instead, you can also implement pagination specifics into:
37
+ Should work with most paginations by default, if you're extending this then
38
+ override:
39
39
 
40
- - the :py:class:`~Client` class with the
41
- :py:meth:`~Client.pagination_initialize` and
42
- :py:meth:`~Client.pagination_parameters` methods
43
-
44
- - or also, per model, in the :py:class:`~Model` class with the
45
- :py:meth:`~Model.pagination_initialize` and
46
- :py:meth:`~Model.pagination_parameters` methods
47
-
48
- Refer to :py:meth:`pagination_parameters` and
49
- :py:meth:`pagination_initialize` for details.
40
+ - :py:meth:`~Paginator.pagination_initialize`
41
+ - :py:meth:`~Paginator.pagination_parameters`
50
42
 
51
43
  .. py:attribute:: total_pages
52
44
 
@@ -76,17 +68,15 @@ class Paginator:
76
68
 
77
69
  :py:class:`Model` class or ``dict`` by default.
78
70
 
79
- .. py:attribute:: postfilter
80
-
81
- Callback called for every item after filtering.
82
-
83
- .. py:attribute:: prefilter
71
+ .. py:attribute:: callback
84
72
 
85
- Callback called for every item before filtering.
73
+ Callback called for every item before filtering by expressions.
74
+ This must return True or the item will be filtered *out* of yielded
75
+ results.
86
76
  """
87
77
 
88
78
  def __init__(self, client, url, params=None, model=None, expressions=None,
89
- prefilter=None, postfilter=None):
79
+ callback=None):
90
80
  """
91
81
  Initialize a paginator object with a client on a URL with parameters.
92
82
 
@@ -102,8 +92,7 @@ class Paginator:
102
92
  self.page_start = 1
103
93
  self.per_page = None
104
94
  self.initialized = False
105
- self.prefilter = prefilter
106
- self.postfilter = postfilter
95
+ self.callback = callback
107
96
  self.expressions = []
108
97
  for expression in (expressions or []):
109
98
  if not isinstance(expression, Expression):
@@ -180,12 +169,6 @@ class Paginator:
180
169
 
181
170
  :param data: Data of the first response
182
171
  """
183
- try:
184
- self.model.pagination_initialize
185
- except AttributeError:
186
- return self.client.pagination_initialize(self, data)
187
- else:
188
- return self.model.pagination_initialize(self, data)
189
172
 
190
173
  def pagination_parameters(self, page_number):
191
174
  """
@@ -199,15 +182,12 @@ class Paginator:
199
182
 
200
183
  .. code-block:: python
201
184
 
202
- def pagination_parameters(self, paginator, page_number):
185
+ def pagination_parameters(self, page_number):
186
+ # this is the default implementation
203
187
  return dict(page=page_number)
204
188
  """
205
- try:
206
- self.model.pagination_parameters
207
- except AttributeError:
208
- return self.client.pagination_parameters(self, page_number)
209
- else:
210
- return self.model.pagination_parameters(self, page_number)
189
+ if page_number > 1:
190
+ return dict(page=page_number)
211
191
 
212
192
  def response_items(self, response):
213
193
  """
@@ -277,16 +257,17 @@ class Paginator:
277
257
  await self.initialize(response)
278
258
  return response
279
259
 
280
- async def __aiter__(self, prefilter=None, postfilter=None):
260
+ async def __aiter__(self, callback=None):
281
261
  """
282
262
  Asynchronous iterator.
283
263
  """
284
- prefilter = prefilter or self.prefilter
285
- postfilter = postfilter or self.postfilter
264
+ callback = callback or self.callback
286
265
 
287
266
  if self._reverse and not self.total_pages:
288
267
  first_page_response = await self.page_response(1)
289
268
  page = self.total_pages
269
+ if not self.total_pages:
270
+ raise Exception('Reverse pagination without total_pages')
290
271
  else:
291
272
  page = self.page_start
292
273
 
@@ -294,11 +275,10 @@ class Paginator:
294
275
 
295
276
  async def yielder(items):
296
277
  for item in items:
297
- if prefilter:
298
- await async_resolve(prefilter(item))
278
+ if callback:
279
+ if not await async_resolve(callback(item)):
280
+ continue
299
281
  if not python_filter or python_filter.matches(item):
300
- if postfilter:
301
- await async_resolve(postfilter(item))
302
282
  yield item
303
283
 
304
284
  while items := await self.page_items(page):
@@ -708,6 +688,8 @@ class ModelMetaclass(type):
708
688
  cls = super().__new__(cls, name, bases, attributes)
709
689
  client = getattr(cls, 'client', None)
710
690
  if client:
691
+ if not cls.paginator:
692
+ cls.paginator = client.paginator
711
693
  return cls
712
694
 
713
695
  client_class = getattr(cls, '_client_class', None)
@@ -776,7 +758,7 @@ class Model(metaclass=ModelMetaclass):
776
758
 
777
759
  Object URL based on :py:attr:`url_detail` and :py:attr:`id_field`.
778
760
  """
779
- paginator = Paginator
761
+ paginator = None
780
762
  model_command = ModelCommand
781
763
  model_group = ModelGroup
782
764
  url_list = None
@@ -834,32 +816,6 @@ class Model(metaclass=ModelMetaclass):
834
816
  """
835
817
  return cls.paginator(cls.client, url, params, cls, expressions)
836
818
 
837
- @classmethod
838
- def pagination_initialize(cls, paginator, data):
839
- """
840
- Implement Model-specific pagination initialization here.
841
-
842
- Otherwise, :py:meth:`Client.pagination_initialize` will
843
- take place.
844
-
845
- Refer to :py:meth:`Paginator.pagination_initialize` for
846
- details.
847
- """
848
- cls.client.pagination_initialize(paginator, data)
849
-
850
- @classmethod
851
- def pagination_parameters(cls, paginator, page_number):
852
- """
853
- Implement Model-specific pagination parameters here.
854
-
855
- Otherwise, :py:meth:`Client.pagination_parameters` will
856
- take place.
857
-
858
- Refer to :py:meth:`Paginator.pagination_parameters` for
859
- details.
860
- """
861
- return cls.client.pagination_parameters(paginator, page_number)
862
-
863
819
  @property
864
820
  def cli2_display(self):
865
821
  return self.data
@@ -1177,9 +1133,7 @@ class Client(metaclass=ClientMetaclass):
1177
1133
 
1178
1134
  .. py:attribute:: paginator
1179
1135
 
1180
- :py:class:`Paginator` class, you can leave it by default and just
1181
- implement :py:meth:`pagination_initialize` and
1182
- :py:meth:`pagination_parameters`.
1136
+ :py:class:`Paginator` class
1183
1137
 
1184
1138
  .. py:attribute:: semaphore
1185
1139
 
@@ -1605,7 +1559,8 @@ class Client(metaclass=ClientMetaclass):
1605
1559
  """ DELETE Request """
1606
1560
  return await self.request('DELETE', url, *args, **kwargs)
1607
1561
 
1608
- def paginate(self, url, params=None, model=None):
1562
+ def paginate(self, url, *expressions, params=None, model=None,
1563
+ callback=None):
1609
1564
  """
1610
1565
  Return a paginator to iterate over results
1611
1566
 
@@ -1613,23 +1568,8 @@ class Client(metaclass=ClientMetaclass):
1613
1568
  :param params: GET parameters
1614
1569
  :param model: Model class to cast for items
1615
1570
  """
1616
- return self.paginator(self, url, params or {}, model or dict)
1617
-
1618
- def pagination_parameters(self, paginator, page_number):
1619
- """
1620
- Implement Model-specific pagination parameters here.
1621
-
1622
- Refer to :py:meth:`Paginator.pagination_parameters` for
1623
- details.
1624
- """
1625
-
1626
- def pagination_initialize(self, paginator, data):
1627
- """
1628
- Implement Model-specific pagination initialization here.
1629
-
1630
- Refer to :py:meth:`Paginator.pagination_initialize` for
1631
- details.
1632
- """
1571
+ return self.paginator(self, url, params or {}, model or dict,
1572
+ expressions, callback)
1633
1573
 
1634
1574
 
1635
1575
  class Expression:
@@ -49,6 +49,7 @@ async def test_client_cli(client_class, httpx_mock):
49
49
  assert isinstance(result.client, client_class)
50
50
 
51
51
  httpx_mock.add_response(url='http://lol/', json=[dict(a=1)])
52
+ httpx_mock.add_response(url='http://lol/?page=2', json=[])
52
53
  await client_class.cli['testmodel']['find'].async_call()
53
54
 
54
55
  class TestModel2(client_class.Model):
@@ -124,6 +125,7 @@ async def test_async_factory(httpx_mock):
124
125
  url_list = '/2'
125
126
 
126
127
  httpx_mock.add_response(url='http://bar/2', json=[dict(a=1)])
128
+ httpx_mock.add_response(url='http://bar/2?page=2', json=[])
127
129
  await TestClient.cli['testmodel']['find'].async_call()
128
130
 
129
131
 
@@ -369,33 +371,48 @@ async def test_token(httpx_mock):
369
371
 
370
372
  @pytest.mark.asyncio
371
373
  async def test_pagination(httpx_mock):
372
- httpx_mock.add_response(url='http://lol/?page=1', json=[dict(a=1)])
374
+ httpx_mock.add_response(url='http://lol/', json=[dict(a=1)])
373
375
  httpx_mock.add_response(url='http://lol/?page=2', json=[dict(a=2)])
374
376
  httpx_mock.add_response(url='http://lol/?page=3', json=[])
375
377
  client = Client(base_url='http://lol')
376
- paginator = client.paginate('/')
377
378
 
378
- def prefilter(item):
379
+ def callback(item):
379
380
  item['b'] = item['a']
381
+ return True
380
382
 
381
- def postfilter(item):
382
- item['c'] = item['b']
383
-
384
- paginator.prefilter = prefilter
385
- paginator.postfilter = postfilter
383
+ paginator = client.paginate(
384
+ '/',
385
+ lambda item: item['b'] == 2,
386
+ callback=callback,
387
+ )
386
388
  assert await paginator.list() == [
387
- dict(a=1, b=1, c=1),
388
- dict(a=2, b=2, c=2)
389
+ dict(a=2, b=2)
389
390
  ]
390
391
 
391
392
 
393
+ def test_paginator(client_class):
394
+ class Client(client_class):
395
+ paginator = 'foo'
396
+
397
+ class Model1(Client.Model):
398
+ pass
399
+
400
+ class Model2(Client.Model):
401
+ paginator = 'bar'
402
+
403
+ client = Client()
404
+ assert client.Model1.paginator == 'foo'
405
+ assert client.Model2.paginator == 'bar'
406
+
407
+
392
408
  @pytest.mark.asyncio
393
409
  async def test_pagination_initialize(httpx_mock):
394
- httpx_mock.add_response(url='http://lol/?page=1', json=dict(
410
+ httpx_mock.add_response(url='http://lol/', json=dict(
395
411
  total_pages=2,
396
412
  items=[dict(a=1)],
397
413
  ))
398
414
  httpx_mock.add_response(url='http://lol/?page=2', json=[dict(a=2)])
415
+ httpx_mock.add_response(url='http://lol/?page=3', json=[])
399
416
 
400
417
  class PaginatedClient(Client):
401
418
  def pagination_initialize(self, paginator, data):
@@ -404,7 +421,7 @@ async def test_pagination_initialize(httpx_mock):
404
421
  client = PaginatedClient(base_url='http://lol')
405
422
  assert await client.paginate('/').list() == [dict(a=1), dict(a=2)]
406
423
 
407
- httpx_mock.add_response(url='http://lol/?page=1', json=dict(
424
+ httpx_mock.add_response(url='http://lol/', json=dict(
408
425
  total_pages=2,
409
426
  items=[dict(a=1)],
410
427
  ))
@@ -414,7 +431,7 @@ async def test_pagination_initialize(httpx_mock):
414
431
  @pytest.mark.asyncio
415
432
  async def test_token_get(httpx_mock):
416
433
  httpx_mock.add_response(url='http://lol/token', json=dict(token=123))
417
- httpx_mock.add_response(url='http://lol/?page=1', json=[])
434
+ httpx_mock.add_response(url='http://lol/', json=[])
418
435
 
419
436
  class TokenClient(Client):
420
437
  async def token_get(self):
@@ -431,7 +448,7 @@ async def test_pagination_model(httpx_mock):
431
448
  class Model(dict):
432
449
  pass
433
450
 
434
- httpx_mock.add_response(url='http://lol/?page=1', json=[dict(a=2)])
451
+ httpx_mock.add_response(url='http://lol/', json=[dict(a=2)])
435
452
  httpx_mock.add_response(url='http://lol/?page=2', json=[])
436
453
  client = Client(base_url='http://lol')
437
454
  result = await client.paginate('/', model=Model).list()
@@ -450,47 +467,50 @@ async def test_pagination_patterns(httpx_mock):
450
467
  # I'm dealing with APIs which have a different pagination system on
451
468
  # different resources, and on some resources no pagination at all
452
469
  # Would like to define that per model
470
+
471
+ class TotalPaginator(cli2.Paginator):
472
+ def pagination_initialize(self, data):
473
+ self.total_items = data['total_items']
474
+ self.per_page = len(data['items'])
475
+
453
476
  class TotalModel(Client.Model):
477
+ paginator = TotalPaginator
454
478
  url_list = '/foo'
455
479
 
456
- @classmethod
457
- def pagination_initialize(cls, paginator, data):
458
- paginator.total_items = data['total_items']
459
- paginator.per_page = len(data['items'])
460
-
461
480
  httpx_mock.add_response(
462
- url='http://lol/foo?page=1',
481
+ url='http://lol/foo',
463
482
  json=dict(total_items=2, items=[dict(a=1)]),
464
483
  )
465
484
 
485
+ class PagesPaginator(cli2.Paginator):
486
+ def pagination_initialize(self, data):
487
+ self.total_pages = data['total_pages']
488
+ self.per_page = len(data['items'])
489
+
466
490
  class Pages(Client.Model):
467
491
  url_list = '/bar'
468
-
469
- @classmethod
470
- def pagination_initialize(cls, paginator, data):
471
- paginator.total_pages = data['total_pages']
472
- paginator.per_page = len(data['items'])
492
+ paginator = PagesPaginator
473
493
 
474
494
  httpx_mock.add_response(
475
- url='http://lol/bar?page=1',
495
+ url='http://lol/bar',
476
496
  json=dict(total_pages=1, items=[dict(a=1)]),
477
497
  )
478
498
 
479
- class Offset(Client.Model):
480
- url_list = '/off'
499
+ class OffsetPaginator(cli2.Paginator):
500
+ def pagination_initialize(self, data):
501
+ self.total_items = data['total']
481
502
 
482
- @classmethod
483
- def pagination_initialize(cls, paginator, data):
484
- paginator.total_items = data['total']
485
-
486
- @classmethod
487
- def pagination_parameters(cls, paginator, page_number):
488
- paginator.per_page = 1
503
+ def pagination_parameters(self, page_number):
504
+ self.per_page = 1
489
505
  return dict(
490
506
  offset=(page_number - 1) * paginator.per_page,
491
507
  limit=paginator.per_page,
492
508
  )
493
509
 
510
+ class Offset(Client.Model):
511
+ url_list = '/off'
512
+ paginator = OffsetPaginator
513
+
494
514
  httpx_mock.add_response(
495
515
  url='http://lol/off?offset=0&limit=1',
496
516
  json=dict(total=2, items=[dict(a=1)]),
@@ -519,7 +539,7 @@ async def test_pagination_patterns(httpx_mock):
519
539
  @pytest.mark.asyncio
520
540
  async def test_pagination_reverse(httpx_mock):
521
541
  httpx_mock.add_response(
522
- url='http://lol/bar?page=1',
542
+ url='http://lol/bar',
523
543
  json=dict(total_pages=3, items=[dict(a=1), dict(a=2)]),
524
544
  )
525
545
  httpx_mock.add_response(
@@ -531,13 +551,13 @@ async def test_pagination_reverse(httpx_mock):
531
551
  json=dict(total_pages=3, items=[dict(a=5)]),
532
552
  )
533
553
 
554
+ class Paginator(cli2.Paginator):
555
+ def pagination_initialize(self, data):
556
+ self.total_pages = data['total_pages']
557
+
534
558
  # test that we can reverse pagination too
535
559
  class Client(cli2.Client):
536
- def pagination_initialize(self, paginator, data):
537
- paginator.total_pages = data['total_pages']
538
-
539
- def pagination_parameters(self, paginator, page_number):
540
- return dict(page=page_number)
560
+ paginator = Paginator
541
561
 
542
562
  client = Client(base_url='http://lol')
543
563
  paginator = client.paginate('/bar')
@@ -663,17 +683,18 @@ def test_relation_many():
663
683
 
664
684
  @pytest.mark.asyncio
665
685
  async def test_python_expression(httpx_mock):
686
+ class Paginator(cli2.Paginator):
687
+ def pagination_initialize(self, data):
688
+ self.total_pages = data['total_pages']
689
+
666
690
  class Model(Client.Model):
667
691
  url_list = '/foo'
668
692
  a = cli2.Field()
669
693
  b = cli2.Field()
670
-
671
- @classmethod
672
- def pagination_initialize(cls, paginator, data):
673
- paginator.total_pages = data['total_pages']
694
+ paginator = Paginator
674
695
 
675
696
  def mock():
676
- httpx_mock.add_response(url='http://lol/foo?page=1', json=dict(
697
+ httpx_mock.add_response(url='http://lol/foo', json=dict(
677
698
  total_pages=2,
678
699
  items=[dict(a=1, b=1), dict(a=2, b=2), dict(a=3, b=1)],
679
700
  ))
@@ -723,7 +744,7 @@ async def test_expression_parameter(httpx_mock):
723
744
  a = cli2.Field()
724
745
  b = cli2.Field(parameter='b')
725
746
 
726
- httpx_mock.add_response(url='http://lol/foo?page=1&b=1', json=dict(
747
+ httpx_mock.add_response(url='http://lol/foo?b=1', json=dict(
727
748
  items=[dict(a=1, b=1), dict(a=3, b=1)],
728
749
  ))
729
750
  httpx_mock.add_response(url='http://lol/foo?page=2&b=1', json=dict())
@@ -769,7 +790,7 @@ async def test_client_cli2(httpx_mock):
769
790
 
770
791
  meth = Client.cli['foo']['find']
771
792
  httpx_mock.add_response(
772
- url='http://lol/foo?page=1',
793
+ url='http://lol/foo',
773
794
  json=[dict(id=1, a=2)],
774
795
  )
775
796
  httpx_mock.add_response(url='http://lol/foo?page=2', json=[])
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: cli2
3
- Version: 3.3.36
3
+ Version: 3.3.40
4
4
  Summary: image:: https://yourlabs.io/oss/cli2/badges/master/pipeline.svg
5
5
  Home-page: https://yourlabs.io/oss/cli2
6
6
  Author: James Pic
@@ -23,6 +23,17 @@ Requires-Dist: pytest-cov; extra == "test"
23
23
  Requires-Dist: pytest-mock; extra == "test"
24
24
  Requires-Dist: pytest-asyncio; extra == "test"
25
25
  Requires-Dist: pytest-httpx; extra == "test"
26
+ Dynamic: author
27
+ Dynamic: author-email
28
+ Dynamic: description
29
+ Dynamic: description-content-type
30
+ Dynamic: home-page
31
+ Dynamic: keywords
32
+ Dynamic: license
33
+ Dynamic: provides-extra
34
+ Dynamic: requires-dist
35
+ Dynamic: requires-python
36
+ Dynamic: summary
26
37
 
27
38
  .. image:: https://yourlabs.io/oss/cli2/badges/master/pipeline.svg
28
39
  :target: https://yourlabs.io/oss/cli2/pipelines
@@ -3,7 +3,7 @@ from setuptools import setup
3
3
 
4
4
  setup(
5
5
  name='cli2',
6
- version='3.3.36',
6
+ version='3.3.40',
7
7
  setup_requires='setupmeta',
8
8
  install_requires=[
9
9
  'docstring_parser',
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes