Compare commits

...

13 commits

Author SHA1 Message Date
Aliaksei Yaletski (Tiendil)
b799ba1d11 updated python versions for github actions 2024-12-17 09:39:52 +01:00
Aliaksei Yaletski (Tiendil)
f441d7c122 Updated README.rst 2024-12-16 18:57:39 +01:00
Aliaksei Yaletski (Tiendil)
5e04edce53 Finish 0.2.4 2021-11-09 13:24:06 +03:00
Aliaksei Yaletski (Tiendil)
57635e2bdd Support Python 3.10, drop support of Python 3.5 2021-11-09 13:23:38 +03:00
Tiendil
ae103165cb Finish 0.2.3 2020-10-06 14:42:18 +03:00
Tiendil
0ea5d2ff3c Finish 0.2.3 2020-10-06 14:42:18 +03:00
Tiendil
43eb9fafac update gitignore 2020-10-06 14:41:36 +03:00
Tiendil
b09704a4f4 Версия 0.2.3 2020-10-06 14:36:21 +03:00
Aliaksei Yaletski
da45eaaac3
Актуализирована лицензия 2017-11-04 16:33:15 +03:00
Tiendil
20c3baa828 Исправлена ошибка в мужском суффиксе у DnD эльфов 2017-01-13 21:52:40 +03:00
Tiendil
f7ac5046f1 Finish 0.2.2 2016-12-04 17:07:00 +03:00
Tiendil
0d77c4ca3a Версия 0.2.2 2016-12-04 17:06:24 +03:00
Tiendil
22b14793b6 Иправлена ошибка при открытии юникодных файлов в Python 3 2016-10-25 19:03:14 +03:00
18 changed files with 177 additions and 142 deletions

26
.github/workflows/run_tests.yml vendored Normal file
View file

@ -0,0 +1,26 @@
name: Run tests
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install poetry
poetry install
- name: Run Tests
run: poetry run python -m unittest discover pynames

1
.gitignore vendored
View file

@ -1,4 +1,5 @@
*.pyc
*~
*.egg-info
*.eggs
dist

44
LICENSE
View file

@ -1,25 +1,29 @@
Copyright 2012 Aleksey Yeletsky. All rights reserved.
BSD 3-Clause License
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
Copyright (c) 2012, Yaletski Aliaksei
All rights reserved.
1. Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
2. Redistributions in binary form must reproduce the above copyright notice, this list
of conditions and the following disclaimer in the documentation and/or other materials
provided with the distribution.
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
The views and conclusions contained in the software and documentation are those of the
authors and should not be interpreted as representing official policies, either expressed
or implied, of <copyright holder>.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -1,3 +0,0 @@
global-include *.json
global-include *.csv
global-include *.rst

View file

