coalib.bearlib.languages package

Subpackages

Submodules

coalib.bearlib.languages.Language module

class coalib.bearlib.languages.Language.Language(*versions)[source]

Bases: object

This class defines programming languages and their versions.

You can define a new programming language as follows:

>>> @Language
... class TrumpScript:
...     __qualname__ = "America is great."
...     aliases = 'ts',
...     versions = 2.7, 3.3, 3.4, 3.5, 3.6
...     comment_delimiter = '#'
...     string_delimiter = {"'": "'"}

From a bear, you can simply parse the user given language string to get the instance of the Language you desire:

>>> Language['trumpscript']
America is great. 2.7, 3.3, 3.4, 3.5, 3.6
>>> Language['ts 3.4, 3.6']
America is great. 3.4, 3.6
>>> Language['TS 3']
America is great. 3.3, 3.4, 3.5, 3.6
>>> Language['tS 1']
Traceback (most recent call last):
 ...
ValueError: No versions left

All given versions will be stored as a sorted tuple of packaging.version.Version instances:

>>> Language.TrumpScript(3.4, 3.3).versions
(<Version('3.3')>, <Version('3.4')>)

The attributes are not accessible unless you have selected one - and only one - version of your language:

>>> Language.TrumpScript(3.3, 3.4).comment_delimiter
Traceback (most recent call last):
 ...
AttributeError: You have to specify ONE version ...
>>> Language.TrumpScript(3.3).comment_delimiter
'#'

If you don’t know which version is the right one, just use this:

>>> Language.TrumpScript().get_default_version()
America is great. 3.6

To see which attributes are available, use the attributes property:

>>> Language.TrumpScript(3.3).attributes
['comment_delimiter', 'string_delimiter']

You can access a dictionary of the attribute values for every version from the class:

>>> Language.TrumpScript.comment_delimiter
OrderedDict([(<Version('2.7')>, '#'), (<Version('3.3')>, '#'), (<Version('3.4')>, '#'), (<Version('3.5')>, '#'), (<Version('3.6')>, '#')])

Any nonexistent item will of course not be served:

>>> Language.TrumpScript.unknown_delimiter
Traceback (most recent call last):
 ...
AttributeError

You now know the most important parts for writing a bear using languages. Read ahead if you want to know more about working with multiple versions of programming languages as well as derivative languages!

We can define derivative languages as follows:

>>> @Language
... class TrumpScriptDerivative(Language.TrumpScript):
...     __qualname__ = 'Shorter'
...     comment_delimiter = '//'
...     keywords = None
>>> Language.TrumpScriptDerivative()
Shorter 2.7, 3.3, 3.4, 3.5, 3.6
>>> Language.TrumpScriptDerivative().get_default_version().attributes
['comment_delimiter', 'keywords', 'string_delimiter']
>>> Language.TrumpScriptDerivative().get_default_version().keywords
>>> Language.TrumpScriptDerivative().get_default_version().comment_delimiter
'//'
>>> Language.TrumpScriptDerivative().get_default_version().string_delimiter
{"'": "'"}

We can get an instance via this syntax as well:

>>> Language[Language.TrumpScript]
America is great. 2.7, 3.3, 3.4, 3.5, 3.6
>>> Language[Language.TrumpScript(3.6)]
America is great. 3.6

As you see, you can use the __qualname__ property. This will also affect the string representation and work as an implicit alias:

>>> str(Language.TrumpScript(3.4))
'America is great. 3.4'

We can specify the version by instantiating the TrumpScript class now:

>>> str(Language.TrumpScript(3.6))
'America is great. 3.6'

You can also define ranges of versions of languages:

>>> (Language.TrumpScript > 3.3) <= 3.5
America is great. 3.4, 3.5
>>> Language.TrumpScript == 3
America is great. 3.3, 3.4, 3.5, 3.6

Those can be combined by the or operator:

>>> (Language.TrumpScript == 3.6) | (Language.TrumpScript == 2)
America is great. 2.7, 3.6

