Giter VIP home page Giter VIP logo

constantly's Introduction

Twisted

gitter rtd pypi ci

For information on changes in this release, see the NEWS file.

What is this?

Twisted is an event-based framework for internet applications, supporting Python 3.6+. It includes modules for many different purposes, including the following:

  • twisted.web: HTTP clients and servers, HTML templating, and a WSGI server
  • twisted.conch: SSHv2 and Telnet clients and servers and terminal emulators
  • twisted.words: Clients and servers for IRC, XMPP, and other IM protocols
  • twisted.mail: IMAPv4, POP3, SMTP clients and servers
  • twisted.positioning: Tools for communicating with NMEA-compatible GPS receivers
  • twisted.names: DNS client and tools for making your own DNS servers
  • twisted.trial: A unit testing framework that integrates well with Twisted-based code.

Twisted supports all major system event loops -- select (all platforms), poll (most POSIX platforms), epoll (Linux), kqueue (FreeBSD, macOS), IOCP (Windows), and various GUI event loops (GTK+2/3, Qt, wxWidgets). Third-party reactors can plug into Twisted, and provide support for additional event loops.

Installing

To install the latest version of Twisted using pip:

$ pip install twisted

Additional instructions for installing this software are in the installation instructions.

Documentation and Support

Twisted's documentation is available from the Twisted Matrix website. This documentation contains how-tos, code examples, and an API reference.

Help is also available on the Twisted mailing list.

There is also an IRC channel, #twisted, on the Libera.Chat network. A web client is available at web.libera.chat.

Unit Tests

Twisted has a comprehensive test suite, which can be run by tox:

$ tox -l                       # to view all test environments
$ tox -e nocov                 # to run all the tests without coverage
$ tox -e withcov               # to run all the tests with coverage
$ tox -e alldeps-withcov-posix # install all dependencies, run tests with coverage on POSIX platform

You can test running the test suite under the different reactors with the TWISTED_REACTOR environment variable:

$ env TWISTED_REACTOR=epoll tox -e alldeps-withcov-posix

Some of these tests may fail if you:

  • don't have the dependencies required for a particular subsystem installed,
  • have a firewall blocking some ports (or things like Multicast, which Linux NAT has shown itself to do), or
  • run them as root.

Static Code Checkers

You can ensure that code complies to Twisted coding standards:

$ tox -e lint   # run pre-commit to check coding stanards
$ tox -e mypy   # run MyPy static type checker to check for type errors

Or, for speed, use pre-commit directly:

$ pipx run pre-commit run

Copyright

All of the code in this distribution is Copyright (c) 2001-2024 Twisted Matrix Laboratories.

Twisted is made available under the MIT license. The included LICENSE file describes this in detail.

Warranty

THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE USE OF THIS SOFTWARE IS WITH YOU.

IN NO EVENT WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY, BE LIABLE TO YOU FOR ANY DAMAGES, EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

Again, see the included LICENSE file for specific legal details.

constantly's People

Contributors

adiroiban avatar exarkun avatar glyph avatar graingert avatar hawkowl avatar julian avatar markrwilliams avatar mithrandi avatar twm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

constantly's Issues