@ -1,61 +1,65 @@
==================================
PYNAMES — names generation library
==================================
===================================
PYNAMES — Name Generation Library
===================================
Pynames intended for generation of all sorts of names. Currently it implements generators for character names of different races and cultures:
Pynames is a library designed for generating various types of names. It currently supports name generators for characters of different races and cultures, including:
* Scandinavian: traditional names;
* Russian: pagan names;
* Mongolian: traditional names;
* Korean: traditional names;
* Elven: DnD names;
* Elven: Warhammer names;
* Goblins: custom names;
* Orcs: custom names;
* Iron Kingdoms: caspian midlunder sulese;
* Iron Kingdoms: dwarf;
* Iron Kingdoms: gobber;
* Iron Kingdoms: iossan nyss;
* Iron Kingdoms: khadoran;
* Iron Kingdoms: ogrun;
* Iron Kingdoms: ryn;
* Iron Kingdoms: thurian morridane;
* Iron Kingdoms: tordoran;
* Iron Kingdoms: trollkin.
* **Scandinavian**: traditional names
* **Russian**: pagan names
* **Mongolian**: traditional names
* **Korean**: traditional names
* **Elven**:
* DnD
* Warhamme
* **Goblins**: custom names
* **Orcs**: custom names
* **Iron Kingdoms**:
* Caspian, Midlunder, Sulese
* Dwarf
* Gobber
* Iossan, Nyss
* Khadoran
* Ogrun
* Ryn
* Thurian, Morridane
* Tordoran
* Trollkin
There are two supported languages : English & Russian. Russian language names are generated with forms for every case of a noun and time.
The library supports two languages: **English** and **Russian**. For Russian, names are generated with forms for every grammatical case and tense.
Currently implemented two generation algorithms:
Two name generation algorithms are implemented:
* ``pynames.from_list_generator`` — names are created from list of predefined words;
* ``pynames.from_table_generator`` — names are created using templates, every part of template is gotten from separate table;
* ``pynames.from_list_generator`` — names are created from a predefined list of words.
* ``pynames.from_table_generator`` — names are created using templates, with each part of the template drawn from a separate table.
The library is easily extensible. If you need extra functionality (including new languages), please, contact me, post an issue, or just make a pull request.
The library is highly extensible. If you need additional functionality (including support for new languages), feel free to contact the author, post an issue, or submit a pull request.
*************
Installation
*************
Install the library via pip:
::
pip install pynames
*************
********
Usage
*************
********
.. code:: python
from pynames import GENDER, LANGUAGE
All generators are divided by "races", so that all generators of elven names are placed in the module ``pynames.generators.elven``, etc.
All generators are organized by "races," so, for instance, all elven name generators are in the module ``pynames.generators.elven``.
.. code:: python
from pynames.generators.elven import DnDNamesGenerator
elven_generator = DnDNamesGenerator()
Number of different names (male and female) and for each gender separately.
You can retrieve the total number of unique names or the count for a specific gender:
.. code:: python
@ -68,7 +72,7 @@ Number of different names (male and female) and for each gender separately.
In [6]: elven_generator.get_names_number(GENDER.FEMALE)
Out[6]: 976474968
Fast random name generation.
Generate random names quickly:
.. code:: python
@ -81,10 +85,10 @@ Fast random name generation.
In [9]: elven_generator.get_name_simple(GENDER.MALE, LANGUAGE.EN) # English
Out[9]: u'Mararon'
In [10]: print elven_generator.get_name_simple(GENDER.MALE, LANGUAGE.RU) # Russian
In [10]: print(elven_generator.get_name_simple(GENDER.MALE, LANGUAGE.RU)) # Russian
Ттомусиэл
Instead of text, you can get the Name object with additional functionality.
Instead of just text, you can retrieve a `Name` object with additional functionality:
.. code:: python
@ -106,7 +110,7 @@ Instead of text, you can get the Name object with additional functionality.
u"\u0430\u044d'\u0410\u043d\u0433\u0430\u0438\u0442\u0442\u043d\u0438\u0438\u043d\u0430\u043c\u0438",
u"\u0430\u044d'\u0410\u043d\u0433\u0430\u0438\u0442\u0442\u043d\u0438\u0438\u043d\u0430\u0445"]}}
In [13]: print u'\n'.join(name.get_forms_for(GENDER.MALE, language=LANGUAGE.RU))
In [13]: print(u'\n'.join(name.get_forms_for(GENDER.MALE, language=LANGUAGE.RU)))
аэ'Ангаиттниин
аэ'Ангаиттниина
аэ'Ангаиттниину

17
poetry.lock generated Normal file
View file

@ -0,0 +1,17 @@
[[package]]
name = "unicodecsv"
version = "0.14.1"
description = "Python2's stdlib csv module is nice, but it doesn't support unicode. This module is a drop-in replacement which *does*."
category = "main"
optional = false
python-versions = "*"
[metadata]
lock-version = "1.1"
python-versions = "^3.6"
content-hash = "a2dbfe0efb1a442b962c7ba3ba3b8426f520795bc6b7be369207178e4c320fae"
[metadata.files]
unicodecsv = [
{file = "unicodecsv-0.14.1.tar.gz", hash = "sha256:018c08037d48649a0412063ff4eda26eaa81eff1546dbffa51fa5293276ff7fc"},
]