The __contains__ operator of the class is defined as well for strings and instances. This is case insensitive and aliases are allowed:

>>> Language.TrumpScript(3.6) in Language.TrumpScript
True
>>> 'ts 3.6, 3.5' in Language.TrumpScript
True
>>> 'TrumpScript 2.6' in Language.TrumpScript
False
>>> 'TrumpScript' in Language.TrumpScript
True

This also works on instances:

>>> 'ts 3.6, 3.5' in (Language.TrumpScript == 3)
True
>>> 'ts 3.6,3.5' in ((Language.TrumpScript == 2)
...                  | Language.TrumpScript(3.5))
False
>>> Language.TrumpScript(2.7, 3.5) in (Language.TrumpScript == 3)
False
>>> Language.TrumpScript(3.5) in (Language.TrumpScript == 3)
True

Any undefined language will obviously not be available:

>>> Language.Cobol
Traceback (most recent call last):
 ...
UnknownLanguageError: No language found for `Cobol`
attributes

Retrieves the names of all attributes that are available for this language.

get_default_version()[source]

Retrieves the latest version the user would want to choose from the given versions in self.

(At a later point this might also retrieve a default version specifiable by the language definition, so keep using this!)

versions = ()
class coalib.bearlib.languages.Language.LanguageMeta(clsname, bases, clsattrs)[source]

Bases: type

Metaclass for coalib.bearlib.languages.Language.Language.

Allows it being used as a decorator as well as implements the __contains__() operation and stores all languages created with the decorator.

Ensures that .versions defined in language classes will be turned into sorted tuples of packaging.version.Version instances.

The operators are defined on the class as well, so you can do the following:

>>> @Language
... class SomeLang:
...     versions = 2.7, 3.3, 3.4, 3.5, 3.6
>>> Language.SomeLang > 3.4
SomeLang 3.5, 3.6
>>> Language.SomeLang < 3.4
SomeLang 2.7, 3.3
>>> Language.SomeLang >= 3.4
SomeLang 3.4, 3.5, 3.6
>>> Language.SomeLang <= 3.4
SomeLang 2.7, 3.3, 3.4
>>> Language.SomeLang == 3.4
SomeLang 3.4
>>> Language.SomeLang != 3.4
SomeLang 2.7, 3.3, 3.5, 3.6
>>> Language.SomeLang == 1.0
Traceback (most recent call last):
 ...
ValueError: No versions left
class coalib.bearlib.languages.Language.LanguageUberMeta[source]

Bases: type

This class is used to hide the all attribute from the Language class.

all = [<class 'coalib.bearlib.languages.Language.Unknown'>, <class 'coalib.bearlib.languages.Language.C'>, <class 'coalib.bearlib.languages.Language.CPP'>, <class 'coalib.bearlib.languages.Language.C#'>, <class 'coalib.bearlib.languages.Language.CSS'>, <class 'coalib.bearlib.languages.Language.Fortran'>, <class 'coalib.bearlib.languages.Language.Golang'>, <class 'coalib.bearlib.languages.Language.Hypertext Markup Language'>, <class 'coalib.bearlib.languages.Language.Java'>, <class 'coalib.bearlib.languages.Language.JavaScript'>, <class 'coalib.bearlib.languages.Language.JavaServer Pages'>, <class 'coalib.bearlib.languages.Language.Matlab'>, <class 'coalib.bearlib.languages.Language.Markdown'>, <class 'coalib.bearlib.languages.Language.ObjectiveC'>, <class 'coalib.bearlib.languages.Language.PHP'>, <class 'coalib.bearlib.languages.Language.PLSQL'>, <class 'coalib.bearlib.languages.Language.Python'>, <class 'coalib.bearlib.languages.Language.Ruby'>, <class 'coalib.bearlib.languages.Language.Scala'>, <class 'coalib.bearlib.languages.Language.Swift'>, <class 'coalib.bearlib.languages.Language.Vala'>, <class 'coalib.bearlib.languages.Language.TypeScript'>, <class 'coalib.bearlib.languages.Language.Shell'>, <class 'coalib.bearlib.languages.Language.Jinja2'>]
class coalib.bearlib.languages.Language.Languages[source]

