import collections (dynamic class targeting EASY FIX)

Open
#713 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
25/100
Issue type
Feature
Clarity
Needs clarification
Activity status
Stale
Tech stack
javascript, python
Domain
compilers

Research direction

The issue identifies collections.py and the namedtuple function as the relevant entry points; start by reviewing how Transcrypt handles imports and dynamically generated classes. Compare behavior with the pysc2 Feature example and define completion as supporting the requested collections usage without requiring a manually generated local copy.

Written by the indexing model from the issue text.

Description

STATE: under consideration

Context:
I am using Transcrypt to convert the code in this repository:
https://github.com/deepmind/pysc2
to javascript.

Problem:
I can't import collections, therefore I cant target the classes that are generated by collections, for example:

class Feature(collections.namedtuple(
    "Feature", ["index", "name", "layer_set", "full_name", "scale", "type",
                "palette", "clip"])):

Solution:
Create a local copy of 'collections' module in a file named collections.py. Modify the namedtuple function to print the class or write the stringified class template to a target directory. I took the code from collections (python version 2) to make the following method:

def print_class(typename, field_names):
    numfields = len(field_names)
    argtxt = repr(field_names).replace("'", "")[1:-1]   # tuple repr without parens or quotes
    reprtxt = ', '.join('%s=%%r' % name for name in field_names)
    template = '''class %(typename)s(tuple):
        '%(typename)s(%(argtxt)s)' \n
        __slots__ = () \n
        _fields = %(field_names)r \n
        def __new__(_cls, %(argtxt)s):
            'Create new instance of %(typename)s(%(argtxt)s)'
            return _tuple.__new__(_cls, (%(argtxt)s)) \n
        @classmethod
        def _make(cls, iterable, new=tuple.__new__, len=len):
            'Make a new %(typename)s object from a sequence or iterable'
            result = new(cls, iterable)
            if len(result) != %(numfields)d:
                raise TypeError('Expected %(numfields)d arguments, got %%d' %% len(result))
            return result \n
        def __repr__(self):
            'Return a nicely formatted representation string'
            return '%(typename)s(%(reprtxt)s)' %% self \n
        def _asdict(self):
            'Return a new OrderedDict which maps field names to their values'
            return OrderedDict(zip(self._fields, self)) \n
        def _replace(_self, **kwds):
            'Return a new %(typename)s object replacing specified fields with new values'
            result = _self._make(map(kwds.pop, %(field_names)r, _self))
            if kwds:
                raise ValueError('Got unexpected field names: %%r' %% kwds.keys())
            return result \n
        def __getnewargs__(self):
            'Return self as a plain tuple.  Used by copy and pickle.'
            return tuple(self) \n\n''' % locals()
    for i, name in enumerate(field_names):
        template += "        %s = _property(_itemgetter(%d), doc='Alias for field number %d')\n" % (name, i, i)
  
    print(template)

The function print_class is called inside the namedtuple method inside of the collections.py file.
This way, anytime a class is dynamically generated at run time, I can then go back and target the classes that the collections module would have been using internally. Easy peasy.

I know its hacky as hell, but it got the job done. And I believe that this approach could be used to ease the burden of developers utilizing Transcrypt to develop javascript projects from existing python projects.

Dominant language
Python
Stars
2.9k
Forks
218
PR merge metrics
No merged PRs in 30d

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from TranscryptOrg/Transcrypt

All issues in TranscryptOrg/Transcrypt

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.