Skip to content
This repository was archived by the owner on Aug 25, 2024. It is now read-only.

Commit 323fd6d

Browse files
Yash-Varshneypdxjohnny
authored andcommitted
feature: Remove evaluation methods
Signed-off-by: John Andersen <[email protected]>
1 parent 8d95d88 commit 323fd6d

File tree

4 files changed

+2
-236
lines changed

4 files changed

+2
-236
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6161
### Removed
6262
- The model predict operation erroneously had a `msg` parameter in it's config.
6363
- Unused imports identified by deepsource.io
64+
- Evaluation code from feature.py file as well as tests for those evaluations.
6465

6566
## [0.3.2] - 2020-01-03
6667
### Added

dffml/feature/feature.py

Lines changed: 1 addition & 196 deletions
Original file line numberDiff line numberDiff line change
@@ -190,52 +190,6 @@ def length(self) -> int:
190190
self.LOGGER.warning("%s length unimplemented", self)
191191
return 1
192192

193-
async def applicable(self, data) -> bool:
194-
return True
195-
196-
async def fetch(self, data):
197-
"""
198-
Fetch retrieves any additional information about the software we are
199-
evaluating. Any data fetched should be stored in tempdir().
200-
"""
201-
pass
202-
203-
async def parse(self, data):
204-
"""
205-
Parse the data we downloaded in fetch() into a usable form.
206-
"""
207-
pass
208-
209-
async def calc(self, data):
210-
"""
211-
Calculates the score for this feature based on data found by parse().
212-
"""
213-
return False
214-
215-
async def setUp(self, data):
216-
"""
217-
Preform setup
218-
"""
219-
pass
220-
221-
async def tearDown(self, data, error=False):
222-
"""
223-
Release any post calculation resources
224-
"""
225-
pass
226-
227-
async def open(self):
228-
"""
229-
Opens any resources needed
230-
"""
231-
pass
232-
233-
async def close(self):
234-
"""
235-
Closes any opened resources
236-
"""
237-
pass
238-
239193
@classmethod
240194
def load(cls, loading=None):
241195
# CLI or dict compatibility
@@ -261,12 +215,11 @@ def convert_dtype(cls, dtype: str):
261215
return found
262216

263217
async def __aenter__(self):
264-
await self.open()
265218
# TODO Context management
266219
return self
267220

268221
async def __aexit__(self, exc_type, exc_value, traceback):
269-
await self.close()
222+
pass
270223

271224

272225
def DefFeature(name, dtype, length):
@@ -327,154 +280,6 @@ def _fromdict(cls, **kwargs):
327280
]
328281
)
329282