View file

@ -23,9 +23,8 @@ class FromListGenerator(BaseGenerator):
error_msg = 'FromListGenerator: you must make subclass of FromListGenerator and define attribute SOURCE in it.'
raise NotImplementedError(error_msg)
with open(self.SOURCE) as f:
names_data = json.load(f, encoding='utf-8')
with open(self.SOURCE, encoding='utf-8') as f:
names_data = json.load(f)
self.native_language = names_data['native_language']
self.languages = set(names_data['languages'])
self.full_forms_for_languages = set(names_data.get('full_forms_for_languages', set()))

View file

@ -5,10 +5,9 @@ from __future__ import unicode_literals
# python lib:
import json
import random
from collections import Iterable
from collections.abc import Iterable
# thirdparties:
import six
import unicodecsv
# pynames:
@ -42,15 +41,15 @@ class Template(object):
@classmethod
def merge_forms(cls, left, right):
if not isinstance(left, six.string_types):
if not isinstance(right, six.string_types):
if not isinstance(left, str):
if not isinstance(right, str):
if len(left) != len(right):
raise exceptions.NotEqualFormsLengths(left=left, right=right)
return [l+r for l, r in zip(left, right)]
else:
return [l+right for l in left]
else:
if not isinstance(right, six.string_types):
if not isinstance(right, str):
return [left+r for r in right]
else:
return left + right
@ -63,7 +62,7 @@ class Template(object):
record = random.choice(tables[slug])
languages = {
lang: self.merge_forms(forms, record['languages'][lang])
for lang, forms in six.iteritems(languages)
for lang, forms in languages.items()
}
genders = dict(
@ -141,7 +140,7 @@ class FromTablesGenerator(BaseGenerator):
templates = self._get_templates_slice(genders)
definition_number = sum([template.probability for template in templates])
choice = random.randint(1, definition_number)
choice = random.uniform(0.0, definition_number)
for template in templates:
if choice > template.probability:
@ -156,7 +155,7 @@ class FromTablesGenerator(BaseGenerator):
return name.get_for(gender, language)
def test_names_consistency(self, test):
for table_name, table in six.iteritems(self.tables):
for table_name, table in self.tables.items():
for record in table:
test.assertEqual(set(record['languages'].keys()) & self.languages, self.languages)

View file

@ -557,7 +557,7 @@
{"languages": {"en": "ael", "ru": ["аель","аеля","аелю","аеля","аелем","аеле","аели","аелей","аелям","аелей","аелями","аелях"]}},
{"languages": {"en": "aer", "ru": ["аер","аера","аеру","аера","аером","аере","аеры","аеров","аерам","аеров","аерами","аерах"]}},
{"languages": {"en": "aias", "ru": ["аиас","аиаса","аиасу","аиаса","аиасом","аиасе","аиасы","аиасов","аиасам","аиасов","аиасами","аиасах"]}},
{"languages": {"en": "ah", "ru": ["ах","ахи","ахе","аху","ахой","ахе","ахи","ахов","ахам","ахи","ахами","ахах"]}},
{"languages": {"en": "ah", "ru": ["ах","аха","аху","аха","ахом","ахе","ахи","ахов","ахам","ахов","ахами","ахах"]}},
{"languages": {"en": "aith", "ru": ["аитт","аитта","аитту","аитта","аиттом","аитте","аитты","аиттов","аиттам","аиттов","аиттами","аиттах"]}},
{"languages": {"en": "al", "ru": ["ал","ала","алу","ала","алом","але","алы","алов","алам","алов","алами","алах"]}},
{"languages": {"en": "la", "ru": ["ла","лы","ле","лу","лой","ле","лы","л","лам","л","лами","лах"]}},

View file

@ -2,8 +2,6 @@
from __future__ import unicode_literals
import six
from pynames.relations import GENDER, LANGUAGE
from pynames import exceptions
@ -24,7 +22,7 @@ class Name(object):
forms = self.translations[gender][language]
if not isinstance(forms, six.string_types):
if not isinstance(forms, str):
return forms[0]
return forms
@ -35,7 +33,7 @@ class Name(object):
forms = self.translations[gender][language]
if not isinstance(forms, six.string_types):
if not isinstance(forms, str):
return list(forms)
return None

View file

@ -5,8 +5,6 @@ from __future__ import unicode_literals
import os
import unittest
from six.moves import xrange
from pynames.relations import GENDER, LANGUAGE
from pynames.from_list_generator import FromListGenerator
@ -50,19 +48,19 @@ class TestFromListGenerator(unittest.TestCase):
def test_get_name__simple(self):
generator = self.TestGenerator()
for i in xrange(100):
for i in range(100):
name = generator.get_name_simple(gender=GENDER.MALE, language=LANGUAGE.RU)
self.assertTrue(name in self.NAMES_RU_MALE)
for i in xrange(100):
for i in range(100):
name = generator.get_name_simple(gender=GENDER.FEMALE, language=LANGUAGE.RU)
self.assertTrue(name in self.NAMES_RU_FEMALE)
for i in xrange(100):
for i in range(100):
name = generator.get_name_simple(gender=GENDER.MALE, language=LANGUAGE.EN)
self.assertTrue(name in self.NAMES_EN_MALE)
for i in xrange(100):
for i in range(100):
name = generator.get_name_simple(gender=GENDER.FEMALE, language=LANGUAGE.EN)
self.assertTrue(name in self.NAMES_EN_FEMALE)
@ -70,24 +68,24 @@ class TestFromListGenerator(unittest.TestCase):
def test_get_name__with_forms(self):
generator = self.TestGeneratorWithForms()
for i in xrange(100):
for i in range(100):
name = generator.get_name(genders=[GENDER.MALE])
self.assertTrue(name.get_for(GENDER.MALE, LANGUAGE.RU) in self.NAMES_RU_MALE)
self.assertNotEqual(name.get_forms_for(GENDER.MALE, LANGUAGE.RU), None)
self.assertTrue(name.get_forms_for(GENDER.MALE, LANGUAGE.RU)[1] in self.NAMES_RU_MALE_FORMS)
for i in xrange(100):
for i in range(100):
name = generator.get_name(genders=[GENDER.FEMALE])
self.assertTrue(name.get_for(GENDER.FEMALE, LANGUAGE.RU) in self.NAMES_RU_FEMALE)
self.assertNotEqual(name.get_forms_for(GENDER.FEMALE, LANGUAGE.RU), None)
self.assertTrue(name.get_forms_for(GENDER.FEMALE, LANGUAGE.RU)[1] in self.NAMES_RU_FEMALE_FORMS)
for i in xrange(100):
for i in range(100):
name = generator.get_name(genders=[GENDER.MALE])
self.assertTrue(name.get_for(GENDER.MALE, LANGUAGE.EN) in self.NAMES_EN_MALE)
self.assertEqual(name.get_forms_for(GENDER.MALE, LANGUAGE.EN), None)
for i in xrange(100):
for i in range(100):
name = generator.get_name(genders=[GENDER.FEMALE])
self.assertTrue(name.get_for(GENDER.FEMALE, LANGUAGE.EN) in self.NAMES_EN_FEMALE)
self.assertEqual(name.get_forms_for(GENDER.FEMALE, LANGUAGE.EN), None)

View file

@ -5,9 +5,6 @@ from __future__ import unicode_literals
import os
import unittest
import six
from six.moves import xrange
from pynames.relations import GENDER, LANGUAGE
from pynames.from_tables_generator import FromTablesGenerator, FromCSVTablesGenerator
@ -49,19 +46,19 @@ class TestFromTablesGenerator(unittest.TestCase):
def test_get_name_simple(self):
generator = self.TestGenerator()
for i in xrange(100):
for i in range(100):
name = generator.get_name_simple(gender=GENDER.MALE, language=LANGUAGE.RU)
self.assertTrue(name in self.NAMES_RU_MALE)
for i in xrange(100):
for i in range(100):
name = generator.get_name_simple(gender=GENDER.FEMALE, language=LANGUAGE.RU)
self.assertTrue(name in self.NAMES_RU_FEMALE)
for i in xrange(100):
for i in range(100):
name = generator.get_name_simple(gender=GENDER.MALE, language=LANGUAGE.EN)
self.assertTrue(name in self.NAMES_EN_MALE)
for i in xrange(100):
for i in range(100):
name = generator.get_name_simple(gender=GENDER.FEMALE, language=LANGUAGE.EN)
self.assertTrue(name in self.NAMES_EN_FEMALE)
@ -70,14 +67,14 @@ class TestFromTablesGenerator(unittest.TestCase):
has_none = set()
for i in xrange(100):
for i in range(100):
name = generator.get_name(genders=[GENDER.MALE])
self.assertTrue(name.get_for(GENDER.MALE, LANGUAGE.RU) in self.NAMES_RU_MALE)
has_none.add(name.get_forms_for(GENDER.MALE, LANGUAGE.RU) is None)
self.assertEqual(has_none, set([True, False]))
for i in xrange(100):
for i in range(100):
name = generator.get_name(genders=[GENDER.FEMALE])
self.assertTrue(name.get_for(GENDER.FEMALE, LANGUAGE.RU) in self.NAMES_RU_FEMALE)
self.assertNotEqual(name.get_forms_for(GENDER.FEMALE, LANGUAGE.RU), None)
@ -85,14 +82,14 @@ class TestFromTablesGenerator(unittest.TestCase):
has_none = set()
for i in xrange(100):
for i in range(100):
name = generator.get_name(genders=[GENDER.MALE])
self.assertTrue(name.get_for(GENDER.MALE, LANGUAGE.EN) in self.NAMES_EN_MALE)
has_none.add(name.get_forms_for(GENDER.MALE, LANGUAGE.RU) is None)
self.assertEqual(has_none, set([True, False]))
for i in xrange(100):
for i in range(100):
name = generator.get_name(genders=[GENDER.FEMALE])
self.assertTrue(name.get_for(GENDER.FEMALE, LANGUAGE.EN) in self.NAMES_EN_FEMALE)
self.assertEqual(name.get_forms_for(GENDER.FEMALE, LANGUAGE.EN), None)
@ -124,6 +121,6 @@ class TestFromCSVTablesGenerator(unittest.TestCase):
json_attr = getattr(json_generator, attr_name)
csv_attr = getattr(csv_generator, attr_name)
if isinstance(json_attr, list):
six.assertCountEqual(self, csv_attr, json_attr)
self.assertCountEqual(csv_attr, json_attr)
else:
self.assertEqual(csv_attr, json_attr)

View file

@ -21,7 +21,10 @@ def create_test_method(generator_class):
generator = generator_class()
self.assertTrue(generator.get_names_number() > 0)
self.assertTrue(generator.get_names_number(GENDER.MALE) + generator.get_names_number(GENDER.FEMALE) >= generator.get_names_number())
self.assertTrue(generator.get_names_number(GENDER.MALE) + generator.get_names_number(GENDER.FEMALE) >=
generator.get_names_number())
self.assertTrue(generator.get_name_simple())
self.assertTrue(generator.get_name())

View file

@ -2,7 +2,6 @@
from __future__ import unicode_literals
import six
import unittest
from pynames.relations import GENDER, LANGUAGE
@ -13,7 +12,7 @@ class TestName(unittest.TestCase):
def test_base(self):
name = Name('ru', {'genders': {'m': {'ru': 'ru_name'}}})
self.assertEqual(six.text_type(name), 'ru_name')
self.assertEqual(str(name), 'ru_name')
self.assertEqual(name.get_for(GENDER.MALE, LANGUAGE.RU), 'ru_name')
self.assertEqual(name.get_for(GENDER.MALE), 'ru_name')
self.assertEqual(name.get_forms_for(GENDER.MALE), None)
@ -21,7 +20,7 @@ class TestName(unittest.TestCase):
def test_genders(self):
name = Name('ru', {'genders': {'m': {'ru': 'ru_m_name'},
'f': {'ru': 'ru_f_name'}}})
self.assertEqual(six.text_type(name), 'ru_m_name')
self.assertEqual(str(name), 'ru_m_name')
self.assertEqual(name.get_for(GENDER.MALE, LANGUAGE.RU), 'ru_m_name')
self.assertEqual(name.get_for(GENDER.FEMALE, LANGUAGE.RU), 'ru_f_name')
@ -30,7 +29,7 @@ class TestName(unittest.TestCase):
'en': 'en_m_name'},
'f': {'ru': 'ru_f_name',
'en': 'en_f_name'}}})
self.assertEqual(six.text_type(name), 'ru_m_name')
self.assertEqual(str(name), 'ru_m_name')
self.assertEqual(name.get_for(GENDER.MALE, LANGUAGE.RU), 'ru_m_name')
self.assertEqual(name.get_for(GENDER.FEMALE, LANGUAGE.RU), 'ru_f_name')
self.assertEqual(name.get_for(GENDER.MALE, LANGUAGE.EN), 'en_m_name')

