Skip Navigation

InitialsDiceBearhttps://github.com/dicebear/dicebearhttps://creativecommons.org/publicdomain/zero/1.0/„Initials” (https://github.com/dicebear/dicebear) by „DiceBear”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/)L
Posts
7
Comments
320
Joined
2 yr. ago

  • so for 1 byte characters has both upper and lower case forms

     
        
    def keysym_group(ks1, ks2):
        """Generates a group from two *keysyms*.
    
        The implementation of this function comes from:
    
            Within each group, if the second element of the group is ``NoSymbol``,
            then the group should be treated as if the second element were the same
            as the first element, except when the first element is an alphabetic
            *KeySym* ``K`` for which both lowercase and uppercase forms are
            defined.
    
            In that case, the group should be treated as if the first element were
            the lowercase form of ``K`` and the second element were the uppercase
            form of ``K``.
    
        This function assumes that *alphabetic* means *latin*; this assumption
        appears to be consistent with observations of the return values from
        ``XGetKeyboardMapping``.
    
        :param ks1: The first *keysym*.
    
        :param ks2: The second *keysym*.
    
        :return: a tuple conforming to the description above
        """
    
      
  • Solves the mystery of the repeating entries

    1 2 and 3 bytes unicode to corresponding keysym

    mapped into that tuple. Seems author likes the number 4.

     
        
    def keysym_normalize(keysym):
        """Normalises a list of *keysyms*.
    
        The implementation of this function comes from:
    
            If the list (ignoring trailing ``NoSymbol`` entries) is a single
            *KeySym* ``K``, then the list is treated as if it were the list
            ``K NoSymbol K NoSymbol``.
    
            If the list (ignoring trailing ``NoSymbol`` entries) is a pair of
            *KeySyms* ``K1 K2``, then the list is treated as if it were the list
            ``K1 K2 K1 K2``.
    
            If the list (ignoring trailing ``NoSymbol`` entries) is a triple of
            *KeySyms* ``K1 K2 K3``, then the list is treated as if it were the list
            ``K1 K2 K3 NoSymbol``.
    
        This function will also group the *keysyms* using :func:`keysym_group`.
    
        :param keysyms: A list of keysyms.
    
        :return: the tuple ``(group_1, group_2)`` or ``None``
        """
    
      
  • eggplant math cuz it isn't in SYMBOLS

     
        
    >>> s = '''🍆'''
    >>> dec_s = ord(s)
    127814
    >>> hex(dec_s)
    '0x1f346'
    
      

    From the source code

     
        
    def char_to_keysym(char):
        """Converts a unicode character to a *keysym*.
    
        :param str char: The unicode character.
    
        :return: the corresponding *keysym*, or ``0`` if it cannot be found
        """
        ordinal = ord(char)
        if ordinal < 0x100:
            return ordinal
        else:
            return ordinal | 0x01000000
    
      

    What a nutter! Comparing an int to a hex.

     
        
    >>> int(0x100)
    256
    >>> int(0x01000000)
    16777216
    
    eggplant emoji keysym
    >>> 127814 | 16777216
    16905030
    
      
  • _util/xorg_keysyms.py

    Contains mapping of keysym to unicode str

    type this into the terminal, it'll open up a small window. With the window in focus, type.

    xev -event keyboard

    type 1

    From xev

    keysym 0x31, 1

    Corresponding entry in pynput._util.xorg_keysyms.SYMBOLS

    '1': (0x0031, u'\u0031'),

    so the hex is minimum four places. So 0031 instead of 0x31

    From xev

    keysym 0xac9, trademark

    Corresponding entry in pynput._util.xorg_keysyms.SYMBOLS

    'trademark': (0x0ac9, u'\u2122'),

    From xev

    type in nuke radiation emoji

    keysym 0x1002622, U2622 bytes: (e2 98 a2) "☢"

    So three bytes instead of one or two bytes

    From xev

     
        
    (keysym 0x7c, bar)
    1 bytes: (7c) "|"
    
      

    Corresponding entry in pynput._util.xorg_keysyms.SYMBOLS

    'bar': (0x007c, u'\u007C'),

  • Took two days to think about your original post. Was thinking, hmmm this package and trouble you are having are both fresh and interesting.

    Remote controlling both the mouse and keyboard seems worthy to spend time trying it out.

  • Very wise idea. And if you want to up your game, can validate the yaml against a schema.

    Check out strictyaml

    The author is ahead of his time. Uses validated yaml to build stories and weave those into web sites.

    Unfortunately the author also does the same with strictyaml tests. Can get frustrating cause the tests are too simple.

  • Curious to hear your reasoning as to why yaml is less desirable? Would think the opposite.

    Surprised me with your strong opinion.

    Maybe if you would allow, and have a few shot glasses handy, could take a stab at changing your mind.

    But first list all your reservations concerning yaml

    Relevent packages I wrote that rely on yaml

    • pytest-logging-strict
    • sphinx-external-toc-strict
  • v1.8.1 was release on 2025-03-17

    So pynput is being maintained. BUT there are current 155 open issues and 23 PRs. This means nothing besides this is a popular package.

    v1.8.1 Changes

    • Remove incorrectly merged line for the Xorg backend. Thanks to sphh!
    • Let events know about the new injected parameter. Thanks to phpjunkie420!

    Mentioned that a PR dealt with a Xorg backend issue. Don't know if this addresses your particular issue.

    What pynput version do you have in your venv?

    Run this command please to get the package version

    python -m pip list | grep pynput

    Can understand your issue report would be buried in all the other issues. So help there might not come within a timely manner.

    The next step would be to create a pytest file to be able to repeat the tests, rather than run them each time manually. Obviously logging in and out is not possible. But it's probably also completely unnecessary.

    I use Xorg and Linux. Competent enough with pytest (author of pytest-logging-strict).

    Before roll up my sleeves want you to confirm v1.8.1 still has this issue.

  • You yourself are a victim

    Having good intentions you tried and found out the hard way that in fact packaging does matter.

    You were tricked.

    I looked at it, recognized the flaming turd being thrown at the proverbial wall, and dodged.

    That is our job when doing code reviews and offering advice. Be kind up to the point where being honest is unavoidable.

    A series of scripts does not make a package. Have to put our collective foot down; follow Nancy Reagon's advice, Just say no!

    This project cannot be helped. It needs a complete rewrite.

    Having minimal expectations is not being mean to noobs. Not getting anywhere in the ballpark of minimal expectations is being mean to potential users ...

  • Using match is virtue signaling that have no intention of creating a working package.

    What's next on the list of crap could all live without?

  • Why? It's not a package? There are no tests or anything else. It's held together with duct tape, hope, and good intentions. So of course it'll not work as intended.

  • User friendly LOL!

    If you encounter any issues or bugs, let me know so I can fix them!

    You shoulda lead with that. I love the humor. Can't stop laughing,

    The entire project is a bug LOL!

    Where to start?

    1. There is no packaging at all

    Start with a pyproject.toml and work from there.

    1. no tests

    Everything is a bug until it's got test coverage.

    1. screenshots

    In the .github folder?! That's gotta be a 1st

    1. no dev environment

    Expecting pre-commit as well as isort, flask, black, and mypy

    1. print statements galore

    Looked into requirements.txt expecting to find a console UI framework. There is none!

    A pattern has emerged that many Python coders have spent not enough to no time learning packaging, dev toolchain, and CI/CD publishing. When asking folks to test your work they'll be expecting a published package, not a series of amateurish scripts and a bash install script.

    Should write an advertisement

    Please someone skilled at console UI and packaging please please please help in a paid position.

    Can confidently say, you need help.

    Not writing more features the OP is good at that. Just packaging and swapping out the prehistoric console UI with a modern console UI framework.

  • Wow that's neat! Thanks for bringing this up.

    The feature flags example should be rewritten to use enum.Flag

  • a use case -- feature flags

    Mix and match to plan your day

    will i be going home today?

     
        
    >>> OUTRAGED_BY_NEWS = 0b00000001
    >>> GET_A_COFFEE = 0b00000010
    >>> GO_FOR_A_HIKE = 0b00000100
    >>> GO_FOR_A_RUN = 0b00001000
    >>> GO_HOME = 0b00010000 
    >>> various_flags_ored_together = GET_A_COFFEE | GO_FOR_A_RUN | GO_HOME
    >>> various_flags_ored_together & GO_HOME == GO_HOME
    True
    >>> various_flags_ored_together & GO_FOR_A_HIKE == GO_FOR_A_HIKE
    False
    >>> various_flags_ored_together = GET_A_COFFEE | GO_FOR_A_RUN | GO_HOME
    >>> bin(various_flags_ored_together)
    '0b11010'
    >>> various_flags_ored_together & OUTRAGED_BY_NEWS == OUTRAGED_BY_NEWS
    >>> False
    >>> bin(OUTRAGED_BY_NEWS)
    >>> '0b1'
    >>> various_flags_ored_together >> OUTRAGED_BY_NEWS
    >>> bin(various_flags_ored_together)
    '0b1101'
    
      

    Guess haven't gone for a hike today...maybe tomorrow

    right shift removes bit at flag position. Which, in this case, happens to correspond to the right most bit.

    use case -- file access permissions

    For those looking to check file access permissions there is the stat module

     
        
    >>> import stat
    >>> from pathlib import Path
    >>> path_f = Path.home().joinpath(".bashrc")
    >>> stat.S_IRUSR
    256
    >>> path_f.stat().st_mode
    33188
    >>> is_owner_read = path_f.stat().st_mode & stat.S_IRUSR == stat.S_IRUSR
    >>> is_owner_read
    True
    >>> path_f = Path("/etc/fstab")
    >>> is_other_write = path_f.stat().st_mode & stat.S_IWOTH == stat.S_IWOTH
    >>> is_other_write
    False
    
    
      

    Assumes ~/.bashrc exists, if not choose a different file you are owner and have read access to.

    path_f.stat().st_mode & stat.S_IRUSR == stat.S_IRUSR

    Looking thru the mundane file (not Linux access control list) permissions. All those flags are crammed into st_mode. In st_mode, on/off bit at 2^8 is that on?

    Sources

    read user access stat.S_IRUSR

    write others access stat.S_IWOTH

    os.stat_result

    pathlib.Path.stat

  •  
        
    from multiprocessing import Lock
    l = Lock()
    
      

    flake8 .... way too ambiguous

  • so what if it's 100x slower /nosarc

  • Multiple return statements is unusual. In very rare situations i understand. But the rule is never do that.

    When there is only one return statement, can step into the function to see the local variables

  • The sample code for lazy imports looks wrong

     
        
    STRIPE = None
    
    def _stripe():
        global STRIPE
        if STRIPE is None:
            import stripe
    
            return stripe
        return STRIPE
    
    
    
      

    STRIPE is never changed. And two return statements in the same function?!

    Anyways can imagine how to do lazy imports without relying on the given code sample.