Support py3.12

  ==> python3.12 -m pip --python=/home/linuxbrew/.linuxbrew/Cellar/magic-wormhole/0.13.0/libexec/bin/python install --verbose --no-deps --no-binary=:all: --ignore-installed --no-compile /tmp/magic-wormhole--constantly-20231017-7702-1ep4os7/constantly-15.1.0
  Using pip 23.2.1 from /home/linuxbrew/.linuxbrew/lib/python3.12/site-packages/pip (python 3.12)
  Processing /tmp/magic-wormhole--constantly-20231017-7702-1ep4os7/constantly-15.1.0
    Preparing metadata (setup.py): started
    Running command python setup.py egg_info
    /tmp/magic-wormhole--constantly-20231017-7702-1ep4os7/constantly-15.1.0/versioneer.py:467: SyntaxWarning: invalid escape sequence '\s'
      LONG_VERSION_PY['git'] = '''
    Traceback (most recent call last):
      File "<string>", line 2, in <module>
      File "<pip-setuptools-caller>", line 34, in <module>
      File "/tmp/magic-wormhole--constantly-20231017-7702-1ep4os7/constantly-15.1.0/setup.py", line 41, in <module>
        version=versioneer.get_version(),
                ^^^^^^^^^^^^^^^^^^^^^^^^
      File "/tmp/magic-wormhole--constantly-20231017-7702-1ep4os7/constantly-15.1.0/versioneer.py", line 1405, in get_version
        return get_versions()["version"]
               ^^^^^^^^^^^^^^
      File "/tmp/magic-wormhole--constantly-20231017-7702-1ep4os7/constantly-15.1.0/versioneer.py", line 1339, in get_versions
        cfg = get_config_from_root(root)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/tmp/magic-wormhole--constantly-20231017-7702-1ep4os7/constantly-15.1.0/versioneer.py", line 399, in get_config_from_root
        parser = configparser.SafeConfigParser()
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    AttributeError: module 'configparser' has no attribute 'SafeConfigParser'. Did you mean: 'RawConfigParser'?
    error: subprocess-exited-with-error

relates to Homebrew/homebrew-core#151475

License not bundled into package

Our project collects licenses from the Python packages that it depends on to put into 1 place to make available to our customers. THis is failing for constantly because it does not bundle the license file.

Cleanup CI

It looks like Travis-CI was setup only to update the docs via GH pages..

But I can see that the docs are published via RTD.

See if we can enable some tests via GitHub Actions

Add proper support for constant aliases

(Apologies in advance if I'm not using the right terminology, and for the wall of text.)

I'd like to be able to add aliases for some of my constants. As an example, I'm writing a TFTP library, and the TFTP spec uses some terminology that might be unfamiliar to users, so I'd like to be able to alias the older terms to newer, more familiar terms, while still giving access to the old terms as well. There seem to be a couple ways to do this, but neither has the full behavior I want.

What I want to see is for each constant, regardless of whether it's an alias or not, to report itself in __repr__() (i.e. self.name) as the name it was declared with, but also for constants with the same value to report themselves as equal. I don't especially care about sorting order in this case, but it would make sense to me to order them according to their values rather than their declared order.

The first way to declare aliases is as follows:

class TransferMode(constantly.Values):
    """Representation of the different transfer modes. Also includes some convenient aliases.

    The various transfer modes are defined in RFC 1350.
    """
    NETASCII = constantly.ValueConstant("netascii")
    OCTET = constantly.ValueConstant("octet")
    MAIL = constantly.ValueConstant("mail")
    ASCII = constantly.ValueConstant("netascii")
    TEXT = constantly.ValueConstant("netascii")
    BINARY = constantly.ValueConstant("octet")
>>> TransferMode.NETASCII
<TransferMode=NETASCII>
>>> TransferMode.OCTET
<TransferMode=OCTET>
>>> TransferMode.MAIL
<TransferMode=MAIL>
>>> TransferMode.ASCII
<TransferMode=ASCII>
>>> TransferMode.TEXT
<TransferMode=TEXT>
>>> TransferMode.BINARY
<TransferMode=BINARY>
>>> TransferMode.NETASCII == TransferMode.ASCII
False

This gives me the first part (each constant reports itself as the name it was declared with), but it doesn't give me the second part (that is, TransferMode.NETASCII == TransferMode.ASCII is False when I'd like it to be True).

The second way to do aliases is as follows:

class TransferMode(constantly.Values):
    """Representation of the different transfer modes. Also includes some convenient aliases.

    The various transfer modes are defined in RFC 1350.
    """
    NETASCII = constantly.ValueConstant("netascii")
    OCTET = constantly.ValueConstant("octet")
    MAIL = constantly.ValueConstant("mail")
    ASCII = NETASCII
    TEXT = NETASCII
    BINARY = OCTET
>>> TransferMode.NETASCII
<TransferMode=TEXT>
>>> TransferMode.OCTET
<TransferMode=OCTET>
>>> TransferMode.MAIL
<TransferMode=MAIL>
>>> TransferMode.ASCII
<TransferMode=TEXT>
>>> TransferMode.TEXT
<TransferMode=TEXT>
>>> TransferMode.BINARY
<TransferMode=OCTET>
>>> TransferMode.NETASCII == TransferMode.ASCII
True

When I do this, I get TransferMode.NETASCII == TransferMode.ASCII like I want, but now NETASCII and ASCII report themselves as TEXT, when I would expect them to report themselves as NETASCII and ASCII, respectively. I don't see the same thing happen to OCTET after declaring BINARY = OCTET, but BINARY does report itself as OCTET. The sorting order seems to be kept the same and I can still look up all of the constants by name. Placing the declaration of BINARY a line before the declaration of TEXT doesn't change the sorting behavior, so it's not quite like the constant is being treated as though it were redefined where TEXT was defined.

TransferMode.iterconstants() reports all six declared constants, but with the wrong names for half of them.

>>> TransferMode.lookupByName("NETASCII")
<TransferMode=TEXT>
>>> TransferMode.lookupByName("OCTET")    
<TransferMode=OCTET>
>>> TransferMode.lookupByName("MAIL")  
<TransferMode=MAIL>
>>> TransferMode.lookupByName("ASCII") 
<TransferMode=TEXT>
>>> TransferMode.lookupByName("TEXT")  
<TransferMode=TEXT>
>>> TransferMode.lookupByName("BINARY") 
<TransferMode=OCTET>
>>> TransferMode.NETASCII < TransferMode.OCTET
True
>>> TransferMode.NETASCII < TransferMode.MAIL 
True
>>> TransferMode.OCTET < TransferMode.MAIL
True
>>> TransferMode.NETASCII == TransferMode.TEXT
True
>>> TransferMode.OCTET == TransferMode.BINARY
True
>>> for c in TransferMode.iterconstants():
...  print(c)
... 
<TransferMode=TEXT>
<TransferMode=TEXT>
<TransferMode=TEXT>
<TransferMode=OCTET>
<TransferMode=OCTET>
<TransferMode=MAIL>

Removing the declaration of TEXT reverts NETASCII to reporting itself as NETASCII, but now ASCII reports itself as NETASCII, too. It seems to indicate that the ValueConstant instance reports itself as whichever of its aliases is last in the English dictionary.


Flags similarly doesn't support aliasing, but it has an additional problem. Consider the following (highly simplified) example:

class Test(constantly.Flags):
  A = constantly.FlagConstant(1)
  B = constantly.FlagConstant(2)
  C = constantly.FlagConstant(1)
>>> Test.A | Test.C
<Test={A,C}>
>>> Test.A ^ Test.C
<Test={A,C}>
>>> ~Test.B
<Test={A,C}>

This is definitely not what should happen. Even ignoring the weird naming, Test.A ^ Test.C should be <Test={}>, not <Test={A,C}>! Those flags are no longer set! Using the second declaration style has correct bitwise results here, but it still has the same problems as ValueConstants.

It's also bad when one of the constants is a combination of other flags.

class Test(constantly.Flags):
  A = constantly.FlagConstant(1)
  B = constantly.FlagConstant(2)
  C = constantly.FlagConstant(3)
>>> Test.A | Test.C
<Test={A,C}>
>>> Test.A ^ Test.C
<Test={A,C}>
>>> ~Test.B
<Test=A>

~Test.B behaves properly now, and Test.A | Test.C and Test.A ^ Test.C behave like the last example. We can't even get there with the second declaration style, though, as declaring C = A | B complains AttributeError: 'FlagConstant' object has no attribute 'names' because A and B haven't been properly set up yet.


Regarding an actual solution to this, I think the easiest way to implement this for ValueConstants would be to redefine the comparison operators to compare self.value rather than self._index. That would sufficiently allow aliases using the first declaration method, though it would change the comparison ordering (IMO to something that makes better sense, but it is a noticeable interface change). It also still leaves the aliases listed in iterconstants(), which isn't ideal.

Because FlagConstants also have a value attribute, that implementation would begin to apply to them, too, in the most basic cases, but it still has the problem with bitwise operations. It also doesn't work very well if you're creating an alias representing multiple flags being set. Making aliases work properly for FlagConstant may require some overhaul of its internals.

NamedConstants don't have an associated value, so you'd have to add one to properly mimic the equality functionality. That could probably be as simple as a new alias_of() function (or class?) that copies the original constant's _index to the new alias. Equality checks would then compare _index first. This would also group all aliases of the same constant together when iterating over the class, and also give a good way to filter out aliases, which can apply to the other Constant types as well.

How feasible is this to add? The current behavior leaves a bit to be desired.

error installing constantly : ERROR conda.core.link:_execute(481):

Hi,

I tried to install SCRAPY by typing conda install scrapy

It gives an error with constantly. Then I tried to install constantly alone and I have an permission error:

PermissionError(13, 'Permission denied')

Here is what I have when the terminal get stuck:

mic@ubuntu:~$ conda install constantly
Solving environment: done

Package Plan

environment location: /home/mic/anaconda3

added / updated specs:
constantly

The following NEW packages will be INSTALLED:

constantly: 15.1.0-py36_0

Proceed ([y]/n)? y

Preparing transaction: done
Verifying transaction: done
Executing transaction: failed
ERROR conda.core.link:_execute(481): An error occurred while installing package >defaults::constantly-15.1.0-py36_0'.
PermissionError(13, 'Permission denied')
Attempting to roll back.

Rolling back transaction: done

PermissionError(13, 'Permission denied')

Anyone can help me with this ??

ValueConstants are not JSON serializable

In [1]: from constantly import Values, ValueConstant

In [2]: class Foo(Values):
   ...:     foo = ValueConstant('foo')
   ...:     bar = ValueConstant('bar')
   ...:

In [3]: import json

In [4]: json.dumps([Foo.foo, Foo.bar])
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-4-5375b22f7626> in <module>()
----> 1 json.dumps([Foo.foo, Foo.bar])

/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.pyc in dumps(obj, skipkeys, ensure_ascii, check_circular, allow_nan, cls, indent, separators, encoding, default, sort_keys, **kw)
    241         cls is None and indent is None and separators is None and
    242         encoding == 'utf-8' and default is None and not sort_keys and not kw):
--> 243         return _default_encoder.encode(obj)
    244     if cls is None:
    245         cls = JSONEncoder

/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.pyc in encode(self, o)
    205         # exceptions aren't as detailed.  The list call should be roughly
    206         # equivalent to the PySequence_Fast that ''.join() would do.
--> 207         chunks = self.iterencode(o, _one_shot=True)
    208         if not isinstance(chunks, (list, tuple)):
    209             chunks = list(chunks)

/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.pyc in iterencode(self, o, _one_shot)
    268                 self.key_separator, self.item_separator, self.sort_keys,
    269                 self.skipkeys, _one_shot)
--> 270         return _iterencode(o, 0)
    271
    272 def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,

/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.pyc in default(self, o)
    182
    183         """
--> 184         raise TypeError(repr(o) + " is not JSON serializable")
    185
    186     def encode(self, o):

TypeError: <Foo=foo> is not JSON serializable

I would expect Foo.foo to serialize to "foo", Foo.bar to serialize to "bar". In general, for a ValueConstant to serialize to whatever its value serializes to.

Add Python 3.5 to tox and trove classifiers

We test against Python 3.5:

matrix:
include:
- python: 3.5
env:
- TOX_ENV=py35
fast_finish: true

But we don't have an explicit tox enviroment for it:

envlist = {py27,pypy,py33,py34}-tests, pyflakes, cov, docs

Or a trove classifier:

constantly/setup.py

Lines 21 to 32 in 3189c1b

classifiers=[
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
'Topic :: Software Development :: Libraries :: Python Modules'
],

constantly should have both a Python 3.5 tox environment and trove classifier.

License not included in install from PyPi

image

I was going through the libraries I use to collect licenses since I distribute my application using pyqtdeploy on Windows and noticed that constantly did not seem to include it's own license when installed from PyPi.

RFE: is it possible to start making github releases?๐Ÿค”

On create github release entry is created email notification to those whom have set in your repo the web UI Watch->Releases.
gh release can contain additional comments (li changelog) or additional assets like release tar balls (by default it contains only assets from git tag) however all those part are not obligatory.
In simplest variant gh release can be empty because subiekt of the sent email contains git tag name.

I'm asking because my automation process uses those email notifications by trying to make preliminary automated upgrades of building packages, which allows saving some time on maintaining packaging procedures.
Probably other people may be interested to be instantly informed about release new version as well.

Documentation and examples of generate gh releases:
https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository
https://cli.github.com/manual/gh_release_upload/
jbms/sphinx-immaterial#282
https://github.com/marketplace/actions/github-release
https://pgjones.dev/blog/trusted-plublishing-2023/
jbms/sphinx-immaterial#281 (comment)
tox target to publish on pypi and make gh release https://github.com/jaraco/skeleton/blob/928e9a86d61d3a660948bcba7689f90216cc8243/tox.ini#L42-L58

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.