330-
async def evaluate(self, src: str, task: Task = None) -> Dict[str, Any]:
331-
return await asyncio.wait_for(
332-
self._evaluate(src, task=task), self.timeout
333-
)
334-
335-
async def _evaluate(self, src: str, task: Task = None) -> Dict[str, Any]:
336-
"""
337-
Evaluates all repos passed to it.
338-
Args:
339-
src: src of repo to be evaluated
340-
caching: If `True` sources will NOT be re-evaluated if they have
341-
features
342-
Returns:
343-
A `dict` containing source URLs and their repos
344-
"""
345-
toreDown = False
346-
data: Data = Data(src)
347-
if not task is None:
348-
data = task # type: ignore
349-
features: Dict[str, Feature] = {}
350-
results: Dict[str, Any] = {}
351-
try:
352-
applicable = await self.applicable(data)
353-
self.LOGGER.debug("Applicable[%r]: %r", data.key, applicable)
354-
await applicable.on_all("setUp", data)
355-
await applicable.on_all("fetch", data)
356-
await applicable.on_all("parse", data)
357-
await applicable.run_calc(results, data)
358-
await applicable.on_all("tearDown", data)
359-
toreDown = True
360-
except futures._base.CancelledError as err:
361-
if not toreDown:
362-
await applicable.on_all("tearDown", data)
363-
return {}
364-
data.results.update(results)
365-
return results
366-
367-
async def applicable(self, data: Data) -> "Features":
368-
return self.__class__(
369-
*[
370-
feature
371-
for feature in self
372-
if feature.NAME and await feature.applicable(data)
373-
]
374-
)
375-
376-
async def on_all(self, method_name: str, data: Data):
377-
await asyncio.gather(
378-
*[
379-
self.run_feature_method(
380-
feature, getattr(feature, method_name), data
381-
)
382-
for feature in self
383-
]
384-
)
385-
386-
async def run_calc(self, results: Dict[str, Any], data: Data):
387-
await asyncio.gather(
388-
*[self._run_calc(feature, results, data) for feature in self]
389-
)
390-
391-
async def _run_calc(
392-
self, feature: Feature, results: Dict[str, Any], data: Data
393-
) -> Any:
394-
results[feature.NAME] = await self.run_feature_method(
395-
feature, feature.calc, data
396-
)
397-
398-
async def run_feature_method(
399-
self, feature: Feature, method: Callable[[Data], Any], data: Data
400-
) -> Any:
401-
error: Exception = Exception("Not an error")
402-
try:
403-
self.LOGGER.debug(
404-
"%s %s(%s).%s",
405-
data.key,
406-
feature.NAME,
407-
feature.__class__.__qualname__,
408-
method.__name__,
409-
)
410-
return await method(data)
411-
except futures._base.CancelledError as err:
412-
raise
413-
except Exception as err:
414-
error = err
415-
self.LOGGER.error(
416-
"Error evaluating %s: %s: %s",
417-
data.key,
418-
err,
419-
traceback.format_exc().strip(),
420-
)
421-
if str(error) != "Not an error":
422-
if method.__name__ != "tearDown":
423-
await feature.tearDown(data)
424-
self.remove(feature)
425-
426-
def mktask(self, func, key):
427-
data = Data(key)
428-
Task.__init__(data, func, key)
429-
return data
430-
431-
async def evaluate_repo(
432-
self, repo: Repo, *, features: List[str] = [], caching: bool = False
433-
):
434-
results: Dict[str, Any] = repo.features(features)
435-
if caching and results:
436-
return repo
437-
try:
438-
results = await self.evaluate(repo.key)
439-
if results:
440-
repo.evaluated(results)
441-
except futures._base.TimeoutError:
442-
self.LOGGER.warning("Evaluation timed out: %s", repo.key)
443-
return repo
444-
445-
async def evaluate_repos(
446-
self,
447-
repos: AsyncIterator[Repo],
448-
*,
449-
features: Optional[List[str]] = None,
450-
caching: bool = False,
451-
num_workers: int = 1,
452-
):
453-
if features is None:
454-
features = self.names()
455-
sem = asyncio.Semaphore(value=num_workers)
456-
457-
async def with_sem(sem, func, *args, **kwargs):
458-
async with sem:
459-
return await func(*args, **kwargs)
460-
461-
evaluate_repo = partial(
462-
with_sem,
463-
sem,
464-
self.evaluate_repo,
465-
features=features,
466-
caching=caching,
467-
)
468-
for repo in await asyncio.gather(
469-
*[evaluate_repo(repo) async for repo in repos]
470-
):
471-
yield repo
472-
473-
async def submit(self, src: str):
474-
return await super().start(
475-
partial(self.evaluate, src), src, mktask=self.mktask
476-
)
477-
478283
async def __aenter__(self):
479284
self._stack = AsyncExitStack()
480285
await self._stack.__aenter__()

tests/test_cli.py

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -101,18 +101,6 @@ def dtype(self):
101101
def length(self):
102102
return 1 # pragma: no cov
103103

104-
async def applicable(self, data):
105-
return True
106-
107-
async def fetch(self, data):
108-
pass
109-
110-
async def parse(self, data):
111-
pass
112-
113-
async def calc(self, data):
114-
return float(data.key)
115-
116104

117105
class FakeModelContext(ModelContext):
118106
async def train(self, sources: Sources):

tests/test_feature.py

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,6 @@ def test_default_dtype(self):
107107
def test_default_length(self):
108108
self.assertEqual(self.feature.length(), 1)
109109

110-
async def test_default_applicable(self):
111-
self.assertEqual(await self.feature.applicable(Data("test")), True)
112-
113110
def test_load_def(self):
114111
feature = Feature.load_def("test", "float", 10)
115112
self.assertEqual(feature.NAME, "test")
@@ -144,28 +141,3 @@ async def test_names(self):
144141
names = self.features.names()
145142
for check in ["one", "two", "three"]:
146143
self.assertIn(check, names)
147-
148-
async def test_applicable(self):
149-
async with self.features:
150-
applicable = await self.features.applicable("test")
151-
self.assertIn(self.one, applicable)
152-
self.assertIn(self.two, applicable)
153-
self.assertNotIn(self.three, applicable)
154-
155-
async def test_evaluate(self):
156-
async with self.features:
157-
results = await self.features.evaluate("test")
158-
self.assertIn(self.one.NAME, results)
159-
self.assertIn(self.two.NAME, results)
160-
self.assertNotIn(self.three.NAME, results)
161-
self.assertEqual(results[self.one.NAME], False)
162-
self.assertEqual(results[self.two.NAME], True)
163-
164-
async def test_one_applicable_other_not(self):
165-
twob = TwoBFeatureTester()
166-
features = Features(self.two, twob)
167-
async with features:
168-
results = await features.evaluate("test")
169-
self.assertIn(self.two.NAME, results)
170-
self.assertEqual(len(results), 1)
171-
self.assertEqual(results[self.two.NAME], True)

0 commit comments

Comments
 (0)