View file

@ -48,14 +48,14 @@ class TestName(unittest.TestCase):
test_file_path = os.path.join(root_dir, 'tests', 'fixtures', 'test_from_list_generator.json')
with open(test_file_path) as f:
with open(test_file_path, 'rb') as f:
target_content = f.read()
with file_adapter(test_file_path) as f:
self.assertEqual(f.read(), target_content)
django_file_object = ContentFile(target_content)
classic_file_object = open(test_file_path, 'r')
classic_file_object = open(test_file_path, 'rb')
for tested_file_object in [django_file_object, classic_file_object]:
with file_adapter(tested_file_object) as f:

View file

@ -51,11 +51,11 @@ def is_file(obj):
@contextlib.contextmanager
def file_adapter(file_or_path):
def file_adapter(file_or_path, mode='rb'):
"""Context manager that works similar to ``open(file_path)``but also accepts already openned file-like objects."""
if is_file(file_or_path):
file_obj = file_or_path
else:
file_obj = open(file_or_path, 'rb')
file_obj = open(file_or_path, mode)
yield file_obj
file_obj.close()

28
pyproject.toml Normal file
View file

@ -0,0 +1,28 @@
[tool.poetry]
name = "pynames"
version = "0.2.4"
description = "Name generation library."
readme = "README.rst"
repository = "https://github.com/Tiendil/pynames"
authors = ["Aliaksei Yaletski (Tiendil) <a.eletsky@gmail.com>"]
license = "BSD-3"
include = ["*.json", "*.csv", "*.rst"]
keywords = ["gamedev", "game", "game development", "names", "procedural content generation"]
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"Topic :: Games/Entertainment",
"Topic :: Software Development :: Libraries :: Python Modules",
"License :: OSI Approved :: BSD License",
"Natural Language :: English",
"Natural Language :: Russian"]
[tool.poetry.dependencies]
python = "^3.6"
unicodecsv = "^0.14"

View file

@ -1,35 +0,0 @@
# coding: utf-8
import setuptools
setuptools.setup(
name='Pynames',
version='0.2.1',
description='name generation library',
long_description = open('README.rst').read(),
url='https://github.com/Tiendil/pynames',
author='Aleksey Yeletsky <Tiendil>',
author_email='a.eletsky@gmail.com',
license='BSD',
classifiers=[
'Development Status :: 5 - Production/Stable',
'Intended Audience :: Developers',
'Topic :: Games/Entertainment',
'Topic :: Software Development :: Libraries :: Python Modules',
'License :: OSI Approved :: BSD License',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.5',
'Natural Language :: English',
'Natural Language :: Russian'],
keywords=['gamedev', 'game', 'game development', 'names', 'names generation'],
packages=setuptools.find_packages(),
install_requires=['six', 'unicodecsv'],
include_package_data=True,
test_suite = 'tests',
)