From 715d10fa8a660a486d641f7521b493c4efaac391 Mon Sep 17 00:00:00 2001 From: Peter Yasi Date: Thu, 14 May 2020 00:00:30 -0400 Subject: [PATCH 1/9] Initial implementation with example unit tests --- pact/matchers.py | 62 +++++++++++++++++++++++++++++++++++++----- tests/test_matchers.py | 24 +++++++++++++++- 2 files changed, 78 insertions(+), 8 deletions(-) diff --git a/pact/matchers.py b/pact/matchers.py index b721471aa..0d8909b73 100644 --- a/pact/matchers.py +++ b/pact/matchers.py @@ -1,5 +1,8 @@ """Classes for defining request and response data that is variable.""" import six +import datetime + +from enum import Enum class Matcher(object): @@ -33,8 +36,8 @@ class EachLike(Matcher): ... })) Would expect the response to be a JSON object, with a comments list. In - that list should be at least 2 items, and each item should be a `dict` - with the keys `name` and `text`, + that list should be at least 2 items, and each item should be a 'dict' + with the keys 'name' and 'text', """ def __init__(self, matcher, minimum=1): @@ -83,8 +86,8 @@ class Like(Matcher): ... })) Would expect the response body to be a JSON object, containing the key - `number`, which would contain an integer. When the consumer runs this - contract, the value `1111222233334444` will be returned by the mock + 'number', which would contain an integer. When the consumer runs this + contract, the value '1111222233334444' will be returned by the mock service, instead of a randomly generated value. """ @@ -132,7 +135,7 @@ class Term(Matcher): >>> from pact import Consumer, Provider >>> pact = Consumer('consumer').has_pact_with(Provider('provider')) - >>> (pact.given('the current user is logged in as `tester`') + >>> (pact.given('the current user is logged in as 'tester'') ... .upon_receiving('a request for the user profile') ... .with_request('get', '/profile') ... .will_respond_with(200, body={ @@ -141,9 +144,9 @@ class Term(Matcher): ... })) Would expect the response body to be a JSON object, containing the key - `name`, which will contain the value `tester`, and `theme` which must be + 'name', which will contain the value 'tester', and 'theme' which must be one of the values: light, dark, or legacy. When the consumer runs this - contract, the value `dark` will be returned by the mock service. + contract, the value 'dark' will be returned by the mock service. """ def __init__(self, matcher, generate): @@ -225,3 +228,48 @@ def get_generated_values(input): return input.generate()['data']['generate'] else: raise ValueError('Unknown type: %s' % type(input)) + +class Format: + + def __init__(self): + """ + + """ + self.identifier = self.identifier() + self.ip_address = self.ip_address() + self.hexadecimal = self.hexadecimal() + self.uuid = self.uuid() + self.timestamp = self.timestamp() + self.date = self.date() + self.time = self.time() + + def identifier(self): + return Like(1) + + def ip_address(self): + return Term(self.Regexes.ip_address.value, '127.0.0.1') + + def ipv6_address(self): + return Term(self.Regexes.ipv6_address.value, '::ffff:192.0.2.128') + + def uuid(self): + return Term(self.Regexes.uuid.value, 'fc763eba-0905-41c5-a27f-3934ab26786c') + + def timestamp(self): + return Term(self.Regexes.timestamp.value, datetime.datetime(2000, 2, 1, 12, 30, 0, 0)) + + def date(self): + return Term(self.Regexes.date.value, datetime.datetime(2000, 2, 1, 12, 30, 0, 0).date()) + + def time(self): + return Term(self.Regexes.time_regex.value, datetime.datetime(2000, 2, 1, 12, 30, 0, 0).time()) + + + class Regexes(Enum): + ip_address = '(\d{1,3}\.)+\d{1,3}' + hexadecimal = '[0-9a-fA-F]+' + ipv6_address = '(\A([0-9a-f]{1,4}:){1,1}(:[0-9a-f]{1,4}){1,6}\Z)|(\A([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,5}\Z)|(\A([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,4}\Z)|(\A([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,3}\Z)|(\A([0-9a-f]{1,4}:){1,5}(:[0-9a-f]{1,4}){1,2}\Z)|(\A([0-9a-f]{1,4}:){1,6}(:[0-9a-f]{1,4}){1,1}\Z)|(\A(([0-9a-f]{1,4}:){1,7}|:):\Z)|(\A:(:[0-9a-f]{1,4}){1,7}\Z)|(\A((([0-9a-f]{1,4}:){6})(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})\Z)|(\A(([0-9a-f]{1,4}:){5}[0-9a-f]{1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})\Z)|(\A([0-9a-f]{1,4}:){5}:[0-9a-f]{1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A([0-9a-f]{1,4}:){1,1}(:[0-9a-f]{1,4}){1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,3}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,2}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,1}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A(([0-9a-f]{1,4}:){1,5}|:):(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A:(:[0-9a-f]{1,4}){1,5}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)' + uuid = '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}' + timestamp = '^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$' + date = '^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))?)' + time_regex = '^(T\d\d:\d\d(:\d\d)?(\.\d+)?(([+-]\d\d:\d\d)|Z)?)?$' \ No newline at end of file diff --git a/tests/test_matchers.py b/tests/test_matchers.py index 6514a7bbb..13f97737c 100644 --- a/tests/test_matchers.py +++ b/tests/test_matchers.py @@ -1,7 +1,7 @@ from unittest import TestCase from pact.matchers import EachLike, Like, Matcher, SomethingLike, \ - Term, from_term, get_generated_values + Term, Format, from_term, get_generated_values class MatcherTestCase(TestCase): @@ -238,3 +238,25 @@ def test_nested(self): def test_unknown_type(self): with self.assertRaises(ValueError): get_generated_values(set()) + +class FormatTestCase(TestCase): + + def test_identifier(self): + id = Format().identifier.generate() + self.assertEqual(id, {'json_class': 'Pact::SomethingLike', 'contents': 1}) + + def test_ip_address(self): + ip_address = Format().ip_address.generate() + self.assertEqual( + ip_address, + {'json_class': 'Pact::Term', + 'json_class': 'Pact::Term', + 'data': { + 'matcher': { + 'json_class': 'Regexp', + 's': Format().Regexes.ip_address.value, + 'o': 0 + }, + 'generate': '127.0.0.1' + } + }) \ No newline at end of file From a21118c3ed1205865c11a097065b791b9a371c79 Mon Sep 17 00:00:00 2001 From: Peter Yasi Date: Thu, 14 May 2020 08:54:01 -0400 Subject: [PATCH 2/9] Use raw strings to avoid deprecated escape sequence --- pact/matchers.py | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/pact/matchers.py b/pact/matchers.py index 0d8909b73..4fa0d7850 100644 --- a/pact/matchers.py +++ b/pact/matchers.py @@ -36,8 +36,8 @@ class EachLike(Matcher): ... })) Would expect the response to be a JSON object, with a comments list. In - that list should be at least 2 items, and each item should be a 'dict' - with the keys 'name' and 'text', + that list should be at least 2 items, and each item should be a `dict` + with the keys `name` and `text`, """ def __init__(self, matcher, minimum=1): @@ -86,8 +86,8 @@ class Like(Matcher): ... })) Would expect the response body to be a JSON object, containing the key - 'number', which would contain an integer. When the consumer runs this - contract, the value '1111222233334444' will be returned by the mock + `number`, which would contain an integer. When the consumer runs this + contract, the value `1111222233334444` will be returned by the mock service, instead of a randomly generated value. """ @@ -135,7 +135,7 @@ class Term(Matcher): >>> from pact import Consumer, Provider >>> pact = Consumer('consumer').has_pact_with(Provider('provider')) - >>> (pact.given('the current user is logged in as 'tester'') + >>> (pact.given('the current user is logged in as `tester`') ... .upon_receiving('a request for the user profile') ... .with_request('get', '/profile') ... .will_respond_with(200, body={ @@ -144,9 +144,9 @@ class Term(Matcher): ... })) Would expect the response body to be a JSON object, containing the key - 'name', which will contain the value 'tester', and 'theme' which must be + `name`, which will contain the value `tester`, and `theme` which must be one of the values: light, dark, or legacy. When the consumer runs this - contract, the value 'dark' will be returned by the mock service. + contract, the value `dark` will be returned by the mock service. """ def __init__(self, matcher, generate): @@ -238,6 +238,7 @@ def __init__(self): self.identifier = self.identifier() self.ip_address = self.ip_address() self.hexadecimal = self.hexadecimal() + self.ipv6_address = self.ipv6_address() self.uuid = self.uuid() self.timestamp = self.timestamp() self.date = self.date() @@ -248,6 +249,9 @@ def identifier(self): def ip_address(self): return Term(self.Regexes.ip_address.value, '127.0.0.1') + + def hexadecimal(self): + return Term(self.Regexes.hexadecimal.value, '3F') def ipv6_address(self): return Term(self.Regexes.ipv6_address.value, '::ffff:192.0.2.128') @@ -266,10 +270,10 @@ def time(self): class Regexes(Enum): - ip_address = '(\d{1,3}\.)+\d{1,3}' - hexadecimal = '[0-9a-fA-F]+' - ipv6_address = '(\A([0-9a-f]{1,4}:){1,1}(:[0-9a-f]{1,4}){1,6}\Z)|(\A([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,5}\Z)|(\A([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,4}\Z)|(\A([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,3}\Z)|(\A([0-9a-f]{1,4}:){1,5}(:[0-9a-f]{1,4}){1,2}\Z)|(\A([0-9a-f]{1,4}:){1,6}(:[0-9a-f]{1,4}){1,1}\Z)|(\A(([0-9a-f]{1,4}:){1,7}|:):\Z)|(\A:(:[0-9a-f]{1,4}){1,7}\Z)|(\A((([0-9a-f]{1,4}:){6})(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})\Z)|(\A(([0-9a-f]{1,4}:){5}[0-9a-f]{1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})\Z)|(\A([0-9a-f]{1,4}:){5}:[0-9a-f]{1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A([0-9a-f]{1,4}:){1,1}(:[0-9a-f]{1,4}){1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,3}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,2}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,1}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A(([0-9a-f]{1,4}:){1,5}|:):(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A:(:[0-9a-f]{1,4}){1,5}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)' - uuid = '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}' - timestamp = '^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$' - date = '^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))?)' - time_regex = '^(T\d\d:\d\d(:\d\d)?(\.\d+)?(([+-]\d\d:\d\d)|Z)?)?$' \ No newline at end of file + ip_address = r'(\d{1,3}\.)+\d{1,3}' + hexadecimal = r'[0-9a-fA-F]+' + ipv6_address = r'(\A([0-9a-f]{1,4}:){1,1}(:[0-9a-f]{1,4}){1,6}\Z)|(\A([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,5}\Z)|(\A([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,4}\Z)|(\A([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,3}\Z)|(\A([0-9a-f]{1,4}:){1,5}(:[0-9a-f]{1,4}){1,2}\Z)|(\A([0-9a-f]{1,4}:){1,6}(:[0-9a-f]{1,4}){1,1}\Z)|(\A(([0-9a-f]{1,4}:){1,7}|:):\Z)|(\A:(:[0-9a-f]{1,4}){1,7}\Z)|(\A((([0-9a-f]{1,4}:){6})(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})\Z)|(\A(([0-9a-f]{1,4}:){5}[0-9a-f]{1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})\Z)|(\A([0-9a-f]{1,4}:){5}:[0-9a-f]{1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A([0-9a-f]{1,4}:){1,1}(:[0-9a-f]{1,4}){1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,3}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,2}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,1}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A(([0-9a-f]{1,4}:){1,5}|:):(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A:(:[0-9a-f]{1,4}){1,5}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)' + uuid = r'[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}' + timestamp = r'^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$' + date = r'^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))?)' + time_regex = r'^(T\d\d:\d\d(:\d\d)?(\.\d+)?(([+-]\d\d:\d\d)|Z)?)?$' \ No newline at end of file From 0d588f7210ebe11a7ecbb2f53c654c6c11362b68 Mon Sep 17 00:00:00 2001 From: Peter Yasi Date: Thu, 14 May 2020 18:19:32 -0400 Subject: [PATCH 3/9] pydocs and formatting --- pact/matchers.py | 139 +++++++++++++++++++++++++++++++++++---- tests/test_matchers.py | 146 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 256 insertions(+), 29 deletions(-) diff --git a/pact/matchers.py b/pact/matchers.py index 4fa0d7850..c5878a88c 100644 --- a/pact/matchers.py +++ b/pact/matchers.py @@ -229,11 +229,33 @@ def get_generated_values(input): else: raise ValueError('Unknown type: %s' % type(input)) + class Format: + """ + Class of regular expressions for common formats. + + Example: + + >>> from pact import Consumer, Provider + >>> from pact.matchers import Format + >>> pact = Consumer('consumer').has_pact_with(Provider('provider')) + >>> (pact.given('the current user is logged in as `tester`') + ... .upon_receiving('a request for the user profile') + ... .with_request('get', '/profile') + ... .will_respond_with(200, body={ + ... 'id': Format().identifier, + ... 'lastUpdated': Format().time + ... })) + + Would expect `id` to be any valid int and `lastUpdated` to be a valid time. + When the consumer runs this contract, the value of that will be returned + is the second value passed to Term in the given function, for the time + example it would be datetime.datetime(2000, 2, 1, 12, 30, 0, 0).time() + """ def __init__(self): """ - + Create a new Formatter """ self.identifier = self.identifier() self.ip_address = self.ip_address() @@ -245,35 +267,124 @@ def __init__(self): self.time = self.time() def identifier(self): + """ + Matches any integer + + :return: a Like object with an integer + :rtype: Like + """ return Like(1) def ip_address(self): + """ + Matches any ip address + + :return: a Term object with an ip address regex + :rtype: Term + """ return Term(self.Regexes.ip_address.value, '127.0.0.1') def hexadecimal(self): + """ + Matches any hexadecimal + + :return: a Term object with a hexdecimal regex + :rtype: Term + """ return Term(self.Regexes.hexadecimal.value, '3F') - + def ipv6_address(self): + """ + Matches any ipv6 address + + :return: a Term object with an ipv6 address regex + :rtype: Term + """ return Term(self.Regexes.ipv6_address.value, '::ffff:192.0.2.128') - + def uuid(self): - return Term(self.Regexes.uuid.value, 'fc763eba-0905-41c5-a27f-3934ab26786c') + """ + Matches any uuid + + :return: a Term object with a uuid regex + :rtype: Term + """ + return Term( + self.Regexes.uuid.value, 'fc763eba-0905-41c5-a27f-3934ab26786c' + ) def timestamp(self): - return Term(self.Regexes.timestamp.value, datetime.datetime(2000, 2, 1, 12, 30, 0, 0)) + """ + Matches any timestamp + + :return: a Term object with a timestamp regex + :rtype: Term + """ + return Term( + self.Regexes.timestamp.value, datetime.datetime( + 2000, 2, 1, 12, 30, 0, 0 + ) + ) def date(self): - return Term(self.Regexes.date.value, datetime.datetime(2000, 2, 1, 12, 30, 0, 0).date()) + """ + Matches any date + + :return: a Term object with a date regex + :rtype: Term + """ + return Term( + self.Regexes.date.value, datetime.datetime( + 2000, 2, 1, 12, 30, 0, 0 + ).date() + ) def time(self): - return Term(self.Regexes.time_regex.value, datetime.datetime(2000, 2, 1, 12, 30, 0, 0).time()) + """ + Matches any time + :return: a Term object with a time regex + :rtype: Term + """ + return Term( + self.Regexes.time_regex.value, datetime.datetime( + 2000, 2, 1, 12, 30, 0, 0 + ).time() + ) class Regexes(Enum): - ip_address = r'(\d{1,3}\.)+\d{1,3}' - hexadecimal = r'[0-9a-fA-F]+' - ipv6_address = r'(\A([0-9a-f]{1,4}:){1,1}(:[0-9a-f]{1,4}){1,6}\Z)|(\A([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,5}\Z)|(\A([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,4}\Z)|(\A([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,3}\Z)|(\A([0-9a-f]{1,4}:){1,5}(:[0-9a-f]{1,4}){1,2}\Z)|(\A([0-9a-f]{1,4}:){1,6}(:[0-9a-f]{1,4}){1,1}\Z)|(\A(([0-9a-f]{1,4}:){1,7}|:):\Z)|(\A:(:[0-9a-f]{1,4}){1,7}\Z)|(\A((([0-9a-f]{1,4}:){6})(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})\Z)|(\A(([0-9a-f]{1,4}:){5}[0-9a-f]{1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})\Z)|(\A([0-9a-f]{1,4}:){5}:[0-9a-f]{1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A([0-9a-f]{1,4}:){1,1}(:[0-9a-f]{1,4}){1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,3}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,2}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,1}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A(([0-9a-f]{1,4}:){1,5}|:):(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A:(:[0-9a-f]{1,4}){1,5}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)' - uuid = r'[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}' - timestamp = r'^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$' - date = r'^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))?)' - time_regex = r'^(T\d\d:\d\d(:\d\d)?(\.\d+)?(([+-]\d\d:\d\d)|Z)?)?$' \ No newline at end of file + ip_address = r'(\d{1,3}\.)+\d{1,3}' + hexadecimal = r'[0-9a-fA-F]+' + ipv6_address = r'(\A([0-9a-f]{1,4}:){1,1}(:[0-9a-f]{1,4}){1,6}\Z)|' \ + r'(\A([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,5}\Z)|(\A([0-9a-f]' \ + r'{1,4}:){1,3}(:[0-9a-f]{1,4}){1,4}\Z)|(\A([0-9a-f]{1,4}:)' \ + r'{1,4}(:[0-9a-f]{1,4}){1,3}\Z)|(\A([0-9a-f]{1,4}:){1,5}(:[0-' \ + r'9a-f]{1,4}){1,2}\Z)|(\A([0-9a-f]{1,4}:){1,6}(:[0-9a-f]{1,4})' \ + r'{1,1}\Z)|(\A(([0-9a-f]{1,4}:){1,7}|:):\Z)|(\A:(:[0-9a-f]{1,4})' \ + r'{1,7}\Z)|(\A((([0-9a-f]{1,4}:){6})(25[0-5]|2[0-4]\d|[0-1]' \ + r'?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})\Z)|(\A(([0-9a-f]' \ + r'{1,4}:){5}[0-9a-f]{1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25' \ + r'[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})\Z)|(\A([0-9a-f]{1,4}:){5}:[' \ + r'0-9a-f]{1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4' \ + r']\d|[0-1]?\d?\d)){3}\Z)|(\A([0-9a-f]{1,4}:){1,1}(:[0-9a-f]' \ + r'{1,4}){1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]' \ + r'\d|[0-1]?\d?\d)){3}\Z)|(\A([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}' \ + r'){1,3}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0' \ + r'-1]?\d?\d)){3}\Z)|(\A([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,' \ + r'2}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]' \ + r'?\d?\d)){3}\Z)|(\A([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,1}:' \ + r'(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?' \ + r'\d)){3}\Z)|(\A(([0-9a-f]{1,4}:){1,5}|:):(25[0-5]|2[0-4]\d|[0' \ + r'-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|(\A:(:[' \ + r'0-9a-f]{1,4}){1,5}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]' \ + r'|2[0-4]\d|[0-1]?\d?\d)){3}\Z)' + uuid = r'[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}' + timestamp = r'^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3(' \ + r'[12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-' \ + r'9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2' \ + r'[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d' \ + r'([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$' + date = r'^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|' \ + r'0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|' \ + r'[12]\d{2}|3([0-5]\d|6[1-6])))?)' + time_regex = r'^(T\d\d:\d\d(:\d\d)?(\.\d+)?(([+-]\d\d:\d\d)|Z)?)?$' diff --git a/tests/test_matchers.py b/tests/test_matchers.py index 13f97737c..85dec6729 100644 --- a/tests/test_matchers.py +++ b/tests/test_matchers.py @@ -1,3 +1,5 @@ +import datetime + from unittest import TestCase from pact.matchers import EachLike, Like, Matcher, SomethingLike, \ @@ -239,24 +241,138 @@ def test_unknown_type(self): with self.assertRaises(ValueError): get_generated_values(set()) + class FormatTestCase(TestCase): + @classmethod + def setUpClass(cls): + cls.formatter = Format() def test_identifier(self): - id = Format().identifier.generate() - self.assertEqual(id, {'json_class': 'Pact::SomethingLike', 'contents': 1}) - + id = self.formatter.identifier.generate() + self.assertEqual(id, {"json_class": "Pact::SomethingLike", "contents": 1}) + def test_ip_address(self): - ip_address = Format().ip_address.generate() + ip_address = self.formatter.ip_address.generate() self.assertEqual( ip_address, - {'json_class': 'Pact::Term', - 'json_class': 'Pact::Term', - 'data': { - 'matcher': { - 'json_class': 'Regexp', - 's': Format().Regexes.ip_address.value, - 'o': 0 - }, - 'generate': '127.0.0.1' - } - }) \ No newline at end of file + { + "json_class": "Pact::Term", + "json_class": "Pact::Term", + "data": { + "matcher": { + "json_class": "Regexp", + "s": self.formatter.Regexes.ip_address.value, + "o": 0, + }, + "generate": "127.0.0.1", + }, + }, + ) + + def test_hexadecimal(self): + hexadecimal = self.formatter.hexadecimal.generate() + self.assertEqual( + hexadecimal, + { + "json_class": "Pact::Term", + "json_class": "Pact::Term", + "data": { + "matcher": { + "json_class": "Regexp", + "s": self.formatter.Regexes.hexadecimal.value, + "o": 0, + }, + "generate": "3F", + }, + }, + ) + + def test_ipv6_address(self): + ipv6_address = self.formatter.ipv6_address.generate() + self.assertEqual( + ipv6_address, + { + "json_class": "Pact::Term", + "json_class": "Pact::Term", + "data": { + "matcher": { + "json_class": "Regexp", + "s": self.formatter.Regexes.ipv6_address.value, + "o": 0, + }, + "generate": "::ffff:192.0.2.128", + }, + }, + ) + + def test_uuid(self): + uuid = self.formatter.uuid.generate() + self.assertEqual( + uuid, + { + "json_class": "Pact::Term", + "json_class": "Pact::Term", + "data": { + "matcher": { + "json_class": "Regexp", + "s": self.formatter.Regexes.uuid.value, + "o": 0, + }, + "generate": "fc763eba-0905-41c5-a27f-3934ab26786c", + }, + }, + ) + + def test_timestamp(self): + timestamp = self.formatter.timestamp.generate() + self.assertEqual( + timestamp, + { + "json_class": "Pact::Term", + "json_class": "Pact::Term", + "data": { + "matcher": { + "json_class": "Regexp", + "s": self.formatter.Regexes.timestamp.value, + "o": 0, + }, + "generate": datetime.datetime(2000, 2, 1, 12, 30, 0, 0), + }, + }, + ) + + def test_date(self): + date = self.formatter.date.generate() + self.assertEqual( + date, + { + "json_class": "Pact::Term", + "json_class": "Pact::Term", + "data": { + "matcher": { + "json_class": "Regexp", + "s": self.formatter.Regexes.date.value, + "o": 0, + }, + "generate": datetime.datetime(2000, 2, 1, 12, 30, 0, 0).date(), + }, + }, + ) + + def test_time(self): + time = self.formatter.time.generate() + self.assertEqual( + time, + { + "json_class": "Pact::Term", + "json_class": "Pact::Term", + "data": { + "matcher": { + "json_class": "Regexp", + "s": self.formatter.Regexes.time_regex.value, + "o": 0, + }, + "generate": datetime.datetime(2000, 2, 1, 12, 30, 0, 0).time(), + }, + }, + ) From 5aaa82fdba2b4aa8360529e62102be6c45a317d3 Mon Sep 17 00:00:00 2001 From: Peter Yasi Date: Thu, 14 May 2020 18:46:42 -0400 Subject: [PATCH 4/9] README documentation --- README.md | 37 +++++++++++++++++++++++++++++++++++++ pact/matchers.py | 15 +++++++++++++-- tests/test_matchers.py | 36 ++++++++++++++++++++++++++++++++---- 3 files changed, 82 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 67b157f5c..1bc794231 100644 --- a/README.md +++ b/README.md @@ -249,6 +249,43 @@ from pact.matchers import get_generated_values self.assertEqual(result, get_generated_values(expected)) ``` +### Match common formats +Often times, you find yourself having to re-write regular expressions for common formats. + +```python +from pact.matchers import Format +Format().integer # Matches if the value is an integer +Format().ip_address # Matches if the value is a ip address +``` + +We've created a number of them for you to save you the time: + +| matcher | description | +|-----------------|-------------------------------------------------------------------------------------------------| +| `identifier` | Match an ID (e.g. 42) | +| `integer` | Match all numbers that are integers (both ints and longs) | +| `decimal` | Match all real numbers (floating point and decimal) | +| `hexadecimal` | Match all hexadecimal encoded strings | +| `date` | Match string containing basic ISO8601 dates (e.g. 2016-01-01) | +| `timestamp` | Match a string containing an RFC3339 formatted timestapm (e.g. Mon, 31 Oct 2016 15:21:41 -0400) | +| `time` | Match string containing times in ISO date format (e.g. T22:44:30.652Z) | +| `ip_address` | Match string containing IP4 formatted address | +| `ipv6_address` | Match string containing IP6 formatted address | +| `uuid` | Match strings containing UUIDs | + +These can be used to replace other matchers + +```python +from pact import Like, Term +Like({ + 'id': Format().integer, # integer + 'lastUpdated': Format().timestamp, # timestamp + 'location': { # dictionary + 'host': Format().ip_address # ip address + } +}) +``` + For more information see [Matching](https://docs.pact.io/getting_started/matching) ## Verifying Pacts Against a Service diff --git a/pact/matchers.py b/pact/matchers.py index c5878a88c..63899bb50 100644 --- a/pact/matchers.py +++ b/pact/matchers.py @@ -257,7 +257,9 @@ def __init__(self): """ Create a new Formatter """ - self.identifier = self.identifier() + self.identifier = self.integer_or_identifier() + self.integer = self.integer_or_identifier() + self.decimal = self.decimal() self.ip_address = self.ip_address() self.hexadecimal = self.hexadecimal() self.ipv6_address = self.ipv6_address() @@ -266,7 +268,7 @@ def __init__(self): self.date = self.date() self.time = self.time() - def identifier(self): + def integer_or_identifier(self): """ Matches any integer @@ -275,6 +277,15 @@ def identifier(self): """ return Like(1) + def decimal(self): + """ + Matches any decimal + + :return: a Like object with a decimal + :rtype: Like + """ + return Like(1.0) + def ip_address(self): """ Matches any ip address diff --git a/tests/test_matchers.py b/tests/test_matchers.py index 85dec6729..a64be292a 100644 --- a/tests/test_matchers.py +++ b/tests/test_matchers.py @@ -248,8 +248,34 @@ def setUpClass(cls): cls.formatter = Format() def test_identifier(self): - id = self.formatter.identifier.generate() - self.assertEqual(id, {"json_class": "Pact::SomethingLike", "contents": 1}) + identifier = self.formatter.identifier.generate() + self.assertEqual( + identifier, + { + "json_class": "Pact::SomethingLike", + "contents": 1 + } + ) + + def test_integer(self): + integer = self.formatter.integer.generate() + self.assertEqual( + integer, + { + "json_class": "Pact::SomethingLike", + "contents": 1 + } + ) + + def test_decimal(self): + decimal = self.formatter.integer.generate() + self.assertEqual( + decimal, + { + "json_class": "Pact::SomethingLike", + "contents": 1.0 + } + ) def test_ip_address(self): ip_address = self.formatter.ip_address.generate() @@ -354,7 +380,8 @@ def test_date(self): "s": self.formatter.Regexes.date.value, "o": 0, }, - "generate": datetime.datetime(2000, 2, 1, 12, 30, 0, 0).date(), + "generate": datetime.datetime( + 2000, 2, 1, 12, 30, 0, 0).date(), }, }, ) @@ -372,7 +399,8 @@ def test_time(self): "s": self.formatter.Regexes.time_regex.value, "o": 0, }, - "generate": datetime.datetime(2000, 2, 1, 12, 30, 0, 0).time(), + "generate": datetime.datetime( + 2000, 2, 1, 12, 30, 0, 0).time(), }, }, ) From fe068e50ecb62fba420ab2ff7f551f7582a1111a Mon Sep 17 00:00:00 2001 From: Peter Yasi Date: Thu, 14 May 2020 19:07:31 -0400 Subject: [PATCH 5/9] Add examples to e2e tests --- examples/e2e/pact_provider.py | 2 ++ examples/e2e/tests/test_user_consumer.py | 8 +++----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/e2e/pact_provider.py b/examples/e2e/pact_provider.py index aa43c3f41..2c0866ed4 100644 --- a/examples/e2e/pact_provider.py +++ b/examples/e2e/pact_provider.py @@ -20,11 +20,13 @@ def setup_no_user_a(): def setup_user_a_nonadmin(): id = '00000000-0000-4000-a000-000000000000' some_date = '2016-12-15T20:16:01' + ip_address = '198.0.0.1' fakedb['UserA'] = { 'name': "UserA", 'id': id, 'created_on': some_date, + 'ip_address': ip_address, 'admin': False } diff --git a/examples/e2e/tests/test_user_consumer.py b/examples/e2e/tests/test_user_consumer.py index 656b0dd6b..818f25971 100644 --- a/examples/e2e/tests/test_user_consumer.py +++ b/examples/e2e/tests/test_user_consumer.py @@ -8,6 +8,7 @@ import pytest from pact import Consumer, Like, Provider, Term +from pact.matchers import Format from ..src.consumer import UserConsumer @@ -76,14 +77,12 @@ def push_to_broker(version): def test_get_user_non_admin(pact, consumer): expected = { 'name': 'UserA', - 'id': Term( - r'^[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}\Z', # noqa: E501 - '00000000-0000-4000-a000-000000000000' - ), + 'id': Format().uuid, 'created_on': Term( r'\d+-\d+-\d+T\d+:\d+:\d+', '2016-12-15T20:16:01' ), + 'ip_address': Format().ip_address, 'admin': False } @@ -101,7 +100,6 @@ def test_get_user_non_admin(pact, consumer): # pact.verify() - def test_get_non_existing_user(pact, consumer): (pact .given('UserA does not exist') From 1fcc6c1f683a9cba72d678c7a825b05dd620498a Mon Sep 17 00:00:00 2001 From: Peter Yasi Date: Thu, 14 May 2020 19:49:23 -0400 Subject: [PATCH 6/9] Pydocstyle fixes, will still need fix for no enum in 2.7 --- examples/e2e/tests/test_user_consumer.py | 1 + pact/matchers.py | 42 ++++++++++++------------ 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/examples/e2e/tests/test_user_consumer.py b/examples/e2e/tests/test_user_consumer.py index 818f25971..08d028be1 100644 --- a/examples/e2e/tests/test_user_consumer.py +++ b/examples/e2e/tests/test_user_consumer.py @@ -100,6 +100,7 @@ def test_get_user_non_admin(pact, consumer): # pact.verify() + def test_get_non_existing_user(pact, consumer): (pact .given('UserA does not exist') diff --git a/pact/matchers.py b/pact/matchers.py index 63899bb50..90b930007 100644 --- a/pact/matchers.py +++ b/pact/matchers.py @@ -254,9 +254,7 @@ class Format: """ def __init__(self): - """ - Create a new Formatter - """ + """Create a new Formatter.""" self.identifier = self.integer_or_identifier() self.integer = self.integer_or_identifier() self.decimal = self.decimal() @@ -270,54 +268,54 @@ def __init__(self): def integer_or_identifier(self): """ - Matches any integer + Match any integer. - :return: a Like object with an integer + :return: a Like object with an integer. :rtype: Like """ return Like(1) def decimal(self): """ - Matches any decimal + Match any decimal. - :return: a Like object with a decimal + :return: a Like object with a decimal. :rtype: Like """ return Like(1.0) def ip_address(self): """ - Matches any ip address + Match any ip address. - :return: a Term object with an ip address regex + :return: a Term object with an ip address regex. :rtype: Term """ return Term(self.Regexes.ip_address.value, '127.0.0.1') def hexadecimal(self): """ - Matches any hexadecimal + Match any hexadecimal. - :return: a Term object with a hexdecimal regex + :return: a Term object with a hexdecimal regex. :rtype: Term """ return Term(self.Regexes.hexadecimal.value, '3F') def ipv6_address(self): """ - Matches any ipv6 address + Match any ipv6 address. - :return: a Term object with an ipv6 address regex + :return: a Term object with an ipv6 address regex. :rtype: Term """ return Term(self.Regexes.ipv6_address.value, '::ffff:192.0.2.128') def uuid(self): """ - Matches any uuid + Match any uuid. - :return: a Term object with a uuid regex + :return: a Term object with a uuid regex. :rtype: Term """ return Term( @@ -326,9 +324,9 @@ def uuid(self): def timestamp(self): """ - Matches any timestamp + Match any timestamp. - :return: a Term object with a timestamp regex + :return: a Term object with a timestamp regex. :rtype: Term """ return Term( @@ -339,9 +337,9 @@ def timestamp(self): def date(self): """ - Matches any date + Match any date. - :return: a Term object with a date regex + :return: a Term object with a date regex. :rtype: Term """ return Term( @@ -352,9 +350,9 @@ def date(self): def time(self): """ - Matches any time + Match any time. - :return: a Term object with a time regex + :return: a Term object with a time regex. :rtype: Term """ return Term( @@ -364,6 +362,8 @@ def time(self): ) class Regexes(Enum): + """Regex Enum for common formats.""" + ip_address = r'(\d{1,3}\.)+\d{1,3}' hexadecimal = r'[0-9a-fA-F]+' ipv6_address = r'(\A([0-9a-f]{1,4}:){1,1}(:[0-9a-f]{1,4}){1,6}\Z)|' \ From 35dfa0dfd5e122928ed9ef37e3c1d93151201d0c Mon Sep 17 00:00:00 2001 From: Peter Yasi Date: Thu, 14 May 2020 20:52:09 -0400 Subject: [PATCH 7/9] add enum34 a a dep for py27-install --- tox.ini | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 601856d48..6724ab49b 100644 --- a/tox.ini +++ b/tox.ini @@ -1,9 +1,10 @@ [tox] -envlist=py{27,34,35,36,37,38}-{test,install} +envlist=py{27}-{install} [testenv] deps= test: -rrequirements_dev.txt py27-test: subprocess32 + py27-install: enum34 commands= test: nosetests install: python -c "import pact" From cccd30a4ed40936701e7b3ca2e9d885a9dc1e3a4 Mon Sep 17 00:00:00 2001 From: Peter Yasi Date: Fri, 15 May 2020 08:55:57 -0400 Subject: [PATCH 8/9] Add Format to the standard pact package --- README.md | 4 +- examples/e2e/requirements.txt | 3 +- examples/e2e/tests/test_user_consumer.py | 5 +- .../tests/userserviceclient-userservice.json | 32 ------ pact/__init__.py | 4 +- setup.py | 1 + test.py | 0 tox.ini | 3 +- venv27/bin/activate | 84 +++++++++++++++ venv27/bin/activate.csh | 55 ++++++++++ venv27/bin/activate.fish | 102 ++++++++++++++++++ venv27/bin/activate.ps1 | 60 +++++++++++ venv27/bin/activate_this.py | 46 ++++++++ venv27/bin/chardetect | 8 ++ venv27/bin/easy_install | 10 ++ venv27/bin/easy_install-2.7 | 10 ++ venv27/bin/pact-verifier | 12 +++ venv27/bin/pip | 10 ++ venv27/bin/pip2 | 10 ++ venv27/bin/pip2.7 | 10 ++ venv27/bin/python | Bin 0 -> 51744 bytes venv27/bin/python-config | 78 ++++++++++++++ venv27/bin/python2 | 1 + venv27/bin/python2.7 | 1 + venv27/bin/wheel | 10 ++ venv27/include/python2.7 | 1 + 26 files changed, 518 insertions(+), 42 deletions(-) create mode 100644 test.py create mode 100644 venv27/bin/activate create mode 100644 venv27/bin/activate.csh create mode 100644 venv27/bin/activate.fish create mode 100644 venv27/bin/activate.ps1 create mode 100644 venv27/bin/activate_this.py create mode 100755 venv27/bin/chardetect create mode 100755 venv27/bin/easy_install create mode 100755 venv27/bin/easy_install-2.7 create mode 100755 venv27/bin/pact-verifier create mode 100755 venv27/bin/pip create mode 100755 venv27/bin/pip2 create mode 100755 venv27/bin/pip2.7 create mode 100755 venv27/bin/python create mode 100755 venv27/bin/python-config create mode 120000 venv27/bin/python2 create mode 120000 venv27/bin/python2.7 create mode 100755 venv27/bin/wheel create mode 120000 venv27/include/python2.7 diff --git a/README.md b/README.md index 1bc794231..c4fb16e44 100644 --- a/README.md +++ b/README.md @@ -253,7 +253,7 @@ self.assertEqual(result, get_generated_values(expected)) Often times, you find yourself having to re-write regular expressions for common formats. ```python -from pact.matchers import Format +from pact import Format Format().integer # Matches if the value is an integer Format().ip_address # Matches if the value is a ip address ``` @@ -276,7 +276,7 @@ We've created a number of them for you to save you the time: These can be used to replace other matchers ```python -from pact import Like, Term +from pact import Like, Format Like({ 'id': Format().integer, # integer 'lastUpdated': Format().timestamp, # timestamp diff --git a/examples/e2e/requirements.txt b/examples/e2e/requirements.txt index 0ebb5bef9..b24bb4157 100644 --- a/examples/e2e/requirements.txt +++ b/examples/e2e/requirements.txt @@ -2,6 +2,7 @@ attrs==19.3.0 certifi==2019.11.28 chardet==3.0.4 click==7.1.1 +enum34==1.1.10 Flask==1.1.1 idna==2.9 importlib-metadata==1.6.0 @@ -13,7 +14,7 @@ packaging==20.3 pluggy==0.13.1 psutil==5.7.0 py==1.8.1 -pyparsing==2.4.6 +pyparsing==2.4.6f pytest==5.4.1 requests==2.23.0 six==1.14.0 diff --git a/examples/e2e/tests/test_user_consumer.py b/examples/e2e/tests/test_user_consumer.py index 08d028be1..d2410214c 100644 --- a/examples/e2e/tests/test_user_consumer.py +++ b/examples/e2e/tests/test_user_consumer.py @@ -7,14 +7,13 @@ from requests.auth import HTTPBasicAuth import pytest -from pact import Consumer, Like, Provider, Term -from pact.matchers import Format +from pact import Consumer, Like, Provider, Term, Format from ..src.consumer import UserConsumer log = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) - +print(Format().__dict__) PACT_UPLOAD_URL = ( "http://127.0.0.1/pacts/provider/UserService/consumer" diff --git a/examples/e2e/tests/userserviceclient-userservice.json b/examples/e2e/tests/userserviceclient-userservice.json index 5c29a5a46..da96547a9 100644 --- a/examples/e2e/tests/userserviceclient-userservice.json +++ b/examples/e2e/tests/userserviceclient-userservice.json @@ -6,38 +6,6 @@ "name": "UserService" }, "interactions": [ - { - "description": "a request for UserA", - "providerState": "UserA exists and is not an administrator", - "request": { - "method": "get", - "path": "/users/UserA" - }, - "response": { - "status": 200, - "headers": { - }, - "body": { - "name": "UserA", - "id": "00000000-0000-4000-a000-000000000000", - "created_on": "2016-12-15T20:16:01", - "admin": false - }, - "matchingRules": { - "$.body": { - "match": "type" - }, - "$.body.id": { - "match": "regex", - "regex": "^[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}\\Z" - }, - "$.body.created_on": { - "match": "regex", - "regex": "\\d+-\\d+-\\d+T\\d+:\\d+:\\d+" - } - } - } - }, { "description": "a request for UserA", "providerState": "UserA does not exist", diff --git a/pact/__init__.py b/pact/__init__.py index 31fc70948..bd27f6a28 100644 --- a/pact/__init__.py +++ b/pact/__init__.py @@ -1,9 +1,9 @@ """Python methods for interactive with a Pact Mock Service.""" from .consumer import Consumer -from .matchers import EachLike, Like, SomethingLike, Term +from .matchers import EachLike, Like, SomethingLike, Term, Format from .pact import Pact from .provider import Provider from .__version__ import __version__ # noqa: F401 __all__ = ('Consumer', 'EachLike', 'Like', 'Pact', 'Provider', 'SomethingLike', - 'Term') + 'Term', 'Format') diff --git a/setup.py b/setup.py index fd5127a7c..2826d7bd9 100644 --- a/setup.py +++ b/setup.py @@ -117,6 +117,7 @@ def read(filename): if sys.version_info.major == 2: dependencies.append('subprocess32') + dependencies.append('enum34') if __name__ == '__main__': setup( diff --git a/test.py b/test.py new file mode 100644 index 000000000..e69de29bb diff --git a/tox.ini b/tox.ini index 6724ab49b..601856d48 100644 --- a/tox.ini +++ b/tox.ini @@ -1,10 +1,9 @@ [tox] -envlist=py{27}-{install} +envlist=py{27,34,35,36,37,38}-{test,install} [testenv] deps= test: -rrequirements_dev.txt py27-test: subprocess32 - py27-install: enum34 commands= test: nosetests install: python -c "import pact" diff --git a/venv27/bin/activate b/venv27/bin/activate new file mode 100644 index 000000000..62b344a48 --- /dev/null +++ b/venv27/bin/activate @@ -0,0 +1,84 @@ +# This file must be used with "source bin/activate" *from bash* +# you cannot run it directly + + +if [ "${BASH_SOURCE-}" = "$0" ]; then + echo "You must source this script: \$ source $0" >&2 + exit 33 +fi + +deactivate () { + unset -f pydoc >/dev/null 2>&1 + + # reset old environment variables + # ! [ -z ${VAR+_} ] returns true if VAR is declared at all + if ! [ -z "${_OLD_VIRTUAL_PATH:+_}" ] ; then + PATH="$_OLD_VIRTUAL_PATH" + export PATH + unset _OLD_VIRTUAL_PATH + fi + if ! [ -z "${_OLD_VIRTUAL_PYTHONHOME+_}" ] ; then + PYTHONHOME="$_OLD_VIRTUAL_PYTHONHOME" + export PYTHONHOME + unset _OLD_VIRTUAL_PYTHONHOME + fi + + # This should detect bash and zsh, which have a hash command that must + # be called to get it to forget past commands. Without forgetting + # past commands the $PATH changes we made may not be respected + if [ -n "${BASH-}" ] || [ -n "${ZSH_VERSION-}" ] ; then + hash -r 2>/dev/null + fi + + if ! [ -z "${_OLD_VIRTUAL_PS1+_}" ] ; then + PS1="$_OLD_VIRTUAL_PS1" + export PS1 + unset _OLD_VIRTUAL_PS1 + fi + + unset VIRTUAL_ENV + if [ ! "${1-}" = "nondestructive" ] ; then + # Self destruct! + unset -f deactivate + fi +} + +# unset irrelevant variables +deactivate nondestructive + +VIRTUAL_ENV="/Users/py356p/codebase/pact-python/venv27" +export VIRTUAL_ENV + +_OLD_VIRTUAL_PATH="$PATH" +PATH="$VIRTUAL_ENV/bin:$PATH" +export PATH + +# unset PYTHONHOME if set +if ! [ -z "${PYTHONHOME+_}" ] ; then + _OLD_VIRTUAL_PYTHONHOME="$PYTHONHOME" + unset PYTHONHOME +fi + +if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT-}" ] ; then + _OLD_VIRTUAL_PS1="${PS1-}" + if [ "x" != x ] ; then + PS1="${PS1-}" + else + PS1="(`basename \"$VIRTUAL_ENV\"`) ${PS1-}" + fi + export PS1 +fi + +# Make sure to unalias pydoc if it's already there +alias pydoc 2>/dev/null >/dev/null && unalias pydoc || true + +pydoc () { + python -m pydoc "$@" +} + +# This should detect bash and zsh, which have a hash command that must +# be called to get it to forget past commands. Without forgetting +# past commands the $PATH changes we made may not be respected +if [ -n "${BASH-}" ] || [ -n "${ZSH_VERSION-}" ] ; then + hash -r 2>/dev/null +fi diff --git a/venv27/bin/activate.csh b/venv27/bin/activate.csh new file mode 100644 index 000000000..d51864225 --- /dev/null +++ b/venv27/bin/activate.csh @@ -0,0 +1,55 @@ +# This file must be used with "source bin/activate.csh" *from csh*. +# You cannot run it directly. +# Created by Davide Di Blasi . + +set newline='\ +' + +alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH:q" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT:q" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; test "\!:*" != "nondestructive" && unalias deactivate && unalias pydoc' + +# Unset irrelevant variables. +deactivate nondestructive + +setenv VIRTUAL_ENV "/Users/py356p/codebase/pact-python/venv27" + +set _OLD_VIRTUAL_PATH="$PATH:q" +setenv PATH "$VIRTUAL_ENV:q/bin:$PATH:q" + + + +if ("" != "") then + set env_name = "" +else + set env_name = '('"$VIRTUAL_ENV:t:q"') ' +endif + +if ( $?VIRTUAL_ENV_DISABLE_PROMPT ) then + if ( $VIRTUAL_ENV_DISABLE_PROMPT == "" ) then + set do_prompt = "1" + else + set do_prompt = "0" + endif +else + set do_prompt = "1" +endif + +if ( $do_prompt == "1" ) then + # Could be in a non-interactive environment, + # in which case, $prompt is undefined and we wouldn't + # care about the prompt anyway. + if ( $?prompt ) then + set _OLD_VIRTUAL_PROMPT="$prompt:q" + if ( "$prompt:q" =~ *"$newline:q"* ) then + : + else + set prompt = "$env_name:q$prompt:q" + endif + endif +endif + +unset env_name +unset do_prompt + +alias pydoc python -m pydoc + +rehash diff --git a/venv27/bin/activate.fish b/venv27/bin/activate.fish new file mode 100644 index 000000000..a4dd5fa69 --- /dev/null +++ b/venv27/bin/activate.fish @@ -0,0 +1,102 @@ +# This file must be used using `source bin/activate.fish` *within a running fish ( http://fishshell.com ) session*. +# Do not run it directly. + +function _bashify_path -d "Converts a fish path to something bash can recognize" + set fishy_path $argv + set bashy_path $fishy_path[1] + for path_part in $fishy_path[2..-1] + set bashy_path "$bashy_path:$path_part" + end + echo $bashy_path +end + +function _fishify_path -d "Converts a bash path to something fish can recognize" + echo $argv | tr ':' '\n' +end + +function deactivate -d 'Exit virtualenv mode and return to the normal environment.' + # reset old environment variables + if test -n "$_OLD_VIRTUAL_PATH" + # https://github.com/fish-shell/fish-shell/issues/436 altered PATH handling + if test (echo $FISH_VERSION | tr "." "\n")[1] -lt 3 + set -gx PATH (_fishify_path $_OLD_VIRTUAL_PATH) + else + set -gx PATH $_OLD_VIRTUAL_PATH + end + set -e _OLD_VIRTUAL_PATH + end + + if test -n "$_OLD_VIRTUAL_PYTHONHOME" + set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME + set -e _OLD_VIRTUAL_PYTHONHOME + end + + if test -n "$_OLD_FISH_PROMPT_OVERRIDE" + and functions -q _old_fish_prompt + # Set an empty local `$fish_function_path` to allow the removal of `fish_prompt` using `functions -e`. + set -l fish_function_path + + # Erase virtualenv's `fish_prompt` and restore the original. + functions -e fish_prompt + functions -c _old_fish_prompt fish_prompt + functions -e _old_fish_prompt + set -e _OLD_FISH_PROMPT_OVERRIDE + end + + set -e VIRTUAL_ENV + + if test "$argv[1]" != 'nondestructive' + # Self-destruct! + functions -e pydoc + functions -e deactivate + functions -e _bashify_path + functions -e _fishify_path + end +end + +# Unset irrelevant variables. +deactivate nondestructive + +set -gx VIRTUAL_ENV "/Users/py356p/codebase/pact-python/venv27" + +# https://github.com/fish-shell/fish-shell/issues/436 altered PATH handling +if test (echo $FISH_VERSION | tr "." "\n")[1] -lt 3 + set -gx _OLD_VIRTUAL_PATH (_bashify_path $PATH) +else + set -gx _OLD_VIRTUAL_PATH $PATH +end +set -gx PATH "$VIRTUAL_ENV/bin" $PATH + +# Unset `$PYTHONHOME` if set. +if set -q PYTHONHOME + set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME + set -e PYTHONHOME +end + +function pydoc + python -m pydoc $argv +end + +if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" + # Copy the current `fish_prompt` function as `_old_fish_prompt`. + functions -c fish_prompt _old_fish_prompt + + function fish_prompt + # Save the current $status, for fish_prompts that display it. + set -l old_status $status + + # Prompt override provided? + # If not, just prepend the environment name. + if test -n "" + printf '%s%s' "" (set_color normal) + else + printf '%s(%s) ' (set_color normal) (basename "$VIRTUAL_ENV") + end + + # Restore the original $status + echo "exit $old_status" | source + _old_fish_prompt + end + + set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" +end diff --git a/venv27/bin/activate.ps1 b/venv27/bin/activate.ps1 new file mode 100644 index 000000000..95504d395 --- /dev/null +++ b/venv27/bin/activate.ps1 @@ -0,0 +1,60 @@ +$script:THIS_PATH = $myinvocation.mycommand.path +$script:BASE_DIR = Split-Path (Resolve-Path "$THIS_PATH/..") -Parent + +function global:deactivate([switch] $NonDestructive) { + if (Test-Path variable:_OLD_VIRTUAL_PATH) { + $env:PATH = $variable:_OLD_VIRTUAL_PATH + Remove-Variable "_OLD_VIRTUAL_PATH" -Scope global + } + + if (Test-Path function:_old_virtual_prompt) { + $function:prompt = $function:_old_virtual_prompt + Remove-Item function:\_old_virtual_prompt + } + + if ($env:VIRTUAL_ENV) { + Remove-Item env:VIRTUAL_ENV -ErrorAction SilentlyContinue + } + + if (!$NonDestructive) { + # Self destruct! + Remove-Item function:deactivate + Remove-Item function:pydoc + } +} + +function global:pydoc { + python -m pydoc $args +} + +# unset irrelevant variables +deactivate -nondestructive + +$VIRTUAL_ENV = $BASE_DIR +$env:VIRTUAL_ENV = $VIRTUAL_ENV + +New-Variable -Scope global -Name _OLD_VIRTUAL_PATH -Value $env:PATH + +$env:PATH = "$env:VIRTUAL_ENV/bin:" + $env:PATH +if (!$env:VIRTUAL_ENV_DISABLE_PROMPT) { + function global:_old_virtual_prompt { + "" + } + $function:_old_virtual_prompt = $function:prompt + + if ("" -ne "") { + function global:prompt { + # Add the custom prefix to the existing prompt + $previous_prompt_value = & $function:_old_virtual_prompt + ("" + $previous_prompt_value) + } + } + else { + function global:prompt { + # Add a prefix to the current prompt, but don't discard it. + $previous_prompt_value = & $function:_old_virtual_prompt + $new_prompt_value = "($( Split-Path $env:VIRTUAL_ENV -Leaf )) " + ($new_prompt_value + $previous_prompt_value) + } + } +} diff --git a/venv27/bin/activate_this.py b/venv27/bin/activate_this.py new file mode 100644 index 000000000..aa96457f2 --- /dev/null +++ b/venv27/bin/activate_this.py @@ -0,0 +1,46 @@ +"""Activate virtualenv for current interpreter: + +Use exec(open(this_file).read(), {'__file__': this_file}). + +This can be used when you must use an existing Python interpreter, not the virtualenv bin/python. +""" +import os +import site +import sys + +try: + __file__ +except NameError: + raise AssertionError("You must use exec(open(this_file).read(), {'__file__': this_file}))") + +# prepend bin to PATH (this file is inside the bin directory) +bin_dir = os.path.dirname(os.path.abspath(__file__)) +os.environ["PATH"] = os.pathsep.join([bin_dir] + os.environ.get("PATH", "").split(os.pathsep)) + +base = os.path.dirname(bin_dir) + +# virtual env is right above bin directory +os.environ["VIRTUAL_ENV"] = base + +# add the virtual environments site-package to the host python import mechanism +IS_PYPY = hasattr(sys, "pypy_version_info") +IS_JYTHON = sys.platform.startswith("java") +if IS_JYTHON: + site_packages = os.path.join(base, "Lib", "site-packages") +elif IS_PYPY: + site_packages = os.path.join(base, "site-packages") +else: + IS_WIN = sys.platform == "win32" + if IS_WIN: + site_packages = os.path.join(base, "Lib", "site-packages") + else: + site_packages = os.path.join(base, "lib", "python{}.{}".format(*sys.version_info), "site-packages") + +prev = set(sys.path) +site.addsitedir(site_packages) +sys.real_prefix = sys.prefix +sys.prefix = base + +# Move the added items to the front of the path, in place +new = list(sys.path) +sys.path[:] = [i for i in new if i not in prev] + [i for i in new if i in prev] diff --git a/venv27/bin/chardetect b/venv27/bin/chardetect new file mode 100755 index 000000000..ac4d99aca --- /dev/null +++ b/venv27/bin/chardetect @@ -0,0 +1,8 @@ +#!/Users/py356p/codebase/pact-python/venv27/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from chardet.cli.chardetect import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv27/bin/easy_install b/venv27/bin/easy_install new file mode 100755 index 000000000..2205b4573 --- /dev/null +++ b/venv27/bin/easy_install @@ -0,0 +1,10 @@ +#!/Users/py356p/codebase/pact-python/venv27/bin/python +# -*- coding: utf-8 -*- +import re +import sys + +from setuptools.command.easy_install import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv27/bin/easy_install-2.7 b/venv27/bin/easy_install-2.7 new file mode 100755 index 000000000..2205b4573 --- /dev/null +++ b/venv27/bin/easy_install-2.7 @@ -0,0 +1,10 @@ +#!/Users/py356p/codebase/pact-python/venv27/bin/python +# -*- coding: utf-8 -*- +import re +import sys + +from setuptools.command.easy_install import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv27/bin/pact-verifier b/venv27/bin/pact-verifier new file mode 100755 index 000000000..80948a3c2 --- /dev/null +++ b/venv27/bin/pact-verifier @@ -0,0 +1,12 @@ +#!/Users/py356p/codebase/pact-python/venv27/bin/python +# EASY-INSTALL-ENTRY-SCRIPT: 'pact-python','console_scripts','pact-verifier' +__requires__ = 'pact-python' +import re +import sys +from pkg_resources import load_entry_point + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit( + load_entry_point('pact-python', 'console_scripts', 'pact-verifier')() + ) diff --git a/venv27/bin/pip b/venv27/bin/pip new file mode 100755 index 000000000..6381bbfd5 --- /dev/null +++ b/venv27/bin/pip @@ -0,0 +1,10 @@ +#!/Users/py356p/codebase/pact-python/venv27/bin/python +# -*- coding: utf-8 -*- +import re +import sys + +from pip._internal.cli.main import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv27/bin/pip2 b/venv27/bin/pip2 new file mode 100755 index 000000000..6381bbfd5 --- /dev/null +++ b/venv27/bin/pip2 @@ -0,0 +1,10 @@ +#!/Users/py356p/codebase/pact-python/venv27/bin/python +# -*- coding: utf-8 -*- +import re +import sys + +from pip._internal.cli.main import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv27/bin/pip2.7 b/venv27/bin/pip2.7 new file mode 100755 index 000000000..6381bbfd5 --- /dev/null +++ b/venv27/bin/pip2.7 @@ -0,0 +1,10 @@ +#!/Users/py356p/codebase/pact-python/venv27/bin/python +# -*- coding: utf-8 -*- +import re +import sys + +from pip._internal.cli.main import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv27/bin/python b/venv27/bin/python new file mode 100755 index 0000000000000000000000000000000000000000..542eddcc6396c5372a2a538133f3b0ec9363c530 GIT binary patch literal 51744 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 (3, 2): + valid_opts.insert(-1, 'extension-suffix') + valid_opts.append('abiflags') +if sys.version_info >= (3, 3): + valid_opts.append('configdir') + + +def exit_with_usage(code=1): + sys.stderr.write("Usage: {0} [{1}]\n".format( + sys.argv[0], '|'.join('--'+opt for opt in valid_opts))) + sys.exit(code) + +try: + opts, args = getopt.getopt(sys.argv[1:], '', valid_opts) +except getopt.error: + exit_with_usage() + +if not opts: + exit_with_usage() + +pyver = sysconfig.get_config_var('VERSION') +getvar = sysconfig.get_config_var + +opt_flags = [flag for (flag, val) in opts] + +if '--help' in opt_flags: + exit_with_usage(code=0) + +for opt in opt_flags: + if opt == '--prefix': + print(sysconfig.get_config_var('prefix')) + + elif opt == '--exec-prefix': + print(sysconfig.get_config_var('exec_prefix')) + + elif opt in ('--includes', '--cflags'): + flags = ['-I' + sysconfig.get_path('include'), + '-I' + sysconfig.get_path('platinclude')] + if opt == '--cflags': + flags.extend(getvar('CFLAGS').split()) + print(' '.join(flags)) + + elif opt in ('--libs', '--ldflags'): + abiflags = getattr(sys, 'abiflags', '') + libs = ['-lpython' + pyver + abiflags] + libs += getvar('LIBS').split() + libs += getvar('SYSLIBS').split() + # add the prefix/lib/pythonX.Y/config dir, but only if there is no + # shared library in prefix/lib/. + if opt == '--ldflags': + if not getvar('Py_ENABLE_SHARED'): + libs.insert(0, '-L' + getvar('LIBPL')) + if not getvar('PYTHONFRAMEWORK'): + libs.extend(getvar('LINKFORSHARED').split()) + print(' '.join(libs)) + + elif opt == '--extension-suffix': + ext_suffix = sysconfig.get_config_var('EXT_SUFFIX') + if ext_suffix is None: + ext_suffix = sysconfig.get_config_var('SO') + print(ext_suffix) + + elif opt == '--abiflags': + if not getattr(sys, 'abiflags', None): + exit_with_usage() + print(sys.abiflags) + + elif opt == '--configdir': + print(sysconfig.get_config_var('LIBPL')) diff --git a/venv27/bin/python2 b/venv27/bin/python2 new file mode 120000 index 000000000..d8654aa0e --- /dev/null +++ b/venv27/bin/python2 @@ -0,0 +1 @@ +python \ No newline at end of file diff --git a/venv27/bin/python2.7 b/venv27/bin/python2.7 new file mode 120000 index 000000000..d8654aa0e --- /dev/null +++ b/venv27/bin/python2.7 @@ -0,0 +1 @@ +python \ No newline at end of file diff --git a/venv27/bin/wheel b/venv27/bin/wheel new file mode 100755 index 000000000..1fc646aeb --- /dev/null +++ b/venv27/bin/wheel @@ -0,0 +1,10 @@ +#!/Users/py356p/codebase/pact-python/venv27/bin/python +# -*- coding: utf-8 -*- +import re +import sys + +from wheel.cli import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv27/include/python2.7 b/venv27/include/python2.7 new file mode 120000 index 000000000..3fe034fcc --- /dev/null +++ b/venv27/include/python2.7 @@ -0,0 +1 @@ +/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 \ No newline at end of file From db39d870dade97f8f53b45cac48a457935a75b53 Mon Sep 17 00:00:00 2001 From: Peter Yasi Date: Fri, 15 May 2020 09:02:01 -0400 Subject: [PATCH 9/9] remove virtualenv --- .../tests/userserviceclient-userservice.json | 32 ++++++ test.py | 0 venv27/bin/activate | 84 --------------- venv27/bin/activate.csh | 55 ---------- venv27/bin/activate.fish | 102 ------------------ venv27/bin/activate.ps1 | 60 ----------- venv27/bin/activate_this.py | 46 -------- venv27/bin/chardetect | 8 -- venv27/bin/easy_install | 10 -- venv27/bin/easy_install-2.7 | 10 -- venv27/bin/pact-verifier | 12 --- venv27/bin/pip | 10 -- venv27/bin/pip2 | 10 -- venv27/bin/pip2.7 | 10 -- venv27/bin/python | Bin 51744 -> 0 bytes venv27/bin/python-config | 78 -------------- venv27/bin/python2 | 1 - venv27/bin/python2.7 | 1 - venv27/bin/wheel | 10 -- venv27/include/python2.7 | 1 - 20 files changed, 32 insertions(+), 508 deletions(-) delete mode 100644 test.py delete mode 100644 venv27/bin/activate delete mode 100644 venv27/bin/activate.csh delete mode 100644 venv27/bin/activate.fish delete mode 100644 venv27/bin/activate.ps1 delete mode 100644 venv27/bin/activate_this.py delete mode 100755 venv27/bin/chardetect delete mode 100755 venv27/bin/easy_install delete mode 100755 venv27/bin/easy_install-2.7 delete mode 100755 venv27/bin/pact-verifier delete mode 100755 venv27/bin/pip delete mode 100755 venv27/bin/pip2 delete mode 100755 venv27/bin/pip2.7 delete mode 100755 venv27/bin/python delete mode 100755 venv27/bin/python-config delete mode 120000 venv27/bin/python2 delete mode 120000 venv27/bin/python2.7 delete mode 100755 venv27/bin/wheel delete mode 120000 venv27/include/python2.7 diff --git a/examples/e2e/tests/userserviceclient-userservice.json b/examples/e2e/tests/userserviceclient-userservice.json index da96547a9..5c29a5a46 100644 --- a/examples/e2e/tests/userserviceclient-userservice.json +++ b/examples/e2e/tests/userserviceclient-userservice.json @@ -6,6 +6,38 @@ "name": "UserService" }, "interactions": [ + { + "description": "a request for UserA", + "providerState": "UserA exists and is not an administrator", + "request": { + "method": "get", + "path": "/users/UserA" + }, + "response": { + "status": 200, + "headers": { + }, + "body": { + "name": "UserA", + "id": "00000000-0000-4000-a000-000000000000", + "created_on": "2016-12-15T20:16:01", + "admin": false + }, + "matchingRules": { + "$.body": { + "match": "type" + }, + "$.body.id": { + "match": "regex", + "regex": "^[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}\\Z" + }, + "$.body.created_on": { + "match": "regex", + "regex": "\\d+-\\d+-\\d+T\\d+:\\d+:\\d+" + } + } + } + }, { "description": "a request for UserA", "providerState": "UserA does not exist", diff --git a/test.py b/test.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/venv27/bin/activate b/venv27/bin/activate deleted file mode 100644 index 62b344a48..000000000 --- a/venv27/bin/activate +++ /dev/null @@ -1,84 +0,0 @@ -# This file must be used with "source bin/activate" *from bash* -# you cannot run it directly - - -if [ "${BASH_SOURCE-}" = "$0" ]; then - echo "You must source this script: \$ source $0" >&2 - exit 33 -fi - -deactivate () { - unset -f pydoc >/dev/null 2>&1 - - # reset old environment variables - # ! [ -z ${VAR+_} ] returns true if VAR is declared at all - if ! [ -z "${_OLD_VIRTUAL_PATH:+_}" ] ; then - PATH="$_OLD_VIRTUAL_PATH" - export PATH - unset _OLD_VIRTUAL_PATH - fi - if ! [ -z "${_OLD_VIRTUAL_PYTHONHOME+_}" ] ; then - PYTHONHOME="$_OLD_VIRTUAL_PYTHONHOME" - export PYTHONHOME - unset _OLD_VIRTUAL_PYTHONHOME - fi - - # This should detect bash and zsh, which have a hash command that must - # be called to get it to forget past commands. Without forgetting - # past commands the $PATH changes we made may not be respected - if [ -n "${BASH-}" ] || [ -n "${ZSH_VERSION-}" ] ; then - hash -r 2>/dev/null - fi - - if ! [ -z "${_OLD_VIRTUAL_PS1+_}" ] ; then - PS1="$_OLD_VIRTUAL_PS1" - export PS1 - unset _OLD_VIRTUAL_PS1 - fi - - unset VIRTUAL_ENV - if [ ! "${1-}" = "nondestructive" ] ; then - # Self destruct! - unset -f deactivate - fi -} - -# unset irrelevant variables -deactivate nondestructive - -VIRTUAL_ENV="/Users/py356p/codebase/pact-python/venv27" -export VIRTUAL_ENV - -_OLD_VIRTUAL_PATH="$PATH" -PATH="$VIRTUAL_ENV/bin:$PATH" -export PATH - -# unset PYTHONHOME if set -if ! [ -z "${PYTHONHOME+_}" ] ; then - _OLD_VIRTUAL_PYTHONHOME="$PYTHONHOME" - unset PYTHONHOME -fi - -if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT-}" ] ; then - _OLD_VIRTUAL_PS1="${PS1-}" - if [ "x" != x ] ; then - PS1="${PS1-}" - else - PS1="(`basename \"$VIRTUAL_ENV\"`) ${PS1-}" - fi - export PS1 -fi - -# Make sure to unalias pydoc if it's already there -alias pydoc 2>/dev/null >/dev/null && unalias pydoc || true - -pydoc () { - python -m pydoc "$@" -} - -# This should detect bash and zsh, which have a hash command that must -# be called to get it to forget past commands. Without forgetting -# past commands the $PATH changes we made may not be respected -if [ -n "${BASH-}" ] || [ -n "${ZSH_VERSION-}" ] ; then - hash -r 2>/dev/null -fi diff --git a/venv27/bin/activate.csh b/venv27/bin/activate.csh deleted file mode 100644 index d51864225..000000000 --- a/venv27/bin/activate.csh +++ /dev/null @@ -1,55 +0,0 @@ -# This file must be used with "source bin/activate.csh" *from csh*. -# You cannot run it directly. -# Created by Davide Di Blasi . - -set newline='\ -' - -alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH:q" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT:q" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; test "\!:*" != "nondestructive" && unalias deactivate && unalias pydoc' - -# Unset irrelevant variables. -deactivate nondestructive - -setenv VIRTUAL_ENV "/Users/py356p/codebase/pact-python/venv27" - -set _OLD_VIRTUAL_PATH="$PATH:q" -setenv PATH "$VIRTUAL_ENV:q/bin:$PATH:q" - - - -if ("" != "") then - set env_name = "" -else - set env_name = '('"$VIRTUAL_ENV:t:q"') ' -endif - -if ( $?VIRTUAL_ENV_DISABLE_PROMPT ) then - if ( $VIRTUAL_ENV_DISABLE_PROMPT == "" ) then - set do_prompt = "1" - else - set do_prompt = "0" - endif -else - set do_prompt = "1" -endif - -if ( $do_prompt == "1" ) then - # Could be in a non-interactive environment, - # in which case, $prompt is undefined and we wouldn't - # care about the prompt anyway. - if ( $?prompt ) then - set _OLD_VIRTUAL_PROMPT="$prompt:q" - if ( "$prompt:q" =~ *"$newline:q"* ) then - : - else - set prompt = "$env_name:q$prompt:q" - endif - endif -endif - -unset env_name -unset do_prompt - -alias pydoc python -m pydoc - -rehash diff --git a/venv27/bin/activate.fish b/venv27/bin/activate.fish deleted file mode 100644 index a4dd5fa69..000000000 --- a/venv27/bin/activate.fish +++ /dev/null @@ -1,102 +0,0 @@ -# This file must be used using `source bin/activate.fish` *within a running fish ( http://fishshell.com ) session*. -# Do not run it directly. - -function _bashify_path -d "Converts a fish path to something bash can recognize" - set fishy_path $argv - set bashy_path $fishy_path[1] - for path_part in $fishy_path[2..-1] - set bashy_path "$bashy_path:$path_part" - end - echo $bashy_path -end - -function _fishify_path -d "Converts a bash path to something fish can recognize" - echo $argv | tr ':' '\n' -end - -function deactivate -d 'Exit virtualenv mode and return to the normal environment.' - # reset old environment variables - if test -n "$_OLD_VIRTUAL_PATH" - # https://github.com/fish-shell/fish-shell/issues/436 altered PATH handling - if test (echo $FISH_VERSION | tr "." "\n")[1] -lt 3 - set -gx PATH (_fishify_path $_OLD_VIRTUAL_PATH) - else - set -gx PATH $_OLD_VIRTUAL_PATH - end - set -e _OLD_VIRTUAL_PATH - end - - if test -n "$_OLD_VIRTUAL_PYTHONHOME" - set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME - set -e _OLD_VIRTUAL_PYTHONHOME - end - - if test -n "$_OLD_FISH_PROMPT_OVERRIDE" - and functions -q _old_fish_prompt - # Set an empty local `$fish_function_path` to allow the removal of `fish_prompt` using `functions -e`. - set -l fish_function_path - - # Erase virtualenv's `fish_prompt` and restore the original. - functions -e fish_prompt - functions -c _old_fish_prompt fish_prompt - functions -e _old_fish_prompt - set -e _OLD_FISH_PROMPT_OVERRIDE - end - - set -e VIRTUAL_ENV - - if test "$argv[1]" != 'nondestructive' - # Self-destruct! - functions -e pydoc - functions -e deactivate - functions -e _bashify_path - functions -e _fishify_path - end -end - -# Unset irrelevant variables. -deactivate nondestructive - -set -gx VIRTUAL_ENV "/Users/py356p/codebase/pact-python/venv27" - -# https://github.com/fish-shell/fish-shell/issues/436 altered PATH handling -if test (echo $FISH_VERSION | tr "." "\n")[1] -lt 3 - set -gx _OLD_VIRTUAL_PATH (_bashify_path $PATH) -else - set -gx _OLD_VIRTUAL_PATH $PATH -end -set -gx PATH "$VIRTUAL_ENV/bin" $PATH - -# Unset `$PYTHONHOME` if set. -if set -q PYTHONHOME - set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME - set -e PYTHONHOME -end - -function pydoc - python -m pydoc $argv -end - -if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" - # Copy the current `fish_prompt` function as `_old_fish_prompt`. - functions -c fish_prompt _old_fish_prompt - - function fish_prompt - # Save the current $status, for fish_prompts that display it. - set -l old_status $status - - # Prompt override provided? - # If not, just prepend the environment name. - if test -n "" - printf '%s%s' "" (set_color normal) - else - printf '%s(%s) ' (set_color normal) (basename "$VIRTUAL_ENV") - end - - # Restore the original $status - echo "exit $old_status" | source - _old_fish_prompt - end - - set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" -end diff --git a/venv27/bin/activate.ps1 b/venv27/bin/activate.ps1 deleted file mode 100644 index 95504d395..000000000 --- a/venv27/bin/activate.ps1 +++ /dev/null @@ -1,60 +0,0 @@ -$script:THIS_PATH = $myinvocation.mycommand.path -$script:BASE_DIR = Split-Path (Resolve-Path "$THIS_PATH/..") -Parent - -function global:deactivate([switch] $NonDestructive) { - if (Test-Path variable:_OLD_VIRTUAL_PATH) { - $env:PATH = $variable:_OLD_VIRTUAL_PATH - Remove-Variable "_OLD_VIRTUAL_PATH" -Scope global - } - - if (Test-Path function:_old_virtual_prompt) { - $function:prompt = $function:_old_virtual_prompt - Remove-Item function:\_old_virtual_prompt - } - - if ($env:VIRTUAL_ENV) { - Remove-Item env:VIRTUAL_ENV -ErrorAction SilentlyContinue - } - - if (!$NonDestructive) { - # Self destruct! - Remove-Item function:deactivate - Remove-Item function:pydoc - } -} - -function global:pydoc { - python -m pydoc $args -} - -# unset irrelevant variables -deactivate -nondestructive - -$VIRTUAL_ENV = $BASE_DIR -$env:VIRTUAL_ENV = $VIRTUAL_ENV - -New-Variable -Scope global -Name _OLD_VIRTUAL_PATH -Value $env:PATH - -$env:PATH = "$env:VIRTUAL_ENV/bin:" + $env:PATH -if (!$env:VIRTUAL_ENV_DISABLE_PROMPT) { - function global:_old_virtual_prompt { - "" - } - $function:_old_virtual_prompt = $function:prompt - - if ("" -ne "") { - function global:prompt { - # Add the custom prefix to the existing prompt - $previous_prompt_value = & $function:_old_virtual_prompt - ("" + $previous_prompt_value) - } - } - else { - function global:prompt { - # Add a prefix to the current prompt, but don't discard it. - $previous_prompt_value = & $function:_old_virtual_prompt - $new_prompt_value = "($( Split-Path $env:VIRTUAL_ENV -Leaf )) " - ($new_prompt_value + $previous_prompt_value) - } - } -} diff --git a/venv27/bin/activate_this.py b/venv27/bin/activate_this.py deleted file mode 100644 index aa96457f2..000000000 --- a/venv27/bin/activate_this.py +++ /dev/null @@ -1,46 +0,0 @@ -"""Activate virtualenv for current interpreter: - -Use exec(open(this_file).read(), {'__file__': this_file}). - -This can be used when you must use an existing Python interpreter, not the virtualenv bin/python. -""" -import os -import site -import sys - -try: - __file__ -except NameError: - raise AssertionError("You must use exec(open(this_file).read(), {'__file__': this_file}))") - -# prepend bin to PATH (this file is inside the bin directory) -bin_dir = os.path.dirname(os.path.abspath(__file__)) -os.environ["PATH"] = os.pathsep.join([bin_dir] + os.environ.get("PATH", "").split(os.pathsep)) - -base = os.path.dirname(bin_dir) - -# virtual env is right above bin directory -os.environ["VIRTUAL_ENV"] = base - -# add the virtual environments site-package to the host python import mechanism -IS_PYPY = hasattr(sys, "pypy_version_info") -IS_JYTHON = sys.platform.startswith("java") -if IS_JYTHON: - site_packages = os.path.join(base, "Lib", "site-packages") -elif IS_PYPY: - site_packages = os.path.join(base, "site-packages") -else: - IS_WIN = sys.platform == "win32" - if IS_WIN: - site_packages = os.path.join(base, "Lib", "site-packages") - else: - site_packages = os.path.join(base, "lib", "python{}.{}".format(*sys.version_info), "site-packages") - -prev = set(sys.path) -site.addsitedir(site_packages) -sys.real_prefix = sys.prefix -sys.prefix = base - -# Move the added items to the front of the path, in place -new = list(sys.path) -sys.path[:] = [i for i in new if i not in prev] + [i for i in new if i in prev] diff --git a/venv27/bin/chardetect b/venv27/bin/chardetect deleted file mode 100755 index ac4d99aca..000000000 --- a/venv27/bin/chardetect +++ /dev/null @@ -1,8 +0,0 @@ -#!/Users/py356p/codebase/pact-python/venv27/bin/python -# -*- coding: utf-8 -*- -import re -import sys -from chardet.cli.chardetect import main -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) - sys.exit(main()) diff --git a/venv27/bin/easy_install b/venv27/bin/easy_install deleted file mode 100755 index 2205b4573..000000000 --- a/venv27/bin/easy_install +++ /dev/null @@ -1,10 +0,0 @@ -#!/Users/py356p/codebase/pact-python/venv27/bin/python -# -*- coding: utf-8 -*- -import re -import sys - -from setuptools.command.easy_install import main - -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) - sys.exit(main()) diff --git a/venv27/bin/easy_install-2.7 b/venv27/bin/easy_install-2.7 deleted file mode 100755 index 2205b4573..000000000 --- a/venv27/bin/easy_install-2.7 +++ /dev/null @@ -1,10 +0,0 @@ -#!/Users/py356p/codebase/pact-python/venv27/bin/python -# -*- coding: utf-8 -*- -import re -import sys - -from setuptools.command.easy_install import main - -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) - sys.exit(main()) diff --git a/venv27/bin/pact-verifier b/venv27/bin/pact-verifier deleted file mode 100755 index 80948a3c2..000000000 --- a/venv27/bin/pact-verifier +++ /dev/null @@ -1,12 +0,0 @@ -#!/Users/py356p/codebase/pact-python/venv27/bin/python -# EASY-INSTALL-ENTRY-SCRIPT: 'pact-python','console_scripts','pact-verifier' -__requires__ = 'pact-python' -import re -import sys -from pkg_resources import load_entry_point - -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) - sys.exit( - load_entry_point('pact-python', 'console_scripts', 'pact-verifier')() - ) diff --git a/venv27/bin/pip b/venv27/bin/pip deleted file mode 100755 index 6381bbfd5..000000000 --- a/venv27/bin/pip +++ /dev/null @@ -1,10 +0,0 @@ -#!/Users/py356p/codebase/pact-python/venv27/bin/python -# -*- coding: utf-8 -*- -import re -import sys - -from pip._internal.cli.main import main - -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) - sys.exit(main()) diff --git a/venv27/bin/pip2 b/venv27/bin/pip2 deleted file mode 100755 index 6381bbfd5..000000000 --- a/venv27/bin/pip2 +++ /dev/null @@ -1,10 +0,0 @@ -#!/Users/py356p/codebase/pact-python/venv27/bin/python -# -*- coding: utf-8 -*- -import re -import sys - -from pip._internal.cli.main import main - -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) - sys.exit(main()) diff --git a/venv27/bin/pip2.7 b/venv27/bin/pip2.7 deleted file mode 100755 index 6381bbfd5..000000000 --- a/venv27/bin/pip2.7 +++ /dev/null @@ -1,10 +0,0 @@ -#!/Users/py356p/codebase/pact-python/venv27/bin/python -# -*- coding: utf-8 -*- -import re -import sys - -from pip._internal.cli.main import main - -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) - sys.exit(main()) diff --git a/venv27/bin/python b/venv27/bin/python deleted file mode 100755 index 542eddcc6396c5372a2a538133f3b0ec9363c530..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51744 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 (3, 2): - valid_opts.insert(-1, 'extension-suffix') - valid_opts.append('abiflags') -if sys.version_info >= (3, 3): - valid_opts.append('configdir') - - -def exit_with_usage(code=1): - sys.stderr.write("Usage: {0} [{1}]\n".format( - sys.argv[0], '|'.join('--'+opt for opt in valid_opts))) - sys.exit(code) - -try: - opts, args = getopt.getopt(sys.argv[1:], '', valid_opts) -except getopt.error: - exit_with_usage() - -if not opts: - exit_with_usage() - -pyver = sysconfig.get_config_var('VERSION') -getvar = sysconfig.get_config_var - -opt_flags = [flag for (flag, val) in opts] - -if '--help' in opt_flags: - exit_with_usage(code=0) - -for opt in opt_flags: - if opt == '--prefix': - print(sysconfig.get_config_var('prefix')) - - elif opt == '--exec-prefix': - print(sysconfig.get_config_var('exec_prefix')) - - elif opt in ('--includes', '--cflags'): - flags = ['-I' + sysconfig.get_path('include'), - '-I' + sysconfig.get_path('platinclude')] - if opt == '--cflags': - flags.extend(getvar('CFLAGS').split()) - print(' '.join(flags)) - - elif opt in ('--libs', '--ldflags'): - abiflags = getattr(sys, 'abiflags', '') - libs = ['-lpython' + pyver + abiflags] - libs += getvar('LIBS').split() - libs += getvar('SYSLIBS').split() - # add the prefix/lib/pythonX.Y/config dir, but only if there is no - # shared library in prefix/lib/. - if opt == '--ldflags': - if not getvar('Py_ENABLE_SHARED'): - libs.insert(0, '-L' + getvar('LIBPL')) - if not getvar('PYTHONFRAMEWORK'): - libs.extend(getvar('LINKFORSHARED').split()) - print(' '.join(libs)) - - elif opt == '--extension-suffix': - ext_suffix = sysconfig.get_config_var('EXT_SUFFIX') - if ext_suffix is None: - ext_suffix = sysconfig.get_config_var('SO') - print(ext_suffix) - - elif opt == '--abiflags': - if not getattr(sys, 'abiflags', None): - exit_with_usage() - print(sys.abiflags) - - elif opt == '--configdir': - print(sysconfig.get_config_var('LIBPL')) diff --git a/venv27/bin/python2 b/venv27/bin/python2 deleted file mode 120000 index d8654aa0e..000000000 --- a/venv27/bin/python2 +++ /dev/null @@ -1 +0,0 @@ -python \ No newline at end of file diff --git a/venv27/bin/python2.7 b/venv27/bin/python2.7 deleted file mode 120000 index d8654aa0e..000000000 --- a/venv27/bin/python2.7 +++ /dev/null @@ -1 +0,0 @@ -python \ No newline at end of file diff --git a/venv27/bin/wheel b/venv27/bin/wheel deleted file mode 100755 index 1fc646aeb..000000000 --- a/venv27/bin/wheel +++ /dev/null @@ -1,10 +0,0 @@ -#!/Users/py356p/codebase/pact-python/venv27/bin/python -# -*- coding: utf-8 -*- -import re -import sys - -from wheel.cli import main - -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) - sys.exit(main()) diff --git a/venv27/include/python2.7 b/venv27/include/python2.7 deleted file mode 120000 index 3fe034fcc..000000000 --- a/venv27/include/python2.7 +++ /dev/null @@ -1 +0,0 @@ -/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 \ No newline at end of file