Some flake8 cleanup.
This commit is contained in:
parent
fd26441e44
commit
8bc8f09b47
@ -2,19 +2,19 @@ from __future__ import unicode_literals
|
||||
import logging
|
||||
logging.getLogger('boto').setLevel(logging.CRITICAL)
|
||||
|
||||
from .autoscaling import mock_autoscaling
|
||||
from .cloudformation import mock_cloudformation
|
||||
from .cloudwatch import mock_cloudwatch
|
||||
from .dynamodb import mock_dynamodb
|
||||
from .dynamodb2 import mock_dynamodb2
|
||||
from .ec2 import mock_ec2
|
||||
from .elb import mock_elb
|
||||
from .emr import mock_emr
|
||||
from .iam import mock_iam
|
||||
from .s3 import mock_s3
|
||||
from .s3bucket_path import mock_s3bucket_path
|
||||
from .ses import mock_ses
|
||||
from .sns import mock_sns
|
||||
from .sqs import mock_sqs
|
||||
from .sts import mock_sts
|
||||
from .route53 import mock_route53
|
||||
from .autoscaling import mock_autoscaling # flake8: noqa
|
||||
from .cloudformation import mock_cloudformation # flake8: noqa
|
||||
from .cloudwatch import mock_cloudwatch # flake8: noqa
|
||||
from .dynamodb import mock_dynamodb # flake8: noqa
|
||||
from .dynamodb2 import mock_dynamodb2 # flake8: noqa
|
||||
from .ec2 import mock_ec2 # flake8: noqa
|
||||
from .elb import mock_elb # flake8: noqa
|
||||
from .emr import mock_emr # flake8: noqa
|
||||
from .iam import mock_iam # flake8: noqa
|
||||
from .s3 import mock_s3 # flake8: noqa
|
||||
from .s3bucket_path import mock_s3bucket_path # flake8: noqa
|
||||
from .ses import mock_ses # flake8: noqa
|
||||
from .sns import mock_sns # flake8: noqa
|
||||
from .sqs import mock_sqs # flake8: noqa
|
||||
from .sts import mock_sts # flake8: noqa
|
||||
from .route53 import mock_route53 # flake8: noqa
|
||||
|
@ -1,5 +1,5 @@
|
||||
from __future__ import unicode_literals
|
||||
from .models import autoscaling_backend, autoscaling_backends
|
||||
from .models import autoscaling_backend, autoscaling_backends # flake8: noqa
|
||||
from ..core.models import MockAWS
|
||||
|
||||
|
||||
|
@ -1,2 +1,2 @@
|
||||
from __future__ import unicode_literals
|
||||
from .models import BaseBackend
|
||||
from .models import BaseBackend # flake8: noqa
|
||||
|
@ -4,10 +4,10 @@ import datetime
|
||||
import json
|
||||
|
||||
try:
|
||||
from collections import OrderedDict
|
||||
from collections import OrderedDict
|
||||
except ImportError:
|
||||
# python 2.6 or earlier, use backport
|
||||
from ordereddict import OrderedDict
|
||||
# python 2.6 or earlier, use backport
|
||||
from ordereddict import OrderedDict
|
||||
|
||||
|
||||
from moto.core import BaseBackend
|
||||
@ -69,6 +69,7 @@ class DynamoType(object):
|
||||
comparison_func = get_comparison_func(range_comparison)
|
||||
return comparison_func(self.value, *range_values)
|
||||
|
||||
|
||||
class Item(object):
|
||||
def __init__(self, hash_key, hash_key_type, range_key, range_key_type, attrs):
|
||||
self.hash_key = hash_key
|
||||
@ -104,9 +105,10 @@ class Item(object):
|
||||
"Item": included
|
||||
}
|
||||
|
||||
|
||||
class Table(object):
|
||||
|
||||
def __init__(self, table_name, schema=None, attr = None, throughput=None, indexes=None):
|
||||
def __init__(self, table_name, schema=None, attr=None, throughput=None, indexes=None):
|
||||
self.name = table_name
|
||||
self.attr = attr
|
||||
self.schema = schema
|
||||
@ -122,7 +124,7 @@ class Table(object):
|
||||
self.range_key_attr = elem["AttributeName"]
|
||||
self.range_key_type = elem["KeyType"]
|
||||
if throughput is None:
|
||||
self.throughput = {u'WriteCapacityUnits': 10, u'ReadCapacityUnits': 10}
|
||||
self.throughput = {'WriteCapacityUnits': 10, 'ReadCapacityUnits': 10}
|
||||
else:
|
||||
self.throughput = throughput
|
||||
self.throughput["NumberOfDecreasesToday"] = 0
|
||||
@ -133,15 +135,15 @@ class Table(object):
|
||||
@property
|
||||
def describe(self):
|
||||
results = {
|
||||
'Table': {
|
||||
'AttributeDefinitions': self.attr,
|
||||
'ProvisionedThroughput': self.throughput,
|
||||
'TableSizeBytes': 0,
|
||||
'TableName': self.name,
|
||||
'TableStatus': 'ACTIVE',
|
||||
'KeySchema': self.schema,
|
||||
'ItemCount': len(self),
|
||||
'CreationDateTime': unix_time(self.created_at)
|
||||
'Table': {
|
||||
'AttributeDefinitions': self.attr,
|
||||
'ProvisionedThroughput': self.throughput,
|
||||
'TableSizeBytes': 0,
|
||||
'TableName': self.name,
|
||||
'TableStatus': 'ACTIVE',
|
||||
'KeySchema': self.schema,
|
||||
'ItemCount': len(self),
|
||||
'CreationDateTime': unix_time(self.created_at),
|
||||
}
|
||||
}
|
||||
return results
|
||||
@ -204,7 +206,7 @@ class Table(object):
|
||||
results = []
|
||||
last_page = True # Once pagination is implemented, change this
|
||||
|
||||
possible_results = [ item for item in list(self.all_items()) if item.hash_key == hash_key]
|
||||
possible_results = [item for item in list(self.all_items()) if item.hash_key == hash_key]
|
||||
if range_comparison:
|
||||
for result in possible_results:
|
||||
if result.range_key.compare(range_comparison, range_objs):
|
||||
@ -285,17 +287,17 @@ class DynamoDBBackend(BaseBackend):
|
||||
return table.hash_key_attr, table.range_key_attr
|
||||
|
||||
def get_keys_value(self, table, keys):
|
||||
if not table.hash_key_attr in keys or (table.has_range_key and not table.range_key_attr in keys):
|
||||
if table.hash_key_attr not in keys or (table.has_range_key and table.range_key_attr not in keys):
|
||||
raise ValueError("Table has a range key, but no range key was passed into get_item")
|
||||
hash_key = DynamoType(keys[table.hash_key_attr])
|
||||
range_key = DynamoType(keys[table.range_key_attr]) if table.has_range_key else None
|
||||
return hash_key,range_key
|
||||
return hash_key, range_key
|
||||
|
||||
def get_item(self, table_name, keys):
|
||||
table = self.tables.get(table_name)
|
||||
if not table:
|
||||
return None
|
||||
hash_key,range_key = self.get_keys_value(table,keys)
|
||||
hash_key, range_key = self.get_keys_value(table, keys)
|
||||
return table.get_item(hash_key, range_key)
|
||||
|
||||
def query(self, table_name, hash_key_dict, range_comparison, range_value_dicts):
|
||||
|
@ -90,19 +90,19 @@ class DynamoHandler(BaseResponse):
|
||||
|
||||
def create_table(self):
|
||||
body = self.body
|
||||
#get the table name
|
||||
# get the table name
|
||||
table_name = body['TableName']
|
||||
#get the throughput
|
||||
# get the throughput
|
||||
throughput = body["ProvisionedThroughput"]
|
||||
#getting the schema
|
||||
# getting the schema
|
||||
key_schema = body['KeySchema']
|
||||
#getting attribute definition
|
||||
# getting attribute definition
|
||||
attr = body["AttributeDefinitions"]
|
||||
#getting the indexes
|
||||
# getting the indexes
|
||||
table = dynamodb_backend2.create_table(table_name,
|
||||
schema = key_schema,
|
||||
throughput = throughput,
|
||||
attr = attr)
|
||||
schema=key_schema,
|
||||
throughput=throughput,
|
||||
attr=attr)
|
||||
return dynamo_json_dump(table.describe)
|
||||
|
||||
def delete_table(self):
|
||||
@ -169,6 +169,7 @@ class DynamoHandler(BaseResponse):
|
||||
}
|
||||
|
||||
return dynamo_json_dump(response)
|
||||
|
||||
def get_item(self):
|
||||
name = self.body['TableName']
|
||||
key = self.body['Key']
|
||||
@ -178,7 +179,7 @@ class DynamoHandler(BaseResponse):
|
||||
er = 'com.amazon.coral.validate#ValidationException'
|
||||
return self.error(er, status=400)
|
||||
if item:
|
||||
item_dict = item.describe_attrs(attributes = None)
|
||||
item_dict = item.describe_attrs(attributes=None)
|
||||
item_dict['ConsumedCapacityUnits'] = 0.5
|
||||
return dynamo_json_dump(item_dict)
|
||||
else:
|
||||
@ -190,7 +191,7 @@ class DynamoHandler(BaseResponse):
|
||||
table_batches = self.body['RequestItems']
|
||||
|
||||
results = {
|
||||
"ConsumedCapacity":[],
|
||||
"ConsumedCapacity": [],
|
||||
"Responses": {
|
||||
},
|
||||
"UnprocessedKeys": {
|
||||
@ -198,10 +199,9 @@ class DynamoHandler(BaseResponse):
|
||||
}
|
||||
|
||||
for table_name, table_request in table_batches.items():
|
||||
items = []
|
||||
keys = table_request['Keys']
|
||||
attributes_to_get = table_request.get('AttributesToGet')
|
||||
results["Responses"][table_name]=[]
|
||||
results["Responses"][table_name] = []
|
||||
for key in keys:
|
||||
item = dynamodb_backend2.get_item(table_name, key)
|
||||
if item:
|
||||
@ -226,7 +226,7 @@ class DynamoHandler(BaseResponse):
|
||||
range_comparison = None
|
||||
range_values = []
|
||||
else:
|
||||
if range_key_name == None:
|
||||
if range_key_name is None:
|
||||
er = "com.amazon.coral.validate#ValidationException"
|
||||
return self.error(er)
|
||||
else:
|
||||
@ -247,7 +247,7 @@ class DynamoHandler(BaseResponse):
|
||||
items = items[:limit]
|
||||
|
||||
reversed = self.body.get("ScanIndexForward")
|
||||
if reversed != False:
|
||||
if reversed is not False:
|
||||
items.reverse()
|
||||
|
||||
result = {
|
||||
|
@ -1,7 +1,8 @@
|
||||
from __future__ import unicode_literals
|
||||
from .models import ec2_backends, ec2_backend
|
||||
from .models import ec2_backend, ec2_backends # flake8: noqa
|
||||
from ..core.models import MockAWS
|
||||
|
||||
|
||||
def mock_ec2(func=None):
|
||||
if func:
|
||||
return MockAWS(ec2_backends)(func)
|
||||
|
@ -163,7 +163,7 @@ class InvalidSnapshotIdError(EC2ClientError):
|
||||
def __init__(self, snapshot_id):
|
||||
super(InvalidSnapshotIdError, self).__init__(
|
||||
"InvalidSnapshot.NotFound",
|
||||
"") # Note: AWS returns empty message for this, as of 2014.08.22.
|
||||
"") # Note: AWS returns empty message for this, as of 2014.08.22.
|
||||
|
||||
|
||||
class InvalidVolumeIdError(EC2ClientError):
|
||||
|
@ -1,8 +1,9 @@
|
||||
from __future__ import unicode_literals
|
||||
import copy
|
||||
import itertools
|
||||
|
||||
from collections import defaultdict
|
||||
import copy
|
||||
from datetime import datetime
|
||||
import itertools
|
||||
import re
|
||||
|
||||
import six
|
||||
@ -11,6 +12,7 @@ from boto.ec2.instance import Instance as BotoInstance, Reservation
|
||||
from boto.ec2.blockdevicemapping import BlockDeviceMapping, BlockDeviceType
|
||||
from boto.ec2.spotinstancerequest import SpotInstanceRequest as BotoSpotRequest
|
||||
from boto.ec2.launchspecification import LaunchSpecification
|
||||
import six
|
||||
|
||||
from moto.core import BaseBackend
|
||||
from moto.core.models import Model
|
||||
@ -240,12 +242,11 @@ class NetworkInterfaceBackend(object):
|
||||
for (_filter, _filter_value) in filters.items():
|
||||
if _filter == 'network-interface-id':
|
||||
_filter = 'id'
|
||||
enis = [ eni for eni in enis if getattr(eni, _filter) in _filter_value ]
|
||||
enis = [eni for eni in enis if getattr(eni, _filter) in _filter_value]
|
||||
elif _filter == 'group-id':
|
||||
original_enis = enis
|
||||
enis = []
|
||||
for eni in original_enis:
|
||||
group_ids = []
|
||||
for group in eni.group_set:
|
||||
if group.id in _filter_value:
|
||||
enis.append(eni)
|
||||
@ -817,7 +818,7 @@ class Ami(TaggedEC2Resource):
|
||||
elif filter_name == 'kernel-id':
|
||||
return self.kernel_id
|
||||
elif filter_name in ['architecture', 'platform']:
|
||||
return getattr(self,filter_name)
|
||||
return getattr(self, filter_name)
|
||||
elif filter_name == 'image-id':
|
||||
return self.id
|
||||
elif filter_name == 'state':
|
||||
@ -856,7 +857,6 @@ class AmiBackend(object):
|
||||
def describe_images(self, ami_ids=(), filters=None):
|
||||
if filters:
|
||||
images = self.amis.values()
|
||||
|
||||
return generic_filter(filters, images)
|
||||
else:
|
||||
images = []
|
||||
@ -1008,10 +1008,7 @@ class SecurityGroup(object):
|
||||
def physical_resource_id(self):
|
||||
return self.id
|
||||
|
||||
|
||||
def matches_filter(self, key, filter_value):
|
||||
result = True
|
||||
|
||||
def to_attr(filter_name):
|
||||
attr = None
|
||||
|
||||
@ -1031,7 +1028,7 @@ class SecurityGroup(object):
|
||||
ingress_attr = to_attr(match.groups()[0])
|
||||
|
||||
for ingress in self.ingress_rules:
|
||||
if getattr(ingress, ingress_attr) in filters[key]:
|
||||
if getattr(ingress, ingress_attr) in filter_value:
|
||||
return True
|
||||
else:
|
||||
attr_name = to_attr(key)
|
||||
@ -1302,7 +1299,7 @@ class EBSBackend(object):
|
||||
|
||||
def detach_volume(self, volume_id, instance_id, device_path):
|
||||
volume = self.get_volume(volume_id)
|
||||
instance = self.get_instance(instance_id)
|
||||
self.get_instance(instance_id)
|
||||
|
||||
old_attachment = volume.attachment
|
||||
if not old_attachment:
|
||||
@ -1406,7 +1403,7 @@ class VPCBackend(object):
|
||||
self.vpcs[vpc_id] = vpc
|
||||
|
||||
# AWS creates a default main route table and security group.
|
||||
main_route_table = self.create_route_table(vpc_id, main=True)
|
||||
self.create_route_table(vpc_id, main=True)
|
||||
|
||||
default = self.get_security_group_from_name('default', vpc_id=vpc_id)
|
||||
if not default:
|
||||
@ -1429,7 +1426,7 @@ class VPCBackend(object):
|
||||
|
||||
def delete_vpc(self, vpc_id):
|
||||
# Delete route table if only main route table remains.
|
||||
route_tables = self.get_all_route_tables(filters={'vpc-id':vpc_id})
|
||||
route_tables = self.get_all_route_tables(filters={'vpc-id': vpc_id})
|
||||
if len(route_tables) > 1:
|
||||
raise DependencyViolationError(
|
||||
"The vpc {0} has dependencies and cannot be deleted."
|
||||
@ -1599,7 +1596,7 @@ class SubnetBackend(object):
|
||||
def create_subnet(self, vpc_id, cidr_block):
|
||||
subnet_id = random_subnet_id()
|
||||
subnet = Subnet(self, subnet_id, vpc_id, cidr_block)
|
||||
vpc = self.get_vpc(vpc_id) # Validate VPC exists
|
||||
self.get_vpc(vpc_id) # Validate VPC exists
|
||||
self.subnets[subnet_id] = subnet
|
||||
return subnet
|
||||
|
||||
@ -1719,7 +1716,7 @@ class RouteTableBackend(object):
|
||||
route_tables = self.route_tables.values()
|
||||
|
||||
if route_table_ids:
|
||||
route_tables = [ route_table for route_table in route_tables if route_table.id in route_table_ids ]
|
||||
route_tables = [route_table for route_table in route_tables if route_table.id in route_table_ids]
|
||||
if len(route_tables) != len(route_table_ids):
|
||||
invalid_id = list(set(route_table_ids).difference(set([route_table.id for route_table in route_tables])))[0]
|
||||
raise InvalidRouteTableIdError(invalid_id)
|
||||
|
@ -35,12 +35,12 @@ class ElasticBlockStore(BaseResponse):
|
||||
|
||||
def delete_snapshot(self):
|
||||
snapshot_id = self.querystring.get('SnapshotId')[0]
|
||||
success = self.ec2_backend.delete_snapshot(snapshot_id)
|
||||
self.ec2_backend.delete_snapshot(snapshot_id)
|
||||
return DELETE_SNAPSHOT_RESPONSE
|
||||
|
||||
def delete_volume(self):
|
||||
volume_id = self.querystring.get('VolumeId')[0]
|
||||
success = self.ec2_backend.delete_volume(volume_id)
|
||||
self.ec2_backend.delete_volume(volume_id)
|
||||
return DELETE_VOLUME_RESPONSE
|
||||
|
||||
def describe_snapshots(self):
|
||||
|
@ -59,9 +59,9 @@ class ElasticIPAddresses(BaseResponse):
|
||||
|
||||
def disassociate_address(self):
|
||||
if "PublicIp" in self.querystring:
|
||||
disassociated = self.ec2_backend.disassociate_address(address=self.querystring['PublicIp'][0])
|
||||
self.ec2_backend.disassociate_address(address=self.querystring['PublicIp'][0])
|
||||
elif "AssociationId" in self.querystring:
|
||||
disassociated = self.ec2_backend.disassociate_address(association_id=self.querystring['AssociationId'][0])
|
||||
self.ec2_backend.disassociate_address(association_id=self.querystring['AssociationId'][0])
|
||||
else:
|
||||
self.ec2_backend.raise_error("MissingParameter", "Invalid request, expect PublicIp/AssociationId parameter.")
|
||||
|
||||
@ -69,9 +69,9 @@ class ElasticIPAddresses(BaseResponse):
|
||||
|
||||
def release_address(self):
|
||||
if "PublicIp" in self.querystring:
|
||||
released = self.ec2_backend.release_address(address=self.querystring['PublicIp'][0])
|
||||
self.ec2_backend.release_address(address=self.querystring['PublicIp'][0])
|
||||
elif "AllocationId" in self.querystring:
|
||||
released = self.ec2_backend.release_address(allocation_id=self.querystring['AllocationId'][0])
|
||||
self.ec2_backend.release_address(allocation_id=self.querystring['AllocationId'][0])
|
||||
else:
|
||||
self.ec2_backend.raise_error("MissingParameter", "Invalid request, expect PublicIp/AllocationId parameter.")
|
||||
|
||||
|
@ -25,7 +25,7 @@ class ElasticNetworkInterfaces(BaseResponse):
|
||||
raise NotImplementedError('ElasticNetworkInterfaces(AmazonVPC).describe_network_interface_attribute is not yet implemented')
|
||||
|
||||
def describe_network_interfaces(self):
|
||||
#Partially implemented. Supports only network-interface-id and group-id filters
|
||||
# Partially implemented. Supports only network-interface-id and group-id filters
|
||||
filters = filters_from_querystring(self.querystring)
|
||||
enis = self.ec2_backend.describe_network_interfaces(filters)
|
||||
template = Template(DESCRIBE_NETWORK_INTERFACES_RESPONSE)
|
||||
@ -46,7 +46,7 @@ class ElasticNetworkInterfaces(BaseResponse):
|
||||
return template.render()
|
||||
|
||||
def modify_network_interface_attribute(self):
|
||||
#Currently supports modifying one and only one security group
|
||||
# Currently supports modifying one and only one security group
|
||||
eni_id = self.querystring.get('NetworkInterfaceId')[0]
|
||||
group_id = self.querystring.get('SecurityGroupId.1')[0]
|
||||
self.ec2_backend.modify_network_interface_attribute(eni_id, group_id)
|
||||
|
@ -112,4 +112,3 @@ DETACH_INTERNET_GATEWAY_RESPONSE = u"""<DetachInternetGatewayResponse xmlns="htt
|
||||
<requestId>59dbff89-35bd-4eac-99ed-be587EXAMPLE</requestId>
|
||||
<return>true</return>
|
||||
</DetachInternetGatewayResponse>"""
|
||||
|
||||
|
@ -22,7 +22,7 @@ class RouteTables(BaseResponse):
|
||||
interface_id = optional_from_querystring('NetworkInterfaceId', self.querystring)
|
||||
pcx_id = optional_from_querystring('VpcPeeringConnectionId', self.querystring)
|
||||
|
||||
route = self.ec2_backend.create_route(route_table_id, destination_cidr_block,
|
||||
self.ec2_backend.create_route(route_table_id, destination_cidr_block,
|
||||
gateway_id=internet_gateway_id,
|
||||
instance_id=instance_id,
|
||||
interface_id=interface_id,
|
||||
@ -72,7 +72,7 @@ class RouteTables(BaseResponse):
|
||||
interface_id = optional_from_querystring('NetworkInterfaceId', self.querystring)
|
||||
pcx_id = optional_from_querystring('VpcPeeringConnectionId', self.querystring)
|
||||
|
||||
route = self.ec2_backend.replace_route(route_table_id, destination_cidr_block,
|
||||
self.ec2_backend.replace_route(route_table_id, destination_cidr_block,
|
||||
gateway_id=internet_gateway_id,
|
||||
instance_id=instance_id,
|
||||
interface_id=interface_id,
|
||||
|
@ -31,7 +31,7 @@ class VPCPeeringConnections(BaseResponse):
|
||||
|
||||
def reject_vpc_peering_connection(self):
|
||||
vpc_pcx_id = self.querystring.get('VpcPeeringConnectionId')[0]
|
||||
vpc_pcx = self.ec2_backend.reject_vpc_peering_connection(vpc_pcx_id)
|
||||
self.ec2_backend.reject_vpc_peering_connection(vpc_pcx_id)
|
||||
template = Template(REJECT_VPC_PEERING_CONNECTION_RESPONSE)
|
||||
return template.render()
|
||||
|
||||
@ -125,4 +125,3 @@ REJECT_VPC_PEERING_CONNECTION_RESPONSE = """
|
||||
<return>true</return>
|
||||
</RejectVpcPeeringConnectionResponse>
|
||||
"""
|
||||
|
||||
|
@ -130,7 +130,7 @@ def generate_route_id(route_table_id, cidr_block):
|
||||
|
||||
|
||||
def split_route_id(route_id):
|
||||
values = string.split(route_id, '~')
|
||||
values = route_id.split('~')
|
||||
return values[0], values[1]
|
||||
|
||||
|
||||
|
@ -166,12 +166,12 @@ class ResponseObject(object):
|
||||
if request.path == u'/?delete':
|
||||
return self._bucket_response_delete_keys(request, bucket_name, headers)
|
||||
|
||||
#POST to bucket-url should create file from form
|
||||
# POST to bucket-url should create file from form
|
||||
if hasattr(request, 'form'):
|
||||
#Not HTTPretty
|
||||
# Not HTTPretty
|
||||
form = request.form
|
||||
else:
|
||||
#HTTPretty, build new form object
|
||||
# HTTPretty, build new form object
|
||||
form = {}
|
||||
for kv in request.body.decode('utf-8').split('&'):
|
||||
k, v = kv.split('=')
|
||||
@ -185,7 +185,7 @@ class ResponseObject(object):
|
||||
|
||||
new_key = self.backend.set_key(bucket_name, key, f)
|
||||
|
||||
#Metadata
|
||||
# Metadata
|
||||
meta_regex = re.compile('^x-amz-meta-([a-zA-Z0-9\-_]+)$', flags=re.IGNORECASE)
|
||||
|
||||
for form_id in form:
|
||||
|
@ -1,4 +1,6 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
||||
class MessageNotInflight(Exception):
|
||||
description = "The message referred to is not in flight."
|
||||
status_code = 400
|
||||
|
@ -1,5 +1,5 @@
|
||||
from __future__ import unicode_literals
|
||||
import base64
|
||||
|
||||
import hashlib
|
||||
import time
|
||||
import re
|
||||
|
@ -4,3 +4,4 @@ nose
|
||||
sure<1.2.4
|
||||
coverage
|
||||
freezegun
|
||||
flask
|
||||
|
Loading…
Reference in New Issue
Block a user