From 6d479a019662b96e9d137af6872f1dfdcb53c988 Mon Sep 17 00:00:00 2001 From: Clint Byrum Date: Wed, 16 Nov 2016 11:47:53 -0800 Subject: Make Job.name assume utf-8. This breaks the API in subtle ways, but only really for people who want to use Python 3 and/or not utf-8 function names. Change-Id: If6bfc35d916cfb84d630af59f4fde4ccae5187d4 --- gear/__init__.py | 44 ++++++++++++++++++++++++++++++++++++++----- gear/tests/test_functional.py | 11 +++++++++++ 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/gear/__init__.py b/gear/__init__.py index 537a5b2..5db3b78 100644 --- a/gear/__init__.py +++ b/gear/__init__.py @@ -16,6 +16,7 @@ import errno import logging import os import select +import six import socket import ssl import struct @@ -1426,7 +1427,7 @@ class Client(BaseClient): unique = b'' else: unique = job.unique - data = b'\x00'.join((job.name, unique, job.arguments)) + data = b'\x00'.join((job.binary_name, unique, job.arguments)) if background: if precedence == PRECEDENCE_NORMAL: cmd = constants.SUBMIT_JOB_BG @@ -2044,7 +2045,7 @@ class Worker(BaseClient): class BaseJob(object): def __init__(self, name, arguments, unique=None, handle=None): - self.name = convert_to_bytes(name) + self._name = convert_to_bytes(name) if (not isinstance(arguments, bytes) and not isinstance(arguments, bytearray)): raise TypeError("arguments must be of type bytes or bytearray") @@ -2053,6 +2054,22 @@ class BaseJob(object): self.handle = handle self.connection = None + @property + def name(self): + if isinstance(self._name, six.binary_type): + return self._name.decode('utf-8') + return self._name + + @name.setter + def name(self, value): + if isinstance(value, six.text_type): + value = value.encode('utf-8') + self._name = value + + @property + def binary_name(self): + return self._name + def __repr__(self): return '' % ( id(self), self.handle, self.name, self.unique) @@ -2070,7 +2087,7 @@ class Job(BaseJob): The following instance attributes are available: **name** (str) - The name of the job. + The name of the job. Assumed to be utf-8. **arguments** (bytes) The opaque data blob passed to the worker as arguments. **unique** (str or None) @@ -2139,7 +2156,7 @@ class WorkerJob(BaseJob): The following instance attributes are available: **name** (str) - The name of the job. + The name of the job. Assumed to be utf-8. **arguments** (bytes) The opaque data blob passed to the worker as arguments. **unique** (str or None) @@ -2218,8 +2235,25 @@ class WorkerJob(BaseJob): self.connection.sendPacket(p) +class BaseBinaryJob(object): + """ For the case where non-utf-8 job names are needed. It will function + exactly like Job, except that the job name will not be decoded.""" + + @property + def name(self): + return self._name + + +class BinaryWorkerJob(BaseBinaryJob, WorkerJob): + pass + + +class BinaryJob(BaseBinaryJob, Job): + pass + + # Below are classes for use in the server implementation: -class ServerJob(Job): +class ServerJob(BinaryJob): """A job record for use in a server. :arg str name: The name of the job. diff --git a/gear/tests/test_functional.py b/gear/tests/test_functional.py index 26e72e3..ea02ffe 100644 --- a/gear/tests/test_functional.py +++ b/gear/tests/test_functional.py @@ -137,6 +137,17 @@ class TestFunctional(tests.BaseTestCase): jobthread.start() self.worker.stopWaitingForJobs() + def test_text_job_name(self): + self.worker.registerFunction('test') + + for jobcount in range(2): + job = gear.Job('test', b'testdata') + self.client.submitJob(job) + self.assertNotEqual(job.handle, None) + + workerjob = self.worker.getJob() + self.assertEqual('test', workerjob.name) + def load_tests(loader, in_tests, pattern): return testscenarios.load_tests_apply_scenarios(loader, in_tests, pattern) -- cgit v1.2.1