Bases: tuple

A tuple-based container for coalib.bearlib.languages.Language instances. It supports language identifiers in any format accepted by Language[...]:

>>> Languages(['C#', Language.Python == 3])
(C#, Python 3.3, 3.4, 3.5, 3.6)
>>> Languages(['C#', Language.Python == '3.6'])
(C#, Python 3.6)
>>> Languages(['C#', 'Python 2.7'])
(C#, Python 2.7)

It provides __contains__() for checking if a given language identifier is included:

>>> 'Python 2.7, 3.5' in Languages([Language.Python()])
True
>>> 'Py 3.3' in Languages(['Python 2'])
False
>>> 'csharp' in Languages(['C#', Language.Python == 3.6])
True
exception coalib.bearlib.languages.Language.UnknownLanguageError[source]

Bases: AttributeError, KeyError

This exception occurs when an unknown language is requested.

coalib.bearlib.languages.Language.limit_versions(language, limit, operator)[source]

Limits given languages with the given operator:

Parameters:
  • language – A Language instance.
  • limit – A number to limit the versions.
  • operator – The operator to use for the limiting.
Returns:

A new Language instance with limited versions.

Raises:

ValueError – If no version is left anymore.

coalib.bearlib.languages.Language.parse_lang_str(string)[source]

Parses any given language string into name and a list of either int, float, or str versions (ignores leading whitespace):

>>> parse_lang_str("Python")
('Python', [])
>>> parse_lang_str("Python 3.3")
('Python', [3.3])
>>> parse_lang_str("Python 3.6, 3.3.1")
('Python', [3.6, '3.3.1'])
>>> parse_lang_str("Objective C 3.6, 3")
('Objective C', [3.6, 3])
>>> parse_lang_str("Cobol, stupid!")
Traceback (most recent call last):
 ...
packaging.version.InvalidVersion: Invalid version: 'stupid!'
>>> parse_lang_str("Cobol seems at least stupid ;)")
('Cobol seems at least stupid ;)', [])

coalib.bearlib.languages.LanguageDefinition module

class coalib.bearlib.languages.LanguageDefinition.LanguageDefinition(language: str, coalang_dir=None)[source]

Bases: coalib.bearlib.abstractions.SectionCreatable.SectionCreatable

This class is deprecated! Use the Language class instead.

A Language Definition holds constants which may help parsing the language. If you want to write a bear you’ll probably want to use those definitions to keep your bear independent of the semantics of each language.

You can easily get your language definition by just creating it with the name of the language desired:

>>> list(LanguageDefinition("cpp")['extensions'])
['.c', '.cpp', '.h', '.hpp']

For some languages aliases exist, the name is case insensitive; they will behave just like before and return settings:

>>> dict(LanguageDefinition('C++')['comment_delimiter'])
{'//': ''}
>>> dict(LanguageDefinition('C++')['string_delimiters'])
{'"': '"'}

If no language exists, you will get a FileNotFoundError:

>>> LanguageDefinition("BULLSHIT!")
Traceback (most recent call last):
 ...
FileNotFoundError

Custom coalangs are no longer supported. You can simply register your languages to the Languages decorator. When giving a custom coalang directory a warning will be emitted and it will attempt to load the given Language anyway through conventional means:

>>> LanguageDefinition("custom", coalang_dir='somewhere')
Traceback (most recent call last):
 ...
FileNotFoundError

If you need a custom language, just go like this:

>>> @Language
... class MyLittlePony:
...     color = 'green'
...     legs = 5
>>> int(LanguageDefinition('mylittlepony')['legs'])
5

But seriously, just use Language - and mind that it’s already typed:

>>> Language['mylittlepony'].get_default_version().legs
5

Module contents

This directory holds means to get generic information for specific languages.